TCP报文结构
TCP报文结构
TCP特点
1、面向连接
2、可靠传输
3、流量控制
4、拥塞控制
TCP连接
所谓的TCP连接,并不是一条物理连接,只是发送端和接收端各自维护的一些与连接相关的变量和数据结构,具有以下特点:
1、点对点全双工,不能广播或者多播。
2、连接的每一端都有各自的发送缓存和接收缓存。
3、最大报文长度(Maximum Segment Size,MSS),报文里面应用数据的最大长度,不包括TCP首部。MSS=MTU - 20字节(TCP首部长度)- 20字节(IP首部长度)
4、需要通过三次握手建立连接,会引入连接延时。三次握手简单描述就是客户端首先发送一个SYN报文段,请求建立连接,服务器端用SYN+ACK报文段响应,最后客户端再向服务器端发送ACK报文段,连接建立完毕。其中第一次报文段和第二次报文段中,SYN=1,不能带有有效载荷,即应用数据。第三个报文段SYN=0,可以带有应用数据。
三次握手示意图如下:
TCP三次握手TCP连接过程中,客户端和服务器端状态变化如下:
客户端状态变迁 服务器状态变迁TCP可靠数据传输的实现
1、往返时延(RTT)
EstimatedRTT = (1 - α) × EstimatedRTT + α × SampleRTT
其中SampleRTT为最近某个时刻的RTT采样值,α为权重系数,RFC给出的参考值为0.125。
2、RTT变化偏差
DevRTT = (1 - β) × DevRTT + β × |SampleRTT - EstimatedRTT|
β为权重系数,推荐值为0.25
3、TCP重传超时间隔
TimeoutInterval = EstimatedRTT + 4 × DevRTT
RFC推荐TimeoutInterval的初始值为1s。
4、超时间隔加倍
当定时器启动时,按照上面的公式计算TimeoutInterval,每次发生超时重传时都将下一次的超时间隔设置为先前值的两倍。
5、快速重传
超时重传的一个问题是,超时周期可能相对较长。为了解决这个问题,当网络出现丢包的情况时,后发的分组可能会先到接收端,这时接收端发现接收的分组序号出现间隔,会发送对最后按序接收的分组的ACK,这样发送端会收到冗余的ACK。一旦发送端收到3个冗余的ACK,则发送端认为该分组已经丢失,会立即重传该分组。
6、选择确认
参考选择确认
流量控制
所谓流量控制就是协调发送方的发送速率和接收方的应用读取速率,使两者相匹配。如果不做流量限制,发送方的发送速率过快,会导致接收方的接收缓存溢出,丢失已经正确接收的分组,引起发送方不必要的重传。
TCP通过让发送端维护一个接收窗口(Receive Window,rwnd)的变量来提供流量控制。接收方会通过在ACK报文中填充接收窗口的大小,来指示接收方还有多少可用的缓存空间,如下图所示:
接收窗口(rwnd)和接收缓存(RcvBuffer)我们定义如下变量:
LastByteRead:接收方的应用进程从缓存中读出的数据流的最后一个字节编号。
LastByteRcvd:从网络中到达的并且已放入接收方接收缓存中的数据流的最后一个字节编号。
LastByteSent:发送方发送的最后一个字节编号
LastByteAcked:发送方接收到的最后一个字节编号
由于TCP不允许已分配的缓存溢出,所以以下公式成立:
LastByteRead - LastByteRcvd <= RcvBuffer
rwnd = RcvBuffer - [LastByteRead - LastByteRcvd]
LastByteSent - LastByteAcked <= rwnd
当接收方的接收窗口为0时,发送方会继续发送只有一个字节的报文段,用来探测接收方的接收窗口是否变大。
拥塞控制
TCP实现拥塞控制主要面临三个问题:
1、如何限制发送方的发送速率?
2、如何感知网络拥塞?
3、当感知到网络拥塞时,采用何种算法来调节发送速率?
为了解决第一个问题,在发送端维护一个额外的变量,即拥塞窗口(Congestion Window,cwnd)。cwnd对发送方能向网络中发送流量的速率进行了限制,公式如下:
LastByteSent - LastByteAcked <= min(rwnd,cwnd)
假设接收缓存足够大,忽略rwnd的限制,则在一个RTT时间内,发送方的最大发送速率为cwnd/RTT 字节/秒,这样就限制了发送方的发送速率。
TCP通过丢包事件来感知网络拥塞。TCP将丢包事件定义为,要么出现超时,要么收到3个冗余的ACK。
发送端通过TCP拥塞控制算法来调节发送速率,FSM图如下:
TCP拥塞控制算法FSM
网友评论