TCP协议深入
TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输
1. 序列号+确认应答
在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知,这个消息叫做确认应答(ACK); 序列号是按照顺序给发送数据的每一个字节都标上号码的编号。 接收端查询接收数据TCP首部中的序列号和数据的长度,将自已下一步应该接收的序号作为确认应答返送回去
2. 重发超时
重发超时是指在重发数据之前,等待确认应答到来的那个特定时间间隔,如果超过了这个时间仍未收到确认应答,发送端将进行数据重发。 理想的重发超时具体时长是找到一个最小时间,它能保证确认应答一定能在这个时间内返回
数据也不会无限、反复地重发。 达到一定重发次数后,若仍没有任何确认应答返回,就会判断为网络或对端主机发生了异常,强制关闭连接,并通知应用通讯异常强行终止
3. 连接管理
为了准确无误地将数据送达目标处,TCP协议采用了 三次握手 (three-way handshaking)策略。 用TCP协议将数据包送出去后,TCP一定会向对方确认是否成功送达。 若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的顺序包。 而 四次挥手 (Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开
三次握手,即建立连接
第一次握手:客户端发送一个带SYN标志的TCP报文到服务器。 这是三次握手过程中的段1
第二次握手:服务器端回应客户端,是三次握手中的第2个报文段,同时带ACK标志和SYN标志。 它表示对刚才客户端SYN的回应; 同时又发送SYN给客户端,询问客户端是否准备好进行数据通讯
第三次握手:客户必须再次回应服务器端一个ACK报文,这是报文段3
数据传输
客户端发出段4,包含从序号1001开始的20个字节数据。
服务器发出段5,确认序号为1021,对序号为1001-1020的数据表示确认收到,同时请求发送序号1021开始的数据,服务器在应答的同时也向客户端发送从序号8001开始的10个字节数据,这称为piggyback。
客户端发出段6,对服务器发来的序号为8001-8010的数据表示确认收到,请求发送序号8011开始的数据
四次挥手,即关闭连接
第一次挥手:客户端发出段7,FIN位表示关闭连接的请求
第二次挥手:服务器发出段8,应答客户端的关闭连接请求
第三次挥手:服务器发出段9,其中也包含FIN位,向客户端发送关闭连接请求
第四次挥手:客户端发出段10,应答服务器的关闭连接请求
下图是一次完整的三次握手、数据传输以及四次挥手的wireshark抓包测试
4. 流控制
在建立TCP连接时,可以确定发送数据包的单位,即最大消息长度(MSS:Maximum Segment Size)。 MSS是在三次握手的时候,在两端主机之间被计算得出的。 两端的主机在发出建立连接的请求时,会在TCP首部中写入MSS选项,告诉对方自已的接口能够适应的MSS大小,然后会在两者之间选择一个较小的值投入使用
TCP以一个段为单位,若每发一个段进行一次确认应答的处理,会导致往返时间较长通信性能较低。 为了解决该问题,引入了窗口这个概念,使得确认应答不再是以每个分段,而是以更大的单位进行确认
窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。 这个机制实现了使用大量的缓冲区,通过对多个段同时进行确认应答的功能。 在收到确认应答的情况下,将窗口滑动到确认应答中的序列号的位置,就可以顺序地将多个段同时发送以提高通信性能。 这种机制也被称为滑动窗口控制
上图就是一个滑动窗口控制实例,其详细流程见如下分析:
发送端发起连接,声明最大段尺寸是1460,初始序号是0,窗口大小是4K,表示“我的接收缓冲区还有4K字节空闲,你发的数据不要超过4K”。 接收端应答连接请求,声明最大段尺寸是1024,初始序号是8000,窗口大小是6K。 发送端应答,三方握手结束。
发送端发出段4-9,每个段带1K的数据,发送端根据窗口大小知道接收端的缓冲区满了,因此停止发送数据。
接收端的应用程序提走2K数据,接收缓冲区又有了2K空闲,接收端发出段10,在应答已收到6K数据的同时声明窗口大小为2K。
接收端的应用程序又提走2K数据,接收缓冲区有4K空闲,接收端发出段11,重新声明窗口大小为4K。
发送端发出段12-13,每个段带2K数据,段13同时还包含FIN位。
接收端应答接收到的2K数据(6145-8192),再加上FIN位占一个序号8193,因此应答序号是8194,连接处于半关闭状态,接收端同时声明窗口大小为2K。
接收端的应用程序提走2K数据,接收端重新声明窗口大小为4K。
接收端的应用程序提走剩下的2K数据,接收缓冲区全空,接收端重新声明窗口大小为6K。
接收端的应用程序在提走全部数据后,决定关闭连接,发出段17包含FIN位,发送端应答,连接完全关闭。
下图是一次完整的滑动窗口控制实例的wireshark抓包分析:
开启以socket客户端,发送2593个字节的数据到开发板
使用wireshark抓包工具,抓取完整的收发过程
全部0条评论
快来发表一下你的评论吧 !