由于近期项目的原因,使用Socket通信比较频繁,所以想在Java基础篇对此介绍一下,由于没有对Java基础进行详细的阐述,这篇文章需要对Java语言有一定的理解能力,阅读人员如需补充基础,可到网上搜索相关内容进行学习。
1 通信协议TCP/IP
要想理解Socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准,从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族。不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中。
1应用层
向用户提供一组常用的应用程序,比如电子邮件、文件传输访问、远程登录等。远程登录TELNET使用TELNET协议提供在网络其他主机上注册的接口。TELNET会话提供了基于字符的虚拟终端。文件传输访问FTP使用FTP协议提供网络内机器间的文件拷贝功能。
2传输层
提供应用程序间的通信。其功能包括:①格式化信息流;②提供可靠传输。为实现后者,传输层协议规定接收端必须发回确认,并且假如分组丢失,必须重新发送。
3网络层
负责计算机之间的通信。其功能包括三方面:
①处理来自传输层的分组发送请求,收到请求后,将分组装入IP数据报文,填充表头,选择去往信宿机的路径,然后将数据报发往适当的网络接口。
②处理输入数据报文:首先检测其合法性,然后进行寻径——假设该数据报文已经到达信宿机,则去掉报文头,将剩下的部分交给适当的传输协议;接入该数据报文尚未到达信宿,则转发该数据报文。
③处理路径、流控、拥塞等问题。
4网络传输层
这是TCP/IP协议的最底层,负责接收IP数据报并通过网络发送之,或者从网络上接收物理帧,抽出IP数据报文,交给IP层。
下面以HTTP请求展示通信流程
2 Socket通信原理
TCP协议是面向连接、可靠的、有序的,以字节流的方式发送数据。在数据通信之前需要建立连接,保证数据传输的可靠性,那么它的传输是有顺序的,并且以字节流的方式进行传输,在我们JAVA当中如何去基于TCP协议实现网络通信呢?
有这么两个相关的类,基于TCP协议实现网络通信的类:
·客户端的Socket类
·服务器端的ServerSocket类
所谓Socket 通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄(handler)。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。
我们来看一下它具体的通信的过程,也就是Socket通信模型。两台主机需要通信,就必然存在着一台主机为服务器端Server,一台为客户端Client。那么通信的时候是这样的,首先我们在服务端,建立一个ServerSocket(服务端倾听Socket),绑定相应的端口,并且在指定的端口进行侦听,等待客户端的连接。当我们在客户端创建Socket并且向服务器端发送请求,服务器收到请求并且接受客户端的请求信息,一旦接受客户端请求信息以后,会创建一个连接Socket,用来与客户端的Socket进行通信。到底该如何进行通信,就是通过相关的输入流和输出流 InputStream,OutpuStream进行数据的交换,发送接收以及数据的响应等等。那么在客户端和服务器端双方通信完以后,我们需要分别关闭两边的Socket及相关资源,进行通信的断开。这是基于TCP-Socket通信,整个通信的过程,这点需要各位小伙伴们清楚。
3 Socket通信示例代码
1服务端
package socket.socket1.socket; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.ServerSocket;import java.net.Socket; public class ServerSocketTest { public static void main(String[] args) { try { //初始化服务端socket并且绑定9999端口 ServerSocket serverSocket = new ServerSocket(9999); //等待客户端的连接 Socket socket = serverSocket.accept(); //获取输入流 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //读取一行数据 String str = bufferedReader.readLine(); //输出打印 System.out.println(str); } catch (IOException e) { e.printStackTrace(); } }}
2客户端
package socket.socket1.socket; import java.io.BufferedWriter;import java.io.IOException;import java.io.OutputStreamWriter;import java.net.Socket; public class ClientSocket { public static void main(String[] args) { try { Socket socket = new Socket("127.0.0.1", 9999); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); String str = "你好,这是我的第一个socket"; bufferedWriter.write(str); //刷新输入流 bufferedWriter.flush(); //关闭socket的输出流 socket.shutdownOutput(); } catch (IOException e) { e.printStackTrace(); } }}