人生像攀登一座山,而找寻出路,却是一种学习的过程,我们应当在这过程中,学习稳定、冷静,学习如何从慌乱中找到生机。——席慕蓉
TCP
TCP协议概述
TCP是面向连接的协议,在数据传输前,需要在发送方和接收方之间建立起专属的TCP连接。
TCP连接提供全双工服务,一旦A和B之间有了连接,那么数据可以从任一方到另一方。TCP是点对点的,也就是说只能有两台主机参与连接。
在连接建立时,客户向服务器发送第一段TCP报文段,服务器响应客户第二段TCP报文段,客户向服务器发送第三段TCP报文段。这个过程称为三次握手。
在连接建立后,双方要传输数据:
TCP连接在主机的运输层上部署了发送缓存和接收缓存。当数据即将被发送出去时,它被存储到发送缓存中。发送方取出缓存中的一些数据。TCP一次取出的数据量受限于最大报文段长度,即在封装上运输层和网络层(TCP/IP)首部后不能大于最大链路层帧长度(最大传输单元)。
报文段结构
- 源端口号,目的端口号
- 序号字段,确认号字段:用于实现可靠数据传输
- 首部长度字段:顾名思义,指出首部长度
- 标志字段:包括六个标志。ACK指明该报文是一个ACK报文;RST,SYN,FIN用于建立连接和拆除连接;PSH用于指示接收方立即将数据交给上层;URG指示报文中含有被接收方上层认为“紧急”的数据,这些数据的最后一个字节由16位的紧急数据指针字段。当有紧急数据并存在指向其尾部的指针时, TCP必须通知接收端上层实体
- 接收窗口字段:用于流量控制
- 检验和字段
- 选项字段:用于规定一些额外的其他东西
- 数据字段
序号、确认号
序号和确认号一起构成了可靠数据传输技术的一部分。TCP协议对待发送数据的每一个字节编号,当主机A发送一个报文时,序号是它发送的数据中第一个字节的编号;与之相对的,确认号是它期望另一方(设是主机B)在给它发送的数据报的序号:
其中0,1000都是序号。
对于确认号,如果主机A收到来自B的包含序号为0的535个字节数据的,然后因为某些原因(可能是丢包)收到的下一个报文段序号是900,也就是说536-900这段数据是缺失的,为了填补这段空缺,主机A会在下一个发送的报文上设置确认号为536。这种机制称为累计确认机制。
另外,当主机A收到序号为536的报文段之前收到序号为900的报文段,即收到失序报文段,那么它有两种选择:丢弃失序报文段或将失序报文段缓存。实践中常采用后者。
另外,这种方式也可以代替ACK报文的功能。如果主机A向B发送了序号为42的报文,那么接下来当主机B向A发送的报文中确认号为42以后的序号,说明这段报文成功被接收;反之,如果确认号仍是42,说明这段报文未被成功接收。
超时问题
计算RTT
TCP也通过维护一个计时器来处理超时问题,但它对超时的时间量(RTT)处理有所不同。
TCP协议通过估计所有报文的RTT(抽调一个报文的样本RTT,即SampleRTT)来确定一个总的RTT(平均RTT,EstimatedRTT),在实践中,TCP每次为一个已发送但未确认的报文段测量SampleRTT。获得了一个新的SampleRTT后,TCP通过下面的加权运算来计算EstimatedRTT:
其中通过控制α的值来控制旧的EstimatedRTT和新SampleRTT所占权值。α一般取0.125,则公式为:
由于旧的EstimatedRTT也是通过SampleRTT确定的,因此越旧的SampleRTT的权值会越小。
我们也要计算RTT的变化(DevRTT),它反映了网络拥塞程度的波动。计算公式如下:
基本思路和EstimateRTT相同,只是将之前的偏差值和现在的偏差值进行了加权运算。
计算重传时间
我们通过计算出的RTT值来确定重传时间,保险起见,当EstimateRTT偏差过大时,就要将重传值设置的大一些。因此,计算重传时间TimeoutInterval的公式如下:
初始重传时间设置为1秒,当未收到新的EstimateRTT时,每出现一次超时,该时间加倍以避免过早出现超时。当更新EstimateRTT时,重新利用该公式计算重传时间。
可靠数据传输
在上面讲的序号,确认号和重传技术的基础上,我们可以构建可靠数据传输技术。我们先给出可靠传输的阉割版。在这个版本中,TCP协议和重传的有关事件有三个:接收数据,超时事件,收到ACK。
- 接收数据:TCP接收数据并发送,如果这是第一个未被确认的报文段,则启动计时器。
- 超时:进行重传并重启计时器。
- 收到ACK:在TCP中,ACK字段可以随接收到报文的主机发送的带有数据的报文一起回送。由于TCP采用累计确认,收到ACK报文的主机可以直接将SendBase(第一个未被确认的报文的序号),移至ACK字段所指的序号。例如,如果主机A当前的SendBase是100,它收到了主机B带有确认号为300的报文,那么它确定从100到299字节的数据已经成功被接收,将SendBase移至300。
伪代码如下:
另外,在每次重传后,TCP重启计时器并将重传时间加倍,但发生了超时之外的另两个事件时,重新用公式计算重传时间。
除了超时之外,TCP还可以使用冗余ACK技术检测丢包。由于TCP采用累积确认,因此当3个ACK字段都指向相同的序号时,TCP确认这个序号的报文段发生丢包。例如,如果主机A向B发送了序号为100,200,300的三个报文,但在从主机B回送的报文中超过三个都含有确认号为200的报文,因此可以确定200-299这些字节的报文发生了丢包,于是主机A重传200-299这些字节的报文。这个技术被称为快速重传技术,下面是伪代码:
从累积确认的角度来看,TCP差错恢复机制类似于一个GBN协议;但从缓存失序报文段的角度来看,它又类似于一个SR协议,因此最好将其当做GBN和SR的混合体。
我是霜_哀,在算法之路上努力前行的一位萌新,感谢你的阅读!如果觉得好的话,可以关注一下,我会在将来带来更多更全面的知识讲解!