TCP原理(含三次握手和四次挥手等)

本文详细解读了TCP协议的核心特点,包括有连接、可靠传输、面向字节流和全双工,涉及TCP头部结构、确认应答、超时重传、连接管理机制、滑动窗口、流量控制、拥塞控制、延时确认和捎带应答,以及粘包问题的分析和解决方案。
摘要由CSDN通过智能技术生成

        TCP,即TransmissionControlProtocol,传输控制协议。

和之前讲到的UDP一样,TCP也是传输层的重点协议,有四个词来形容:

有连接,可靠传输,面向字节流,全双工。

TCP协议段格式:

源/目的端口号:表示数据从哪个进程来到哪个进程去(端口号可以理解为程序代号,可变)

序列号/确认号:字面意思,用来排序数据(后面会细说)。

4位报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15*4=60

保留位暂时没用

6标志位

URG:紧急指针是否有效

ACK:确认号是否有效

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

SYN:请求建立连接;我们把携带SYN标识的称为同步报文段

FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段

RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段

16位窗口大小:滑动窗口的一个概念,用来提升传输效率,后面细讲。

16位校验和::发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。

16位紧急指针:标识哪部分数据是紧急数据;

40字节头部选项:暂时忽略;

TCP原理

        TCP对数据传输提供的管控机制,主要体现在两个方面:安全和效率。在保证安全的条件下,尽可能地提升效率。

1. 确认应答(安全性、可靠性)

TCP将每个字节的数据都进行了编号,即为序列号(上面说的)

        每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。(确认应答,回复的是ACK即为ackonwledge)

2. 超时重传(安全性、可靠性)

        同样是上面这个过程中,如果出现丢包问题,在一个特定的时间内,A没有收到确认应答,则认为是丢包了,重新再次发送一次数据(返回的确认应答如果丢包了,再发一次也没有影响,后面会说这个情况)

超过特定时间重新发送数据的这个机制就是超时重传。

        确认应答和超时重传两个原理从根本上保证了TCP传输协议的安全性(很多人说是三次握手和四次挥手保证安全性,这个只能说是锦上添花,不能说是确保)

3. 连接管理机制(安全机制、三次握手,四次挥手)

正常情况下,TCP经过三次握手建立连接,四次挥手断开连接

        这张图描述了一次完整的TCP连接、传输、断开的过程和其中的状态,在多次循环数据传输过程之前是三次握手建立连接,在多次循环之后是四次挥手断开连接。

问题:为什么是三次握手,四次挥手?握手两次可不可以,挥手三次行不行?

        答案肯定是不行的,我们来理解一下三次握手和四次挥手时通信双方所处的状态以及每一次交互完成的事情:

三次握手:在这里我请出我的一个朋友和他梦中人的故事

        我的这个朋友,喜欢这个黄同学好久了,有一天鼓起勇气表白(试图建立连接),发出了第一次请求(syn)这时候黄同学收到了请求,回复了个好,此时黄同学知道了王同学喜欢自己,同时答应了王同学做为他的唯一,但是黄同学不能确定自己是不是他的唯一(如果王同学是个渣男呢?),此时这时候黄同学问王同学能不能也成为自己的唯一(syn),此时王同学知道了,自己的请求被接收,且被同意,立即也回复一个好,建立彼此唯一的连接。

但是在这里,小黄的两次回复(ACK+SYN)是不是可以同时发送,节省一次资源消耗呢?当然可以!!,因此图就变成了:

三次交互,三次握手,互相掌握对方的信息,少一次都不能完全掌握,因此不能减少为两次。

四次挥手,同样请出我这个朋友:如果说刚才建立连接是一件开心的事情,那断开连接就是一件悲伤的故事了:

        具体过程和建立连接差不多,王同学说过不下去了,想分手了,黄同学立即回了一个知道了,然后稍加思索,觉得确实没办法继续走下去了,于是也发出了个FIN的数据,王同学立马回了一个ACK(告辞)。但是这里为什么不能ACK和FIN合并呢?

        因为两次数据发出的交互层不同!FIN是应用层数据,而ACK是传输层的交互,ACK是会立即回复的,但是FIN是应用层控制的,所以不能合并。

        在这里有一个状态的变化,特别是TIME_WAIT状态会等2SML,(一次传输的最大时间是SML)因为这个ACK可能会丢包,ACK传到B的时间是一个SML,丢包重传FIN的时间也是SML,因此会在TIME_WAIT状态等2SML。如果2SML之后没有任何信息再过来,默认关闭。(TIME_WAIT这一步不可逆,因为已经把断开连接的操作进行完了,由于确保安全性才会再等一下)

Tips:一般而言,对于服务器上出现大量的CLOSE_WAIT状态,原因就是服务器没有正确的关闭socket,导致四次挥手没有正确完成。这是一个BUG。只需要加上对应的close即可解决问题。

4. 滑动窗口(效率机制)

        在前面我们谈过确认应答机制,每完成一次ACK之后才能进行下一步操作,这大大降低了数据的传输效率,我们通过滑动窗口这个机制来提高效率:

        一次一条数据传输效率过低,我们可以选择一次传输多条,把等待ACK时间放在一起,等待ACK的时间,我们可以看作为一个窗口(窗口期、空窗期,不新发数据):多个数据共用一个窗口,在一条完整的数据传输重看起来就像滑动一样

那这里如果出现丢包怎么办??如何进行重传?

1ACK丢了,不要紧!!后续的ACK也能确认前面的数据

2数据丢了?如何重传?

        某一段数据丢了之后之后的ACK回复的还是上一次收到的确认应答(因为只有上一次的数据对的上号)连发三次之后主机A进行补发(1001丢失不影响发送后面的数据),后续已经接收到的数据ACK由后续进行比对,如果中间又有某次丢了(比如3001丢了),则又会回复索要丢了的数据(连要3001),已经收到的数据ACK与最新的ACK同步(3001补齐之后4001~6000都已经收到了,最新的ACK索要7001)。

5. 流量控制(安全机制)

       由于发送方不是直接将数据一股脑发到接收方的,数据先需要进入一个缓冲区,重新排列好队伍(根据序列号),并且删除可能多发的数据,再依次进入接收方。

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(FlowControl)。

接收方将自己缓冲区的大小放入TCP报头重的“窗口大小”字段,通过ACK通知发回发送方。

        窗口大小字段越大说明网络的吞吐量越高,一旦缓冲区快满了,接收方会把窗口大小设置成一个更小的值发回发送方,如果接收方缓冲区满了,则返回窗口大小为0,但是此时接收方必须每隔一段时间发一个没有数据的窗口探测数据段,通知接收方把窗口大小返回给发送方。

        窗口字段是16位,就意味着TCP窗口最大是65535字节吗?其实并不是,在40位选项中有一个窗口扩大因子M,可以控制矿口字段的值左移,M是几就左移几位。

6.拥塞控制(安全机制)

        虽然TCP使用滑动窗口这个特性可以做到高效可靠地发送大量数据,但是如果再刚开始阶段就发送大量的数据,仍然可能引发问题。(不清楚网络状态,贸然发送大量数据,可能造成网络大规模拥堵)

        TCP引入慢启动机制,先发少量的数据,来探测当前网络拥堵的状态,再根据探测结果来决定按照多大的传输速率进行传输。

此处引入一个概念程为拥塞窗口

        发送开始的时候,定义拥塞窗口大小为1;每次收到一个ACK应答,拥塞窗口加1;

        每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小的值作为实际发送的窗口;像上面这样的拥塞窗口增长速度,是指数级别的。"慢启动"只是指初使时慢,但是增长速度非常快。为了不增长的那么快,因此不能使拥塞窗口单纯的加倍。

        此处引入一个叫做慢启动的阈值(ssthresh),当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长。

        当TCP开始启动的时候,慢启动阈值等于窗口最大值;在每次超时重发的时候,慢启动阈值会变成当前拥塞窗口大小的一半,同时拥塞窗口置回1;

少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;

当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;

神奇的例子:

        拥塞控制机制就像谈恋爱一样,一段热恋期两人的关系以一个极快的速度升温,达到一个临界点的时候,就很容易发生矛盾,接着就是关系迅速冷淡(谁也不想跟对方说话),但是当问题解决了的时候,关系又会迅速升温,到达临界之后会缓慢升温,又有可能发生问题。达成一个“动态平衡”。

7. 延时确认(效率机制)

        如果接收数据的主机立即返回ACK应答,这时候可能返回的窗口(当前缓冲区大小)比较小,但是处理端处理的很快,在这种情况下立刻返回会让下次发送的数据并不能达到当前处理的极限。此时等一会再回答就能提高当前窗口大小,加快速度。窗口越大,网络吞吐量就越大,我们的目标是保证在网络不拥塞的情况下尽可能提高传输效率。

(并不是所有的包都适用延时应答,可以分为数量和时间限制。数量:每隔N个包就应答一次,时间:超过最大延迟时间就应答一次。不同的操作系统数量和时间限制有区别,一般情况下N是2,时间为200ms)。

8. 捎带应答(效率机制)

        捎带应答机制(ACKPiggybacking)是一种优化TCP协议的数据传输过程的技术。它允许在一个TCP报文段中同时携带数据和确认(ACK),从而减少网络中的报文数量和传输延迟。

        在标准的TCP协议中,确认(ACK)是作为独立的控制报文发送的,用于确认接收方已经收到数据。每当接收方收到数据后,就会立即发送一个ACK,通知发送方数据已经成功接收。这样,每个数据包都会伴随一个单独的ACK,增加了网络的负载和传输延迟。

捎带应答机制的工作原理如下:

1.当接收方准备发送ACK时,如果正好有数据要回复,则将ACK捎带在数据报文段的首部中。

2.这样,数据报文段在携带实际数据的同时,还携带了确认信息(ACK)。

3.当发送方收到数据报文段后,会检查报文中是否有确认信息,如果有,就不需要额外发送单独的ACK了。

        通过捎带应答机制,可以减少在网络中传输的报文数量,提高网络的传输效率。它特别适用于网络延迟较高的情况,因为减少了独立ACK的发送,从而降低了数据传输的往返时间。捎带应答机制是TCP协议在提高网络性能和效率方面的一个重要优化手段。

粘包问题:

粘包问题是在数据传输过程中经常出现的一种情况,指的是多个数据包在传输中粘在一起形成一个大的数据块,导致接收方难以正确拆分和解析数据。

粘包问题可能由以下几个原因引起:

1.发送方连续发送数据包:当发送方快速发送多个数据包时,这些数据包可能在传输过程中会被合并成一个大的数据块,形成粘包。

2.接收方缓冲区未及时读取:如果接收方的缓冲区不能及时读取数据,多个数据包可能会在缓冲区中累积,最终导致粘包现象。

3.TCP协议的流模式:TCP协议是一种面向流的传输协议,它将数据视为一连串的字节流而不是数据包。在数据传输过程中,TCP会根据网络状况进行数据的切分和合并,可能导致粘包问题。

为解决粘包问题,可以采取以下方法:

1.消息定界法:在数据包中添加特定的定界符或长度信息,用于标识每个数据包的起始和结束位置,接收方根据定界符或长度信息来正确拆分和解析数据包。

2.消息长度前缀:在数据包前面添加表示数据长度的固定字节数,接收方先读取数据长度信息,再根据长度信息来准确读取数据内容。

3.应用层协议解析:在应用层使用特定的协议来处理数据,例如使用JSON或XML等数据格式,并在协议中明确定义每个数据包的起始和结束标志。

4.数据包确认和响应机制:发送方可以等待接收方发送确认信息,再发送下一个数据包,确保接收方逐个处理数据包。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值