网络协议程序员

理解TCP协议

2018-06-11  本文已影响22人  ShutLove
  1. 首部格式
    16位源端口和目的端口、32位序号、32位确认序号、4位首部长度、6位操作标志位(SYN/ACK/FIN/RST/URG/PSH)、16位窗口大小、16位紧急指针、16位校验和
  2. 面向连接特性 三次握手 四次挥手
    三次握手过程示意图
    image
    AB建立连接,需要三次握手的原因,是为了确保A和B的发送接收都没有问题。第二次握手B响应,可以确认B的接收和A的发送能力;第三次A握手响应B,可以确认B的发送和A的接受能力。
    三次握手可以保证任何一次握手出现问题,都是可以被发现或补救的
    第一次握手A发送SYN传输失败,A,B都不会申请资源,连接失败。如果一段时间内发出多个SYN连接请求,那么A只会接受它最后发送的那个SYN的SYN+ACK回应,忽略其他回应全部回应,B中多申请的资源也会释放
    第二次握手B发送SYN+ACK传输失败,A不会申请资源,B申请了资源,但收不到A的ACK,过一段时间释放资源。如果是收到了多个A的SYN请求,B都会回复SYN+ACK,但A只会承认其中它最早发送的那个SYN的回应,并回复最后一次握手的ACK
    第三次握手ACK传输失败,B没有收到ACK,释放资源,对于后序的A的传输数据返回RST。实际上B会因为没有收到A的ACK会多次发送SYN+ACK,次数是可以设置的,如果最后还是没有收到A的ACK,则释放资源,对A的数据传输返回RST
    AB断开连接,四次挥手。
    A向B发送断开连接FIN,A进入FIN-WAIT-1;
    B回复ACK给A,说明收到了断开连接的请求,B进入CLOSE-WAIT,A进入FIN-WAIT-2;
    B再向A发送断开连接FIN,B进入LAST-ACK;
    A回复ACK给B,A进入TIME-WAIT;
    B收到最后ACK后,进入CLOSED;
    A等待TIME-WAIT时间后,进入CLOSED。
    A最后需要等待TIME-WAIT的原因有二:一是为了确保B能收到最后的ACK,或者即使收不到B还有时间能重发断开连接FIN;二是确保A由足够时间处理B发送的其他到达很慢的包,如果A不等待,那么这些包会对新占用A端口的程序造成干扰。
  3. 有序
    通过TCP首部的序号以及确认序号,结合IP首部的分片和偏移字段,可以保证即使被分片的TCP报文,在接收方处也可以重新把消息排序,并且丢弃重复收到的消息。
  4. 流量控制 滑动窗口
    • 滑动窗口协议允许发送方在停止并等待确认前可以连续发送多个分组。由于 发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。
    • 滑动窗口是动态变化的,每次接收方返回ack确认时,都会通告一个接收方当前可收的窗口大小。
  5. 可靠性 超时与重传
    • 超时通过定时器来实现,当消息超过定时器还未收到ack,就会重新发送,并且定时器时间加倍,以此类推,直到尝试过许多次后确认消息不可达,放弃重传。
    • 超时时间设定:发送方需要一直跟踪一个消息的往返时间(RTT),根据RTT、平滑参数以及RTT变化的方差,来不断地设定一个合理的超时时间。
  6. 拥塞控制
    拥塞避免算法和慢启动算法需要对每个连接维持两个变量:一个拥塞窗口 c w n d和一个慢 启动门限 s s t h re s h 。这样得到的算法的工作过程如下:
    • 对一个给定的连接,初始化 c w n d为 1 个报文段, s s t h re s h为 6 5 5 3 5 个字节。
    • T C P 输出例程的输出不能超过 c w n d和 接 收 方 通 告 窗 口 的 大 小 。 拥 塞 避 免 是 发 送 方 使 用 的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估 计,而后者则与接收方在该连接上的可用缓存大小有关。
    • 当 拥 塞 发 生 时 ( 超 时 或 收 到 重 复 确 认 ), s s t h re s h被设置为当前窗口大小的一半( c w n d 和接收方通告窗口大小的最小值,但最少为 2个报文段)。此外,如果是超时引起了拥塞,则 c w n d 被设置为 1 个 报 文 段 ( 这 就 是 慢 启 动 )。
    • 当新的数据被对方确认时,就增加 c w n d , 但 增 加 的 方 法 依 赖 于 我 们 是 否 正 在 进 行 慢 启 动或拥塞避免。如果 c w n d小于或等于 s s t h re s h, 则 正 在 进 行 慢 启 动 , 否 则 正 在 进 行 拥 塞 避 免 。 慢启动一直持续到我们回到当拥塞发生时所处位置的半时候才停止(因为我们记录了在步骤 2 中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。
    • 慢 启 动 算 法 初 始 设 置 c w n d 为 1 个 报 文 段 , 此 后 每 收 到 一 个 确 认 就 加 1 。这会使窗口按指数方式增长:发送 1个报文段,然后是 2个,接着是 4个⋯⋯。
    • 拥塞避免算法要求每次收 到 一 个 确 认 时 将 cwnd增加 1/cwnd 。 与 慢 启 动 的 指 数 增 加 比 起 来 ,我 们 希 望 在 一 个 往 返 时 间 内 最 多 为 c w n d 增加 1 个报文段 ( 不 管 在 这 个 R T T 中 收 到 了 多 少 个 A C K ), 然 而 慢 启 动 将 根 据 这 个 往 返 时 间 中 所 收 到 的 确 认 的个数增加 c w n d 。
    • 快速重传:如果一连串收到 3个或 3 个以上的重复 A C K ,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就 是快速重传算法。接下来执行的不是慢启动算法而是拥塞避免算法。这就是快速恢复算法。
  7. 坚持定时器
    如果一个确认丢失了,则双方就有可能因为等待对方而使连接终止:接收方等待接收数 据(因为它已经向发送方通告了一个非 0的窗口),而发送方在等待允许它继续发送数据的窗 口更新。为防止这种死锁情况的发生,发送方使用一个坚持定时器 (persist timer)来周期性地 向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查 ( w i n d o w p r o b e )。 而控制何时发送窗口探查的就是坚持定时器。
  8. keepalive机制 保活定时器
    保活定时器常用于服务器端,用来探查连接的client是否还在正常运行,去掉那些已经虚关浪费连接资源的客户端,默认设置是两个小时后发送探查分组完成保活功能。
  9. ,会发送探活包,避免连接被空占。
  10. 状态变化。服务端:LISTEN->SYN-RCVD->ESTABLISHED;客户端:SYN-SENT->ESTABLISHED.
上一篇下一篇

猜你喜欢

热点阅读