一文详解TCP协议

描述

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抓包工具,抓取完整的收发过程

主机

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分