美文网首页
TCP状态转换

TCP状态转换

作者: StevenHD | 来源:发表于2020-12-10 21:40 被阅读0次
    大纲

    一、TCP状态转换

    • 端口一开始都是关闭状态

    • 服务器调用accept()函数会把端口从CLOSTED变为LISTEN状态

    • 客户端调用connect()函数发送SYN报文后,就进入了SYN_SEND状态

    • 服务器收到ACK报文会变成ESTABLISHED状态,然后就会产生新的套接字(处于数据可传输状态与客户端的套接字进行数据传输),旧的套接字会从ESTABLISHED数据可传输状态回到LISTEN监听状态

    • 客户端调用close()函数发送FIN报文,也会关闭掉客户端的套接字,进入FIN_WAIT_1状态,当客户端收到服务器回应的ACK报文后,就会从FIN_WAIT_1状态变回FIN_WAIT_2状态

    • 服务器收到处于FIN_WAIT1客户端发送过来的FIN报文后,会变成CLOSE_WAIT状态

    • 然后,服务器端也调用close()函数,就会从CLOSE_WAIT状态转换为LAST_ACK状态,同时发送FIN报文给客户端,客户端就就会变成TIME_WAIT状态,然后回复ACK给服务器,那么服务器就会变成CLOSED状态

    被动方关闭的一端更早地进入CLOSED状态
    主动方关闭的一端会进入TIME_WAIT状态,等一段时间后才能转化为CLOSED状态

    二、观察每个状态

    2.1 套接字处于LISTEN状态

    • 注意:是accept()函数的调用让服务器的状态从CLOSED变成LISTEN状态。调用listen()函数只是让服务器具备监听能力
    • SYN_SENT和SYN_RECV状态是捕捉不到的,因为很快(ACK是自动回复的,所以状态转换很快)。但是ESTABLISHED状态是可以的——
      当我们先只打开服务器的时候,我们就进入了LISTEN状态:
    LISTEN状态

    紧接着,当我们再打开客户端以后,就进入了ESTABLISHED状态:

    ESTABLISHED状态
    • 同理,因为ACK是协议栈自动回复的,所以FIN_WAIT1这个状态是捕捉不到的

    主动调用close()的函数的一端就会处于FIN_WAIT2状态,被动关闭的就是处于CLOSED_WAIT状态

    2.2 FIN_WAIT_2状态和CLOES_WAIT状态

    • 客户端先关闭套接字,但是服务器并不关闭套接字:
    图示结果

    CLOSE_WAIT状态有一个超时时间,过一会儿就会自动消失

    2.3 TIME_WAIT状态

    • 2MSL

    为什么不直接关闭掉,而是要等2MSL

    出现了大量的CLOSE_WAIT状态的原因?
    服务器端的代码有bug,忘记调用close()函数关闭套接字了

    客户端处于TIME_WAIT状态是无所谓的,因为端口可以临时分配,但是服务器端如果是TIME_WAIT状态就会导致端口不被释放,一直在2MSL中处于被占用状态。

    三、服务器和客户端同时关闭的状态

    大纲

    四、FIN和ACK一起发

    相关文章

      网友评论

          本文标题:TCP状态转换

          本文链接:https://www.haomeiwen.com/subject/wzpzwktx.html