• Tcp连接的七次握手浅析


    LINUX 查看tcp连接数及状态

    # netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

    TIME_WAIT 8947 等待足够的时间以确保远程TCP接收到连接中断请求的确认
    FIN_WAIT1 15 等待远程TCP连接中断请求,或先前的连接中断请求的确认
    FIN_WAIT2 1 从远程TCP等待连接中断请求
    ESTABLISHED 55 代表一个打开的连接
    SYN_RECV 21 再收到和发送一个连接请求后等待对方对连接请求的确认
    CLOSING 2 没有任何连接状态
    LAST_ACK 4 等待原来的发向远程TCP的连接中断请求的确认

    TCP连接状态详解:
    LISTEN: 侦听来自远方的TCP端口的连接请求
    SYN-SENT: 再发送连接请求后等待匹配的连接请求
    SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认
    ESTABLISHED: 代表一个打开的连接
    FIN-WAIT-1: 等待远程TCP连接中断请求,或先前的连接中断请求的确认
    FIN-WAIT-2: 从远程TCP等待连接中断请求
    CLOSE-WAIT: 等待从本地用户发来的连接中断请求
    CLOSING: 等待远程TCP对连接中断的确认
    LAST-ACK: 等待原来的发向远程TCP的连接中断请求的确认
    TIME-WAIT: 等待足够的时间以确保远程TCP接收到连接中断请求的确认
    CLOSED: 没有任何连接状态

     

    连接的三次握手

    1. 客户端向服务器发送SYN请求
    2. 服务器发送ACK回应请求,并同时发送一个SYN的请求给客户端
    3. 客户端回应ACK应答

    关闭的四次握手

    对于关闭流程,一共有三种情况:客户端主动关闭,服务器端主动关闭,客户端和服务器端同时主动关闭。这里仅仅以客户端主动关闭为例列出下图。

    1. 客户端主动关闭,发送FIN请求
    2. 服务器回应ACK应答
    3. 服务器被动关闭,发送FIN请求
    4. 客户端回应ACK应答

    对于关闭流程,服务器端和客户端是对等的地位,其它两种场景处理过程类似。需要注意的是,由于对端是是可以主动关闭的,因此在代码中需要加上被动关闭的响应流程。

    为什么连接和关闭握手次数不一样

    看到上述流程,可能有一个疑问:为什么连接和关闭的握手次数不一样?其实,不论是连接还是关闭,客户端和服务器端都是发送了一次请求(SYN/FIN),回应了一次应答(ACK),它们是对称的。但是,在连接的时候服务器端的请求和应答是在一次握手中同时完成的,而关闭的时候却是分两次完成的,所以就造成了连接和关闭的握手次数不对称

    现在,新问题又来了:为什么连接时复用一次握手,而关闭的时候不复用握手?这个则是因为连接和关闭的行为不是一样所造成的。

    • 在连接过程中,客户端是主动连接,服务器端是被动连接,这个顺序是确定了的,因此,可以复用第二次握手。
    • 在关闭的过程中,客户端和服务器端可能同时主动关闭,此时就不能复用第二次握手了,因此请求和应答需要单独的发送。

    Tcp连接的状态迁移图

    前面只考虑了理想的情况,在实际的过程中,可能还需要处理一些异常操作,如下则是一个完成的TCP连接的状态迁移图。

     

     

    半打开连接和半关闭连接

    如前所述,建立或关闭一个连接时需要三或四步的,在这个过程中,TCP连接则会处于一个半打开或半关闭状态。例如,前面状态图中的FIN_WAIT_1和FIN_WAIT_2就是半关闭状态。

    一般来说,半连接只是一个暂停的过程。但是,在一些异常的情况的时候(如远端主机故障)的时候常常会造成半关闭连接,由于Tcp连接处于半打开或半关闭状态的时候,仍然会占用相应的端口资源,尤其对于http之类的海量服务来说,会造成大量端口被占用,会造成资源的浪费。

    另外,有的程序也针对Tcp协议的这一特征来恶意进行网络攻击。例如,对于一个服务器,大量的恶意客户端建立连接后,既不发请求,也不close套接字,这种情况下服务器如何保护自己呢。因为如果听之任之的话,大量的恶意连接会耗尽服务器的可用描述符,导致服务器不能服务。就算服务器主动close,如果客户端不close的话,那么这个连接还是不能完全释放。对于服务器来说,需要增加相应的机制进行半连接的处理。

  • 相关阅读:
    windows 程序设计自学:窗口正中显示Hello,World
    为网站图片增加延迟加载功能,提升用户体验
    线性表顺序存储
    sys.stdout sys.stderr的用法
    python 跳出嵌套循环方法
    * 与 ** 在调用函数时的作用
    twisted 学习笔记二:创建一个简单TCP客户端
    给命令行上色
    __new__ 的简单应用
    网友对twisted deferr的理解
  • 原文地址:https://www.cnblogs.com/xiaoyaojinzhazhadehangcheng/p/8042959.html
Copyright © 2020-2023  润新知