基本套接字:
TCP协议:
Java 为TCP协议提供了两个类:Socket 和 ServerSocket类。一个TCP连接是一个抽象的双向通道,两端分别绑定IP和端口号。首先由客户端TCP向服务端TCP请求连接,ServerSocket实例用来监听连接请求,为每个请求创建新的Socket实例,也就是说服务端同时处理ServerSocket和Socket实例,而客户端只需要处理Socket实例。
TCP客户端:
客户端向服务端发送TCP请求后,就被动的等待服务器响应。一般包括以下三步:
- 创建Socket实例:绑定服务端IP和端口号,建立连接。
- 通过Socket的输入输出流来进行通信:Socket.getInputStream()和Socket.getOutputStream()方法来获取。
- Socket关闭通信:包括I/O流,Socket本身等。
TCP服务端:
服务端的工作是创建一个ServerSocket实例监听相应端口,被动的等待客户端的请求,一般包括以下两步:
- 创建ServerSocket实例并绑定服务端口:用于监听端口到来的TCP请求
- 重复执行:
- 调用accept方法,获取客户端连接,并返回一个Socket实例。
- 使用Socket的获取的I/O流与客户端进行通信。
- 关闭Socket与I/O流。
关于服务端获取的Socket实例,可以绑定到一个线程,来提高服务端效率,使用不同的线程处理不同的客户请求也是成熟TCP/IP服务器的基本原理。
具体demo代码改天再发。
UDP协议:
UDP协议与TCP不同,他是一种尽力而为的端到端传输服务,不需要事先建立链接,也不保证数据一定能到达,也因此在效率上比TCP快的多。Java中关于UDP的套接字有DatagramPacket类和DatagramSocket类来实现。
与TCP的另一个不同点在于,UDP终端间交换的是数据报文,不再是通过字节流。数据报文也就是DatagramPacket实例,发送信息时,首先创建一个DatagramPacket类的实例,并将其作为DatagramSocket类的send方法。同样,接受信息时,也是先创建一个DatagramPacket实例,用来预先分配一些空间,然后将收到的信息存放在该空间中,然后把该实例作为参数传递给DatagramSocket的receive方法。当然上述的每个DatagramPacket实例都是绑定了相应地址和端口信息的。若是被发送的数据报,则需绑定目的地址和端口号,若是接受的数据报,则绑定接收信息的源地址。
UDP客户端:
同样是先向服务端发送一个数据报,然后被动的等待服务端响应。一般分为以下三步:
- 创建DatagramSocket实例和组装待发送的数据报:创建DatagramSocket实例,设置相应参数(包括:timeout、本地端口信息等),创建DatagramPacket实例,包括数据,数据长度,服务端地址、端口。
- 使用DatagramSocket实例的send和receive方法进行通信:发送第一步组装的数据报,接收时需传入一个空的数据报实例。
- 关闭通信:DatagramSocket类的close方法。
UDP服务端:
建立一个通信终端,等待客户端的数据报文初始化,不需建立链接,分为以下三步:
- 创建一个DatagramSocket实例:绑定本地地址、端口,准备接受从任何客户端发来的数据报。
- 使用DatagramSocket实例的receive方法接受一个数据报:接受的数据报中包含了客户端信息,服务端由此了解了响应信息的目的地址。
- 使用DatagramSocket的receive和send方法与客户端通信:通过DatagramPacket实例来实现。
UDP与TCP的一些区别,不建立链接,虽然提供了相应的API,不建议使用。UDP保留了消息的边界,DatagramSocket的每个receive只能接受一个send的内容,而且不同的receive接收到的绝不会返回同一个send方法的所发送的数据,每次接收完DatagramPacket的长度变为处理数据报的长度,需按需要修改。对于TCP来说每个收到的数据都是都是来自同一个TCP链接,而UDP的每一个receive方法接收到到的数据可以来自不同的发送者。