【Java】TCP Socket编程案例——文件传输聊天工具
TCP(传输控制协议)是面向连接的可靠数据传输协议。TCP连接一旦建立起来,一直占用,直到关闭连接。另外,TCP为了保证数据的正确性,会重发一切没有收到的数据,还会对数据内容进行验证,并保证数据传输的正确顺序。因此TCP协议对系统资源的要求较多。
案例一:文件上传工具
上传过程是一个单向的socket通信过程。
客户端通过文件输入流读取文件,然后从Socket获得输入流写入数据,写入数据完成上传成功,客户端任务完成。
服务端从Socket获得输入流,然后写入文件输出流,写入数据完成上传成功,服务端任务完成。
服务器端UploadServer代码如下:
package wangluobiancheng;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class UploadServer {public static void main(String[] args) {System.out.println("服务端运行...");try {//创建一个ServerSocket监听8080端口的客户请求ServerSocket server=new ServerSocket(8080);//使用accept()阻塞当前线程,等待客户端请求Socket socket=server.accept();BufferedInputStream in=new BufferedInputStream(socket.getInputStream());//由文件输出流创建缓冲输出流FileOutputStream out=new FileOutputStream("TestDir/subDir/coco.jpg");//准备一个缓冲区byte[] buffer=new byte[1024];//首次从Socket读取数据int len=in.read(buffer);while(len!=-1){//写入数据到文件out.write(buffer,0,len);//再次从Socket读取数据len=in.read(buffer);}System.out.println("接收完成!");} catch (IOException e) {e.printStackTrace();}}}
(注意:由于当前线程是主线程,所以server.accept()会阻塞主线程,阻塞主线程是不明智的,如果是在一个图形界面的应用程序,阻塞主线程会导致无法进行任何的界面操作,就是常见的“卡”现象,所以最好是把server.accept()语句放到子线程中。)
客户端UploadClient代码如下:
package wangluobiancheng;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;public class UploadClient {public static void main(String[] args) {System.out.println("客户端运行...");//向本机的8080端口发出请求Socket socket;try {socket = new Socket("127.0.0.1",8080);//由Socket获得输出流,并创建缓冲输出流BufferedOutputStream out=new BufferedOutputStream(socket.getOutputStream());//创建文件输入流FileInputStream fin=new FileInputStream("TestDir/coco.jpg");//由文件输入流创建缓冲输入流BufferedInputStream in=new BufferedInputStream(fin);//准备一个缓冲区byte[] buffer=new byte[1024];//首次读取文件int len=in.read(buffer);while(len!=-1){//数据写入Socketout.write(buffer,0,len);//再次读取文件len=in.read(buffer);}System.out.println("上传成功!");} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}
测试案例时,先运行服务器,再运行客户端。
注意当前运行的路径是工程根目录,需要将用到的文件夹创建在根目录下。本案例文件结构如下所示:
测试Socket程序要查看多个控制台信息,可以在Eclipse控制台上面的工具栏中单击“选择控制台”按钮实现切换。
案例二:聊天工具
案例一介绍的只是单向传输的Socket,Socket可以双向数据传输,比较有代表性的案例就是聊天工具。
首先客户端通过键盘输入字符串,通过标准输入流读取字符串,然后通过Socket获得输入流,将字符串写入输入流。
接着服务器通过Socket获得输入流,从输入流中读取来自客户端发送过来的字符串,然后通过标准输入流输出到显示器的控制台。服务器向客户端传送字符串过程类似。
服务器端ChatServer代码入下:
package wangluobiancheng;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;public class ChatServer {public static void main(String[] args) {System.out.println("服务器运行...");Thread t=new Thread(()->{try ( //使用自动资源管理//创建一个ServerSocket监听端口8080客户请求ServerSocket server=new ServerSocket(8080);//使用accept()阻塞等待客户端请求Socket socket=server.accept();//从socket中获得数据输入流DataInputStream in=new DataInputStream(socket.getInputStream());//从socket中获得数据输出流DataOutputStream out=new DataOutputStream(socket.getOutputStream());//System.in是标准输入流,使用标准输入流创建缓冲输入流BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in))){while(true){/*接收数据*///数据输入流读取UTF编码的字符串String str=in.readUTF();//打印接收的数据System.out.printf("从客户端接收的数据:【%s】\n",str);/*发送数据*///读取键盘输入的字符串String keyboardInputString=keyboardIn.readLine();//结束聊天if(keyboardInputString.equals("bye")){break;}//发送out.writeUTF(keyboardInputString);out.flush();}} catch (IOException e) {e.printStackTrace();}});t.start();}}
上述代码创建一个子线程,将网络通信放到子线程中处理是一种很好的做法,因为网络通信往往有线程阻塞过程,放到子线程中处理就不会阻塞主线程了。
自动资源管理:一般try-catch语句后面还跟有一个finally代码块,无论try正常结束还是catch异常结束都会执行finally代码块,可以在finally语句中释放资源。而使用finally代码块释放资源会导致程序代码大量增加,在Java 7之后提供的自动资源管理技术可以代替finally代码块,不需要自己关闭这些资源,释放过程交给了JVM。自动资源管理是在try语句上的扩展,在try语句后面添加一对小括号"()",其中是声明或初始化资源语句,可以有多条语句,语句之间用分号";"分隔。
注意:所有可以自动管理的资源需要实现AutoCloseable接口,具体哪些资源实现AutoCloseable接口需要查询API文档。
客户端ChatClient代码如下:
package wangluobiancheng;import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;public class ChatClient {public static void main(String[] args) {System.out.println("客户端运行...");Thread t=new Thread(()->{try (//向127.0.0.1主机8080端口发出连接请求Socket socket=new Socket("127.0.0.1",8080);DataInputStream in=new DataInputStream(socket.getInputStream());DataOutputStream out=new DataOutputStream(socket.getOutputStream());BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in))){while(true){/*发送数据*///读取键盘输入的字符串String keyboardInpuStream=keyboardIn.readLine();//结束聊天if(keyboardInpuStream.equals("bye")){break;}//发送out.writeUTF(keyboardInpuStream);out.flush();/*接收数据*/String str=in.readUTF();//打印接收的数据System.out.printf("从服务器接收的数据:【%s】\n",str);}} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}System.out.println("客户端停止!");});t.start();}}
【Java】TCP Socket编程案例——文件传输聊天工具相关推荐
- 【Java】UDP Socket编程案例——文件传输聊天工具
UDP(用户数据报协议)就像日常生活中的邮件投递,是不能保证可靠地寄到目的地.UDP是无连接的,对系统资源的要求较少,UDP可能丢包,也不保证数据顺序.但是对于网络游戏和在线视频等要求传输快,实时性高 ...
- java socket 传多个文件下载,Socket编程多文件传输
有子曰:"其为人也孝弟,而好犯上者,鲜矣:不好犯上,而好作乱者,未之有也.君子务本,本立而道生.孝弟也者,其为仁之本与!" 项目介绍:基于TCP协议实现多文件传输 将F盘test文 ...
- Socket 基础 非阻塞式TCP socket,实现文件传输jpg,mov等格式
Socket 基础 非阻塞式TCP socket 实现文件传输, 实测 传输5M的jpg , 30M的 NEF(单反原图) 以及 1G以上的mov文件,均正常接收 客户端可多开,服务器多线程实现服务器 ...
- socket编程实现文件传输功能
这节我们来完成 socket 文件传输程序,这是一个非常实用的例子.要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: 1) 文件大小不确定,有 ...
- socket编程二十二:socket编程实现文件传输功能
这节我们来完成 socket 文件传输程序,这是一个非常实用的例子.要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: 1) 文件大小不确定,有 ...
- 例程:socket编程实现文件传输功能
程序要实现的功能:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: (1)文件大小不确定 有可能比缓冲区大很多,调用一次 write()/send() 函数不 ...
- socket 编程实现文件传输功能!强无敌,网络通讯的必备知识储备!
socket 文件传输程序,这是一个非常实用的例子. 要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: ======== 1) 文件大小不确定 ...
- 基于TCP,Socket编程,模仿腾讯QQ界面,使用Java开发的一款网络聊天工具。QQ_Chat
代码下载地址 原博客地址 QQ_Chat 基于TCP,Socket编程,模仿腾讯QQ界面,使用Java开发的一款网络聊天工具. (内含报告) 工具: Eclipse.Navicat for MySQL ...
- api有哪些 javasocket_基于java的socket编程及API解析
一.socket通讯过程 1.socket与socket编程简介: socket 被翻译为"套接字",它是计算机之间进行通信的一种约定或一种方式.通过 socket 这种约定,一台 ...
最新文章
- api分层内部外部 spring_java - Spring boot restful API分层架构验证 - SO中文参考 - www.soinside.com...
- 5、ShardingSphere 之 公共表
- jQuery的位置信息和事件
- python中下划线开头的命名_Python 中各种下划线的骚操作:_、_xx、xx_、__xx、__xx__、_classname_...
- The repository does not have a Release
- 为什么 12306 时不时要崩那么一下?
- UDS协议(史上最全)
- 64 位Instant Client连接64位PLSQL(win10)
- Win10系统禁用驱动程序强制签名
- android 流量计算器,电工计算器v8.0.1_for Android 直装解锁专业版
- java中 是什么意思_java中?:是什么意思
- 《CSAPP》(第3版)答案(第十一章)
- 医院科室管理系统(IDEA开发)
- 常用中文字体的英文名称
- cf 723 C2. Potions (Hard Version)(反悔,priority)
- C_.NET+Framdwork题库(未整理完,有时间再补)
- 信息学奥赛一本通习题答案(五)
- VirtualBox中Windows 7虚拟机无法全屏显示怎么办?
- python常用re正则表达式大全,查找指定内容
- 用tensorflow.js实现浏览器内的手写数字识别
热门文章
- apache简单安全配置
- Nokia Booklet 3G试用小记
- 使用 windows命令和iconv.exe批量转换文件编码
- VUE2中axios的使用方法
- L2-030 冰岛人 (25 分)-PAT 团体程序设计天梯赛 GPLT
- SQL命令向表中添加列
- php 去除div标签,JavaScript_清除div下面的所有标签的方法,复制代码 代码如下: div id=s - phpStudy...
- redis查看连接数
- 【Log4j】Jboss下配置log4j简记
- perl中的sleep函数