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编程案例——文件传输聊天工具相关推荐

  1. 【Java】UDP Socket编程案例——文件传输聊天工具

    UDP(用户数据报协议)就像日常生活中的邮件投递,是不能保证可靠地寄到目的地.UDP是无连接的,对系统资源的要求较少,UDP可能丢包,也不保证数据顺序.但是对于网络游戏和在线视频等要求传输快,实时性高 ...

  2. java socket 传多个文件下载,Socket编程多文件传输

    有子曰:"其为人也孝弟,而好犯上者,鲜矣:不好犯上,而好作乱者,未之有也.君子务本,本立而道生.孝弟也者,其为仁之本与!" 项目介绍:基于TCP协议实现多文件传输 将F盘test文 ...

  3. Socket 基础 非阻塞式TCP socket,实现文件传输jpg,mov等格式

    Socket 基础 非阻塞式TCP socket 实现文件传输, 实测 传输5M的jpg , 30M的 NEF(单反原图) 以及 1G以上的mov文件,均正常接收 客户端可多开,服务器多线程实现服务器 ...

  4. socket编程实现文件传输功能

    这节我们来完成 socket 文件传输程序,这是一个非常实用的例子.要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: 1) 文件大小不确定,有 ...

  5. socket编程二十二:socket编程实现文件传输功能

    这节我们来完成 socket 文件传输程序,这是一个非常实用的例子.要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: 1) 文件大小不确定,有 ...

  6. 例程:socket编程实现文件传输功能

    程序要实现的功能:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: (1)文件大小不确定 有可能比缓冲区大很多,调用一次 write()/send() 函数不 ...

  7. socket 编程实现文件传输功能!强无敌,网络通讯的必备知识储备!

    socket 文件传输程序,这是一个非常实用的例子. 要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: ======== 1) 文件大小不确定 ...

  8. 基于TCP,Socket编程,模仿腾讯QQ界面,使用Java开发的一款网络聊天工具。QQ_Chat

    代码下载地址 原博客地址 QQ_Chat 基于TCP,Socket编程,模仿腾讯QQ界面,使用Java开发的一款网络聊天工具. (内含报告) 工具: Eclipse.Navicat for MySQL ...

  9. api有哪些 javasocket_基于java的socket编程及API解析

    一.socket通讯过程 1.socket与socket编程简介: socket 被翻译为"套接字",它是计算机之间进行通信的一种约定或一种方式.通过 socket 这种约定,一台 ...

最新文章

  1. api分层内部外部 spring_java - Spring boot restful API分层架构验证 - SO中文参考 - www.soinside.com...
  2. 5、ShardingSphere 之 公共表
  3. jQuery的位置信息和事件
  4. python中下划线开头的命名_Python 中各种下划线的骚操作:_、_xx、xx_、__xx、__xx__、_classname_...
  5. The repository does not have a Release
  6. 为什么 12306 时不时要崩那么一下?
  7. UDS协议(史上最全)
  8. 64 位Instant Client连接64位PLSQL(win10)
  9. Win10系统禁用驱动程序强制签名
  10. android 流量计算器,电工计算器v8.0.1_for Android 直装解锁专业版
  11. java中 是什么意思_java中?:是什么意思
  12. 《CSAPP》(第3版)答案(第十一章)
  13. 医院科室管理系统(IDEA开发)
  14. 常用中文字体的英文名称
  15. cf 723 C2. Potions (Hard Version)(反悔,priority)
  16. C_.NET+Framdwork题库(未整理完,有时间再补)
  17. 信息学奥赛一本通习题答案(五)
  18. VirtualBox中Windows 7虚拟机无法全屏显示怎么办?
  19. python常用re正则表达式大全,查找指定内容
  20. 用tensorflow.js实现浏览器内的手写数字识别

热门文章

  1. apache简单安全配置
  2. Nokia Booklet 3G试用小记
  3. 使用 windows命令和iconv.exe批量转换文件编码
  4. VUE2中axios的使用方法
  5. L2-030 冰岛人 (25 分)-PAT 团体程序设计天梯赛 GPLT
  6. SQL命令向表中添加列
  7. php 去除div标签,JavaScript_清除div下面的所有标签的方法,复制代码 代码如下: div id=s - phpStudy...
  8. redis查看连接数
  9. 【Log4j】Jboss下配置log4j简记
  10. perl中的sleep函数