TCP协议的特点
- 面向连接
- 双方必须先建立连接才能进行数据的读写,双方都必须为该链接分配必要的内核资源,以管理连接的状态和连接上的传输 。
- TCP连接是全双工的,双方数据传输可以通过一个连接进行,完成数据交换后,双方必须断开连接,以释放系统资源,这种连接是一对一的,不适用于广播和多播的应用程序,基于多播和广播的应用程序适合使用UDP协议。
- 基于字节流
- 发送端执行多次写操作时,TCP模块必须先把这些数据放入TCP发送缓冲区中,当TCP模块真正发送数据时,才把TCP发送缓冲区等待发送的数据封装成一个或多个TCP报文段发出,TCP模块发出的报文的个数与应用程序的写操作的次数没有固定的数量关系 。
- 接收端收到报文段后,TCP模块必须把它们携带的应用数量按照TCP报文段的序号依次放入TCP接收缓冲区中,同时通知应用程序读取数据,接收端应用程序可以一次或多次读取数据(取决于用户指定的应用程序读缓冲区大小应用程序执行读操作的次数和TCP模块接收到的TCP报文的个数没有固定的数量关系
- 发送端执行的写操作次数与接收端执行的读操作次数没有数量关系 ,应用程序对数据的发送和接收没有边界限定的,这也是字节流的概念
- 可靠传输
- TCP采用发送应答机制,保证TCP传输的可靠性。TCP发送的每个报文段,都必须德奥接受方的应答才认为TCP报文传输成功。
- TCP超时重传,发送端发出一个报文后就启动定时器,如果在定时时间内没收到应答就重新发送这个报文。
- TCP报文段最终是以IP数据包发送的,IP数据包达到可能乱序重复,TCP协议对接受的TCP报文段重排整理后再交给应用程序。
TCP报文包格式
TCP报文包封装在IP数据包的数据部分
字段 | 长度 | 含义 |
---|---|---|
Source Port | 16比特 | 源端口,标识哪个应用程序发送。 |
Destination Port | 16比特 | 目的端口,标识哪个应用程序接收。 |
Sequence Number | 32比特 | 序号字段。TCP链接中传输的数据流中每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。 |
Acknowledgment Number | 32比特 | 确认号,是期望收到对方的下一个报文段的数据的第1个字节的序号,即上次已成功接收到的数据字节序号加1。只有ACK标识为1,此字段有效。 |
Data Offset | 4比特 | 数据偏移,即首部长度,指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,以32比特(4字节)为计算单位。最多有60字节的首部,若无选项字段,正常为20字节。 |
Reserved | 6比特 | 保留,必须填0。 |
URG | 1比特 | 紧急指针有效标识。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。 |
ACK | 1比特 | 确认序号有效标识。只有当ACK=1时确认号字段才有效。当ACK=0时,确认号无效。 |
PSH | 1比特 | 标识接收方应该尽快将这个报文段交给应用层。接收到PSH = 1的TCP报文段,应尽快的交付接收应用进程,而不再等待整个缓存都填满了后再向上交付。 |
RST | 1比特 | 重建连接标识。当RST=1时,表明TCP连接中出现严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立连接。 |
SYN 1 | 比特 | 同步序号标识,用来发起一个连接。SYN=1表示这是一个连接请求或连接接受请求。 |
FIN | 1比特 | 发端完成发送任务标识。用来释放一个连接。FIN=1表明此报文段的发送端的数据已经发送完毕,并要求释放连接。 |
Window | 16比特 | 窗口:TCP的流量控制,窗口起始于确认序号字段指明的值,这个值是接收端正期望接收的字节数。窗口最大为65535字节。 |
Checksum | 16比特 | 校验字段,包括TCP首部和TCP数据,是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。 |
Urgent Pointer | 16比特 | 紧急指针,只有当URG标志置1时紧急指针才有效。TCP的紧急方式是发送端向另一端发送紧急数据的一种方式。紧急指针指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。 |
Options | 可变 | 选项字段。TCP协议最初只规定了一种选项,即最长报文段长度(数据字段加上TCP首部),又称为MSS。MSS告诉对方TCP“我的缓存所能接收的报文段的数据字段的最大长度是MSS个字节”。 |
Padding | 可变 | 填充字段,用来补位,使整个首部长度是4字节的整数倍。 |
data | 可变 | TCP负载。 |
TCP三次握手连接(使用wireshark抓包分析)
-
第一次握手:
可以看到:源地址(source)为10.240.45.228,源端口号(source port)为50024,目的地址(destination)为10.255.16.19,目的端口号(destination port)为1554;初始序列号(sequence number)和确认序列号(acknowledgment number)都为0。第一次握手source使用一个随机端口号向destination的1554端口发送建立连接的请求,此过程最典型的表示就是TCP的SYN控制位为1,其他五个控制位全为0。
-
第二次握手:
源地址以及端口号和目的地址和端口与第一次握手相反,初始序列号为0,确认序列号为1,并且控制位中的ACK和SYN都为1。第二次握手实际上分两部分完成:
1)PC2收到PC1的请求,向PC1回复一个确认信息,此过程标志就是TCP的ACK控制位为1,其他五个控制位全为0,并且确认序列号是PC1的初始序列号加1。
2)PC2也向PC1发送一个建立连接的请求,此过程的标志与第一次握手一样,TCP的SYN控制位为1,其他五个控制位全为0。
-
第三次握手:
源地址以及端口号和目的地址以及端口号与第一次握手相同,其中初始序列号即为第二次握手的确认序列号1,确认序列号即为第二次握手的初始序列号加1。PC1收到PC2的回复(包含请求和确认),也要向PC2回复一个确认信息,此过程最典型的标志就是TCP的ACK控制位为1,其他五个控制位为0,而且确认序列号是PC2的初始序列号加1。这样完成了三次握手,在PC1和PC2之间建立了TCP连接。
TCP四次挥手
-
第一次挥手:
服务器向客户端发送FIN和ACK位为1的TCP报文段。
-
第二次挥手
客户端向服务器返回ACK位为1的TCP报文段。
-
第三次挥手
客户端向服务器发送FIN和ACK位为1的TCP报文段。
-
第四次挥手
服务器向客户端返回ACK位为1的TCP报文段,完成终止连接。
TCP四次挥手的半关闭概念(TCP一方终止发数据但可以接收)
- 1)PC2客户端FIN报文段,半关闭了这个连接,PC1服务器发送ACK报文段接收半关闭。
- 2)PC1服务器继续发送数据,而PC2客户端只发送ACK确认,不再发送任何数据。
- 3)当PC1服务器把所有数据都发送完毕时,就发送FIN报文段,PC2客户端再发送ACK报文段,这样就关闭了TCP连接