简介
TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,用于在计算机网络中传输数据,它提供了可靠的、有序的、基于字节流的传输,并通过拥塞控制机制来保证网络的稳定性,TCP协议可以保证传输数据的安全,所以应用十分广泛。例如上传文件、下载文件、浏览网页等。
TCP协议在传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。
TCP的特性
- 面向连接:在进行数据传输之前,TCP需要在通信双方建立连接,确保双方都准备好进行数据传输。
- 可靠性:TCP通过序列号和确认机制来保证数据的可靠传输。接收方会确认已接收到的数据,并要求发送方重新发送丢失的数据。
- 有序性:TCP保证接收到的数据按照发送的顺序进行组装,不会出现乱序的情况。
- 流量控制:TCP使用滑动窗口机制来控制数据的发送速率,确保发送方不会压倒接收方。
- 拥塞控制:TCP通过拥塞窗口和拥塞避免算法来控制网络拥塞的发生,以保证网络的稳定性和公平性。
TCP三次握手(建立连接)和四次挥手(关闭连接)
三次握手
-
第一步:客户端发送SYN
- 客户端向服务器发送一个带有SYN(同步)标志的数据包。
- 客户端选择一个初始序列号(ISN)并将其放入TCP头部的序列号字段。
-
第二步:服务器回复SYN/ACK
- 服务器接收到客户端的SYN数据包后,向客户端发送一个带有SYN/ACK标志的数据包。
- 服务器选择一个自己的初始序列号,并将其放入TCP头部的序列号字段。
- 服务器还确认客户端的序列号,并将下一个期望接收的序列号放入确认序号字段。
-
第三步:客户端发送ACK
- 客户端接收到服务器的SYN/ACK数据包后,向服务器发送一个带有ACK(确认)标志的数据包。
- 客户端确认服务器的序列号,并将下一个期望接收的序列号放入确认序号字段。
四次挥手
-
第一步:客户端发送FIN
- 客户端想要关闭连接时,向服务器发送一个带有FIN(结束)标志的数据包。
- 客户端停止发送数据,但仍然可以接收数据。
-
第二步:服务器发送ACK
- 服务器接收到客户端的FIN数据包后,向客户端发送一个带有ACK标志的数据包,确认收到了客户端的关闭请求。
-
第三步:服务器发送FIN
- 服务器准备关闭连接时,向客户端发送一个带有FIN标志的数据包。
- 服务器停止发送数据,但仍然可以接收数据。
-
第四步:客户端发送ACK
- 客户端接收到服务器的FIN数据包后,向服务器发送一个带有ACK标志的数据包,确认收到了服务器的关闭请求。
- 客户端等待一段时间,确保服务器收到了ACK后,关闭连接。
TCP头部格式(基础占用20个字节)
0 1 2 3 (1 - 4字节,1字节8位)
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 (0 - 31位)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源端口号(16位) | 目标端口号(16位) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 序列号 (32位) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 确认号 (32位) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据偏移 |保留 | U | A | P | R | S | F | |
| (4位) |(6位) | R | C | S | S | Y | I | 窗口大小 |
| | | G | K | H | T | N | N | (16位) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 校验和(16位) | 紧急指针(16位) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 选项(最大40字节) | 填充(0,1,2或3个字节) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 解析如下:
- 源端口号和目标端口号:分别指示发送方和接收方的端口号,用于标识应用程序或服务,并确保数据能够正确地传递到目标地址和端口号。
- 序列号:用于标识发送方发送的数据段中的第一个字节的序列号。接收方通过序列号来组装数据段,保证数据的有序性。
- 确认号:指示接收方期望接收的下一个字节的序列号。接收方在接收到TCP报文后,会将确认号设置为已经成功接收到的最后一个字节的序列号加1。发送方通过确认号来确认接收方已经成功接收到数据,从而可以继续发送下一个数据段。
- 数据偏移:指示TCP头部的长度,以4字节为单位。由于TCP头部的长度是可变的,这个字段用于确定数据在TCP报文中的位置。例如,如果数据偏移字段的值为5,表示TCP头部的长度为5 * 4 = 20个字节
- 保留:保留字段,暂时没有使用。
- 标志位:控制TCP连接的操作
- Urg(Urgent): 指示紧急指针字段是否有效。当Urg标志位被设置为1时,表示TCP报文中存在紧急数据,紧急指针字段指示了紧急数据的位置。紧急数据具有高优先级,接收方应立即处理。
- Ack(Acknowledgment):指示确认号字段是否有效。当Ack标志位被设置为1时,表示确认号字段中包含有效的确认序号,用于确认已经收到的数据。
- Psh(Push):指示接收方是否应该立即将接收到的数据推送给应用程序,而不是等待缓冲区填满或等待更多数据。当Psh标志位被设置为1时,表示发送方希望接收方立即将数据传递给应用程序。
- Rst(Reset):重置TCP连接。当Rst标志位被设置为1时,表示要立即终止连接并丢弃所有未处理的数据。通常用于处理连接异常或恢复到初始状态。
- Syn(Synchronize):建立TCP连接。当Syn标志位被设置为1时,表示发送方希望建立连接,并在序列号字段中包含初始序列号。在连接建立过程中,Syn用于同步双方的初始序列号。
- Fin(Finish): 结束TCP连接。当Fin标志位被设置为1时,表示发送方不再发送数据,并请求关闭连接。接收方收到Fin后,可以继续发送数据,直到完成后也发送一个Fin来关闭连接。
- 窗口大小:指示接收方的接收窗口大小,用于流量控制,控制发送方的发送速率。 发送方根据接收方的窗口大小来控制发送数据的速率,以避免发送过多的数据导致接收方无法及时处理。
- 校验和:用于检测TCP头部和数据的完整性,防止数据在传输过程中被篡改。
- 紧急指针:指示紧急数据的位置,用于处理紧急数据的传输。
- 选项:可选字段,用于扩展TCP功能,如选择确认、时间戳等。长最大长度限制为40个字节度超过40个字节,将会被截断或丢弃。
- 填充:用于填充TCP头部,使其长度为4字节的倍数(比如27填充11字节)。
Java中的TCP通信
- Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。
- Java为客户端提供了Socket类,为服务器端提供了ServerSocket类