【lwip】12-一文解决TCP原理( 四 )


  1. SYN与ACK标志位1
  2. 将TCP报文段首部的确认序号字段设置为A+1 (这个A(ISN)是从握手请求报文中得到) 。
  3. 服务器随机选择自己的初始序号(ISN,注意此ISN是服务器端的ISN,假设为B),并将其放置到TCP报文段首部的序号字段中 。
  • 第三步 :客户端接收到服务器端的握手应答后,会将 SYN 置 0,ACK 置 1,确认序号置为B+1 , 设置窗口值,可以添加数据域的报文段发给服务器端 。同时给该TCP连接分配缓存和变量 。( 建立服务端-->客户端的连接 )( 客户端和服务器端都进入ESTABLISHED状态 )
  • ISN:初始序列号(Inital Sequence Number) 。
    【lwip】12-一文解决TCP原理

    文章插图
    三次握手的原因:
    1. 避免重复连接(主要原因):参考RFC 793,主要原因是为了防止旧的重复连接引起连接混乱问题 。假设两次握手,如果由于网络原因出现SYN重传,第一个SYN请求到达后建立连接,数据交互完毕后关闭连接,如果此时服务器收到重传过来的SYN请求,就直接建立连接,这样会导致虚假连接 。
    2. 同步双方初始序列号:TCP 协议的通信双方, 都必须维护一个序列号 。SYN请求连接的报文,需要服务端回一个ACK应答报文,表示客户端的SYN报文已被服务端成功接收,那当服务端发送SEQ给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步 。
    3. 避免资源浪费:只需要三次握手即可 。
    12.6.2 四次挥手
    【lwip】12-一文解决TCP原理

    文章插图
    等待2MSL的原因:
    1. 保证 TCP 协议的全双工连接能够可靠关闭 。
      • 如果远端没有收到 ACK ,触发超时重发 FIN 报文段,主动端依然能处理重发 ACK 。如果主动端直接 CLOSE 状态,就不能保证远端收到 ACK 。
    2. 保证这次连接的重复数据段从网络中消失 。
      • 保证下次连接收到的数据报文段都是来自新连接的目标端 。
    3. 2MSL的原因:ACK到达对端最长时间是MSL,如果在ACK到达对端前,多对发送重传FIN,FIN过来最长时间是也MSL,所以共2MSL 。如果等待2MSL都没有收到FIN,就可以认为对端已经收到我们的ACK 。
    SO_REUSEADDR选项的配置,能直接复用处于TIME_WAIT状态的端口 。
    四次挥手的原因:而在释放连接时需要四次是因为TCP连接的半关闭造成的 。由于TCP是全双工的(即数据可在两个方向上同时传递),所以,每个方向都必须要单独进行关闭,单方向的关闭就叫半关闭 。
    12.6.3 同时打开同时打开需要交换4个报文段,比正常的三次握手多一个 。没有任何一端称为客户或服务器,因为每一端既是客户又是服务器 。
    【lwip】12-一文解决TCP原理

    文章插图
    12.6.4 同时关闭在标准的情况下通过一方发送FIN来关闭连接,但是双方都执行主动关闭也是有可能的 。
    【lwip】12-一文解决TCP原理

    文章插图
    12.6.5 半关闭半关闭:TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力 。
    如果应用程序不调用close()而调用shutdown(),且第2个参数值为1,则插口的API支持半关闭,举个例子:
    【lwip】12-一文解决TCP原理

    文章插图
    12.7 窗口TCP数据中每一个字节都有自己的编号SEQ,而窗口就是能接收或发送的SEQ段 。
    12.7.1 窗口大小通告就是TCP报文段首部的窗口字段 。
    用来告知发送端自己所能接收的数据量,从而达到一部分流控的目的 。

    经验总结扩展阅读