• 【笔记】关于TCP三次握手和四次挥手的理解


    1. 三次握手:

      服务器一定处于Listen状态,否则客户端发过来的连接会被拒绝。注:服务器和客户端的角色是相对的。

      客户端发送第一次握手(客户端发送连接请求(SYNC包)到服务器)之后由Closed状态转为Sync-Send状态;

      服务器收到第一次握手的客户端SYNC包,然后发送第二次握手(服务器发送SYNC+ACK(客户端SYNC包的确认)包给客户端)之后服务器由Listen状态转为Sync-Recv状态;

      客户端收到第二次握手的服务器SYNC+ACK包,然后发送第三次握手(客户端对“服务器的SYNC+ACK包“的ACK包给给服务器)之后客户端就转为ESTABLISHED状态;

      服务器收到第三次握手的客户端ACK包之后也进入了ESTABLISHED。

    2. 四次挥手:

      服务器与客户端都处于ESTABLISHED状态,且有一方主动发起了关闭,另外一方会被动关闭。被动关闭的一方需要处理socket的资源回收等,被动关闭的一方需要及时关闭,所以说被动关闭的一方出现大量CLOSE_WAIT状态通常都是因为程序代码问题。

      主动关闭的一方(可能是服务器也可能是客户端)的状态迁移:FIN-WAIT1->FIN-WAIT2->TIME_WAIT-CLOSED

      被动关闭的一方的状态迁移:CLOSE_WAIT->LAST_ACK->CLOSED

      同时关闭:双方状态一致: FIN_WAIT1->CLOSING->TIME_WAIT

      假设客户端主动关闭连接,以下说明客户端和服务器如何迁移:

      客户端发送第一次挥手(客户端第一个FIN包给服务器)之后由ESTABLISHED状态转为FIN_WAIT1状态;

      服务器收到客户端的第一次挥手(客户端第一个FIN包给服务器)之后,发送第二次挥手(对客户端FIN的ACK确认包)给服务器,服务器进入CLOSE_WAIT状态,等待服务器自身的socket关闭等处理(等待IO,业务处理,资源回收等等);

      客户端收到服务器的第二次挥手(对客户端FIN的ACK确认包),进入FIN_WAIT2状态,等待服务器关闭(服务器调用close函数发送服务器的FIN包);

      服务器发送第三次挥手(在处理完自己的事情,调用close函数之后,发送服务器的FIN包),进入LAST_ACK状态;

      客户端收到第三次挥手(服务器的FIN包),发送第四次挥手(客户端第二个FIN包+ACK(对服务器FIN包的确认)),客户端进入TIME_WAIT状态;

      服务器收到第四次挥手(客户端第二个FIN包+ACK(对服务器FIN包的确认)),进入CLOSED状态;

      客户端等待2MSL时间,进入CLOSED状态

      注:FIN_WAIT2状态等待时间是有限的,系统可配:tcp_fin_timeout 这个参数可以控制改状态存活的时间

        FIN_WAIT1和CLOSE_WAIT是比较危险的状态,一般服务器网络鼓掌首先要查看这俩个状态是否正常:CLOSE_WAIT在上面说过,如果服务器代码有问题(忘记close等),服务器会一直有需要的CLOSE_WAIT状态的socket,造成服务器不可连接;FIN_WAIT1会在发出来FIN而没有手到ACK会重新发送FIN,重发次数由系统参数配置:tcp_orphan_retries;如果系统负载过重,减少tcp_orphan_retries值可能有作用。

        一般来说FIN_WAIT1几乎不可见,因为服务器之间的ACK速度非常快;

        FIN_WAIT1 的DDos攻击举例说明:http://huoding.com/2014/11/06/383

    参考:http://coolshell.cn/articles/1484.html

    TCP共有11个网路状态,其中涉及到关闭的状态有5个。

    在我们编写网络相关程序的时候,这5个状态经常出现。因为这5个状态相互关联,相互纠缠,而且状态变化触发都是由应用触发,但是又涉及操作系统和网络,所以正确的理解TCP 在关闭时网络状态变化情况,为我们诊断网络中各种问题,快速定位故障有着非常重要的作用和意义。

    下是是根据W.Richard Stevens的《TCP/IP详解》一书的TCP状态转换图。

  • 相关阅读:
    抓老鼠啊~亏了还是赚了?
    golang实现AES加密和解密-自已动手写个加解密软件
    安卓hello wolrd【未成功】
    go template修改定界符Delims的坑
    解决liteIDE没有代码提示及跳转问题
    go vue真是稀缺组合(cdn方式)
    golang ---查看进程(Windows)
    go 通过代理服务器获取网站内容
    go 不要通过共享内存来通信,相反,应该通过通信来共享内存
    用rod获取百度搜索结果的例子
  • 原文地址:https://www.cnblogs.com/pengyusong/p/5781059.html
Copyright © 2020-2023  润新知