TCP 协议难点汇总

本文不会完整的介绍TCP,只有在涉及到的时候随便提一下。不适合对TCP整个流程和框架没有了解过的人阅读。

1  TCP 四次挥手中的TIME_WAIT状态的意义何在。

下图四次挥手的一个大体的流程

我们发现在A发送完一个最后一个ACK后,B一收到这个ACK就证明关闭请求已经被确认了,所以可以直接关闭.但是这时候A怎么知道这个ACK是否已经到达了对端呢?这个时候为了保证双方能够正常关闭,就引入了一个MSL时间,MSL定义

”一个电磁波信号在地球最大的存活时间 ” . 所以该ACK存活一个MSL时间,然后我们假设该ACK丢失了,那么B在超时机制下会重新发送一个FIN,那么这个FIN 也要一个MSL时间后才从地球上消失,所以为了保证A的新连接不会被延迟的FIN终结掉,A在TIME_WAIT阶段要等待2个MSL时间

2  每个TCP连接实现单一计时器的可行性

我们知道对于每个数据报文都会有一个超时时间,在超时时间内如果没有收到一个ACK的话,那么我们就需要进行重传了,最简单的实现就是对于每个数据报都启动一个定时器,不过这样子有个很大的弊端就是太耗内存了,数据一大肯定计算器顶不顺。所以,现在业界默认都是按照每个TCP的重传计时由单一计时器来实现的。

单一计时器必须实现的2点:

key1 : 每一个报文在长期收不到确认都必须可以超时;

Key2 : 这个长期收不到中长期不能和测量的RTT相隔太远。

RFC2988定义一套很简单的原则:

a.发送TCP分段时,如果还没有重传定时器开启,那么开启它。

b.发送TCP分段时,如果已经有重传定时器开启,不再开启它。

c.收到一个非冗余ACK时,如果有数据在传输中,重新开启重传定时器。

d.收到一个非冗余ACK时,如果没有数据在传输中,则关闭重传定时器。

下图是按照RFC定义的粗略的画了一下流程

从图中我们看到,首先发送数据1的时候,发现没有定时器,所以就开启了定时器(RFC a),再发数据2的时候,定时器已经存在了,所以不再启动定时器(RFC b)。在RTO_1时间内,如果没有ACK到来,那么就要启动重传机制了。

情景一: 假设数据1 的ack在RTO_1快要结束的时候到来,那么由于这个是非冗余的ack,所以要重置计时器(RFC c),那么数据2的超时重传时间要多少呢,如图所示接近于RTO_1 + RTO_2 ,差不多是2倍的RTT时间。如果我们按照这种最坏的设想(数据报3,4都在RTO快到的时候才收到ACK)推算下去,假设发送数据1,2,3,4的时间分别是T1,T2,T3,T4

数据1 的超时时间: time1 = RTO_1

数据2 的超时时间: time2 = RTO_1 + RTO_2  -(T2 - T1)

数据3的超时时间:  time3 = RTO_1 + RTO_2 + RTO3 - (T3 - T1)

数据4的超时时间:  time4 = RTO_1 + RTO_2 + RTO3 + RTO4  -(T4 - T1)

RTT(往返时间)的计算公式为:

那么在数据1,2,3,4所处的不同阶段的RTT值分配以RTT1,RTT2 .... 来表示
RTT1 = N     #N代表初始值

RTT2 = RTT1 + g(RTO1 + RTO 2 - (T2 - T1)) = RTT1 + g time2

RTT3 = RTT2 + g timer3

RTT4 = RTT3 + g time4

我们会发现其实每个RTT 都与当时的time是紧密联系的,所以基本上满足Key_2。

情景二:

这种情况基本上是情况一的调转过来,新的超时时间如下:

数据4 的超时时间: time1 = RTO_1 + (T4 - T1)

数据3 的超时时间: time2 = RTO_1 + RTO_2  -(T3 - T1)

数据2的超时时间:  time3 = RTO_1 + RTO_2 + RTO3 - (T2 - T1)

数据1的超时时间:  time4 = RTO_1 + RTO_2 + RTO3 + RTO4

在这种情况里其实会引入一个机制---快速重传,因为TCP的ACK机制是按照接收方接受窗口中已接受到的数据中最大序号(max_seq)来填写ack值:ack = max_seq + 1,所以当B接受到数据4,3,2的时候,ack值都是数据1的第一个字节序号,只要连续三次重复ack同个数据后,就会启动快速重传机制,这时候数据1就不等超时时间了,直接就进行重发。

还有一个问题就是,由于定时器和数据报之间是一种一对多的关系,那么如果超时了,

我要如何区分是哪个数据报超时了?

在一个发送窗口中有2种数据,一种是已经发送出去但是还没收到确认的数据,一种是还未发送的数据。上图中2个指针分别指示这两种数据,左侧的指针还标识着一个发送窗口的左边界,而第二个指针指示着下个要发送的数据位置。按照这个图来看,我们很容易就可以发现,如果过了超时时间了,那么要重传的一定就是左侧的指针指向的位置,因为如果该元素收到ACK后,那么必然会像161一样随着发送窗口的滑动而不在这个窗口范围内。

3 接受窗口为0时的处理方案

在TCP的头部里面可以看到有2个字节的字段来标识窗口大小。

当接收窗口的值为0的时候,那么这时候发送端就不能再发数据,即使发了数据也会被扔掉。当接收窗口不为0的时候,接收端会发送一个报文来告诉发送端当前新的窗口值,但是考虑如果发送端的这个通告报文丢失了,那么发送端以为接收端的窗口值为0,接收端以为发送端没有数据,那么就会造成无限等待的死锁状况发生。所以TCP为了防止这种死锁状况,设定了一个坚持定时器(persist timer)规定在这种情况下发送端按无限次的指数避让间隔发出窗口探测包(1字节),TCP接收端立刻确认并更新通知窗口

4 糊涂窗口的场景和解决方案

假设接收窗口为0,接收端的处理程序反应很慢,每次只处理一个字节,如果现在就发送一个报文通知发送端现在接收窗口=1,那么按照定义来看,这时候发送端要发送一个“特殊”的报文即“至少20字节的头部 + 1字节的数据”,如果按照这样的趋势进行交互下去无疑会浪费很多的带宽,这就是糊涂窗口的症状。

解决方案: 当接受窗口再次达到MSS(最大报文长度)的一半大小的时候才发送一个报文来通告这个新的窗口值。在这个期间对发送端的探测报文都回应窗口值为0.

TCP 协议难点汇总,布布扣,bubuko.com

时间: 2024-10-16 21:39:35

TCP 协议难点汇总的相关文章

TCP协议要点和难点全解

说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面 2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的 3).针对对象:对TCP已经有了全面了解的人.因为本文不会解析TCP头里面的每一个字段或者3次握手的细节,也不会解释慢启动和快速重传的定义 4).除了<TCP/IP详解>(卷一,卷二)以及<Unix网络编程>以及Linux源代码之外,学习网络更好的资源是RFC 5).本文给出一个提纲,如果想了解细节,请直接查阅RFC 6).翻

tcp ip 协议简要汇总

OSI 7层模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 网络硬件 集线器: 工作在物理层,只能工作在半双工模式(不能同时读写),发送到端口A的数据,集线器上其他端口都能收到,集线器的端口能收到所有其他端口上收到的数据. 交换机:工作在数据链路层,交换机能够通过MAC地址唯一标识设备,交换机不会广播数据,他只会把数据发给指定MAC地址的设备,其内部有个CAM(内容寻址寄存器) 路由器:工作在网络层,路由器的端口与ip地址对应,其内部含有路由表,具有路由寻址功能. ARP协议

TCP协议疑难杂症全景解析

说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的3).针对对象:对TCP已经有了全面了解的人.因为本文不会解析TCP头里面的每一个字段或者3次握手的细节,也不会解释慢启动和快速重传的定义4).除了<TCP/IP详解>(卷一,卷二)以及<Unix网络编程>以及Linux源代码之外,学习网络更好的资源是RFC 5).本文给出一个提纲,如果想了解细节,请直接查阅RFC 6).翻来覆去

TCP协议疑难杂症全景分析

说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面 2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的 3).针对对象:对TCP已经有了全面了解的人.因为本文不会解析TCP头里面的每一个字段或者3次握手的细节,也不会解释慢启动和快速重传的定义 4).除了<TCP/IP详解>(卷一,卷二)以及<Unix网络编程>以及Linux源代码之外,学习网络更好的资源是RFC 5).本文给出一个提纲,如果想了解细节,请直接查阅RFC 6).翻

【转载】TCP协议疑难杂症全景解析

说明: 1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的3).针对对象:对TCP已经有了全面了解的人.因为本文不会解析TCP头里面的每一个字段或者3次握手的细节,也不会解释慢启动和快速重传的定义4).除了<TCP/IP详解>(卷一,卷二)以及<Unix网络编程>以及Linux源代码之外,学习网络更好的资源是RFC 5).本文给出一个提纲,如果想了解细节,请直接查阅RFC 6).翻来覆去

在网络7层协议中,如果想使用UDP协议达到TCP协议的效果,可以在哪层做文章?(QQ 为什么采用 UDP 协议,而不采用 TCP 协议实现?)

为了解决这题,可以具体看看下面这个讨论. 解灵运工程师 185 人赞同 某次架构师大会上那个58同城做即时通信的人说:原因是因为当时没有epoll这种可以支持成千上万tcp并发连接的技术,所以他们使用了udp,然后在udp上面封装了一下,模拟了一下tcp,解决了大并发的问题,之后因为做的很nb了,虽然epoll这种技术出现了,还是没有改回使用tcp了.现在再做类似的东西就不需要使用udp了.这个说法应该比较可信的. 发布于 2014-04-16 18 条评论 感谢 分享 收藏 • 没有帮助 • 

Android基础入门教程——7.6.2 基于TCP协议的Socket通信(1)

Android基础入门教程--7.6.2 基于TCP协议的Socket通信(1) 标签(空格分隔): Android基础入门教程 本节引言: 上一节的概念课枯燥无味是吧,不过总有点收获是吧,本节开始我们来研究基于TCP协议的Socket 通信,先来了解下Socket的概念,以及Socket通信的模型,实现Socket的步骤,以及作为Socket服务 端与客户端的两位各做要做什么事情!好的,我们由浅入深来扣这个Socket吧! 1.什么是Socket? 2.Socket通信模型: Socket通信

tcp协议分析

tcp协议解析 TCP在网络OSI的七层模型中的第四层--Transport层,IP在第三层--Network层,ARP在第二层--Data Link层.在第二层上的数据,我们叫Frame,在第三层上的数据叫Packet,第四层的数据叫Segment. 我们程序的数据首先会打到TCP的Segment中,然后TCP的Segment会打到IP的Packet中,然后再打到以太网Ethernet的Frame中,传到对端后,各个层解析自己的协议,然后把数据交给更高层的协议处理 TCP头格式 TCP数据段格

时间获取程序服务器 TCP 协议相关性

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 最初代码: 这是一个简单的时间获取服务器程序.它和时间获取程序客户端一道工作. TCP/IPv4, IPv6 协议相关 IPv4 --> IPv6 (把代码中出现的左边的字符串换为右边的,就变成了IPv6版本的) sockaddr_in --> sockaddr_in6 AF_INET --> AF_INET6 sin_family --> sin6_family sin_p