TCP包头分析

来源:互联网 发布:qcard软件源 编辑:程序博客网 时间:2024/04/28 00:18

TCP包头分析:

SYN
同步序号,用来发起一个连接。syn位用于建立连接的过程(如TCP三次握手)。
ACK
建立连接和数据发送,关闭连接都用。 ack位被设置为1表示ack_seq是有效的。如果ack为0,则该数据段不包含确认信息,所以,ack_seq域应该被忽略。
RST
连接异常。
FIN
用于释放一个连接。它表示发送方已经没有数据要传输了。
SEQ
等于该主机选择本次连接的初始序号加上报文段中第一个字节在整个数据流中的序号。在连接建立的时候,会随机选择一个初始序号。序号是32 bit的无符号数。
WINDOW
16 位滑动窗口的大小,单位为字节。接受方用来通知发送方接受 buffer 的大小,发送方不能过分的发送,导致接受方的 buffer 溢出。
PSH
 接收方在收到数据后应立即请求将数据递交给应用程序,而不是将它缓冲起来直到整个缓冲区接收满为止(这样做的目的可能是为了效率的原因)
URG
发送紧急数据。这个设施可以代替中断信息。


TCP 的重传机制 Go-Back-N
    接受方不断发送 ACK 信息和 32 位的 acknowledge seq number, 用来通知发送方,期望接收到数据包的序号,同时也表示已经正确接收的数据。acknowledge seq number 不一定要连续。

Delayed ACK
    TCP 并不是对收到的数据立即发送 ACK 信息,而是希望ACK 信息随着数据一起发送。如果在 200 ms 内,没有数据需要发送,那么就发送一个不含数据的 ACK 数据包。这个数据包不应该增加 TCP 的顺序编号,接受方应该从数据长度上判断出这个包是一个控制包。
    还有一种算法是如果接收到一个数据包之后,启动一个计时器,在计时器超时之前没有可供 piggy back 的数据发送,那么就发送一个 纯 ACK ,一个不带数据包的 ACK 消息。

滑动窗口
    当收到 ACK 的时候,发送方的窗口变大,也叫开窗, 当发送数据的时候,发送方的窗口变小,也叫关窗。在窗子完全关闭的时候,不能在发送数据了。

下面要用到的一些术语的定义:
数据段(segment):一个数据段就是任意的TCP/IP数据或确认包(或两者兼备)。
发送端最大数据段尺寸(SMSS):SMSS是发送端能发送的最大数据段的尺寸。
接收端最大数据段尺寸(RMSS):RMSS是接收端愿意接收的最大数据段的尺寸。
满尺寸数据段:一个包括允许最大数目数据的数据段(也就是说,一个包括SMSS字节数据的数据段)。

拥塞窗口(the congestion window:cwnd):是对发送端收到确认(ACK)之前能向网络传送的最大数据量的一个发送端限制。
接收端窗口(rwnd):是对未完成数据量的接收端限制。Cwnd和rwnd的最小值决定了数据传送。
慢启动阀值(ssthresh),被用来确定是用慢启动还是用拥塞避免算法来控制数据传送。

初始窗口(iw):初始窗口是三次握手完成后发送端的拥塞窗口的尺寸。
丢失窗口(lw):丢失窗口是在一个TCP根据它的重传定时器检测到了数据丢失之后,拥
塞窗口的尺寸。
重启窗口(rw):重启窗口是TCP在一段闲置期之后重新开始传送后拥塞窗口的尺寸(如
果使用慢启动算法;参见4.1节以获取更多的讨论)。
传送尺寸:已经被发送但还没有确认的数据的总量。


拥塞控制算法
   (四种:慢启动,拥塞避免,快速重传和快速恢复)
    1.慢启动和拥塞避免
    慢启动算法在cwnd<ssthresh时使用,拥塞避免算法在cwnd>ssthresh时使用。当cwnd和ssthresh相等时,发送端既可以使用慢启动也可以使用拥塞避免。
cwnd<ssthresh时
    慢启动
    发送方收到一个 ACK ,增加cwnd 。
    cwnd = cwnd + MSS    (MSS < SMSS)
    cwnd = min(cwnd,rwnd)
    如果是 DUPACK ,那么也应该增加。一个 segment 的大小是可变的,假设是个固定值,当出现 3 个DUPACK 的时候,进入 Fast Recovery 过程。当出现超时重传,则进到 Congestion Avoid 的过程。
cwnd>ssthresh时:
    拥塞避免
    收到一个 ACK 的时候,增加 cwnd。
    cwnd = cwnd + MSS*MSS/cwnd
    如果有 3 各重复的 ACK ,那么应该进入 FastRecovery 的过程。如果有重传,那么应该进入 Slow Start 的过程。可以重传第一个 Unacknowledged segment ,也可以重传许多。DUP ACK 不能增加

    2.快速重传/快速恢复
    快速重传算法以三个重复ACK的到达(收到四个一样的ACK,其间没有任何其他包到达)为一个数据段已经丢失的标志。在收到三个重复ACK之后,TCP不等重传定时器超时就重传看来已经丢失的数据段。
  
    当一个TCP用重传定时器检测到数据段丢失时,ssthresh的值必须设定大于等式中给出的值:
   ssthresh = max (FlightSize / 2, 2*SMSS)     (FlightSize是仍在网络中传送的数据量)

    快速重传
    当收到 3 各 DUPACK 的时候会进入 Fast Recovery .重传第一个 unacknowledged segment.
    改变 ssthres , sshres = max(flightsize/2, 2*SMSS)
    改变 cwnd , cwnd = 3*SMSS
    重置重传定时器。
    如果还有新的 DUPACK 到来,那么 cwnd 还会增加, 每次增加 SMSS, 当有 ACK 确认最新的数据,那么 cwnd 设置成为 sshres , 进入 Congestion Avoid 的过程。

    如果在 fast Recovery 的过程中,出现重传, 应该进入 Slow Start 的过程。
    发生重传的处理
    cwnd = MSS
    sshres = max(flightsize/2, 2*MSS)
    重置对于 DUPACK 的计数器
    RTO = min(2*RTO, 64 seconds)
    如果一个包超过重传 4 次,那么 TCP 连接关闭。
    重置关于重传的计时器。
    停止测量 RTT 和 RTO 。
    不再发送新的数据包
    当所有 on the fly 的包都得到确认之后,启动关于重传的计时器,进入 slow start 的过程

    如果在重传的过程中,还发生了重传,也就是计时器超时。
    重新分组。发送方不一定重传和原来一模一样的包,也可以在重传的包内包含新的数据,以增加吞吐量. 尤其是有很多小包的时候。应该发送出去多少个重传的包呢?
    如果在 slow start 的时候超时,应该传送一个 cwnd 那么多的包,cwnd = MSS.
    如果在 congestion avoid 的时候超时,应该传送一个 cwnd 那么多的包,cwnd = MSS.
    如果因为三个 dup ack ,那么应该发送 1 个包。
    如果在 fast recover 的过程中, 每收到一个 DUP ACK ,增加 cwnd 一个 MSS ,发送一个新包。
    RTO 和 RTT 的测量
    RTT_Err = RTT_Delay - RTT_Ave
    RTT_Ave = RTT_Ave + 0.125 × RTT_Err
    RTT_Dev = 0.75 × RTT_Dev + 0.25 × | RTT_Err |
    RTO = RTT_Ave + 4 × RTT_Dev

    根据实现不同,可能所有的包都作测量,也可能选择某些包作测量。

    乱序的包
    如果收到乱序的包,那么就应该立即发送 ACK ,以确保对方知道 DUPACK ,然后及时重传。