• TCP11种状态集之TIME_WAIT


    先看一个实例,上代码:

    #!/usr/bin/env python3
    # _*_ coding:utf-8 _*_
    import socket
    sk = socket.socket()
    sk.bind(("0.0.0.0",9000))   # 把IP绑定到套接字
    sk.listen()                  # 监听链接
    
    
    print("等待客户端连接....")
    conn,addr = sk.accept()     # 接收客户端链接
    print("IP: %s Port: %s  已建立连接..." %(addr[0],addr[1]))
    
    client_data = conn.recv(1024)   # 接收客户端信息
    print(client_data)              #打印客户端信息息
    
    conn.send(b"haha")              # 向客户端发送信息
    
    conn.close()            # 关闭这次的连接
    sk.close()          # 关闭服务器socket,相当于停止了服务
    基于tcp协议的socket server

    运行以上代码: 使用 telnet 连接服务端

     # 客户端退出连接, 再次启动服务端会报错,说端口已经被占用。

    # 查看tcp状态,TIME_WAIT。。什么鬼  程序已经结束了,socket为啥还存在呢? 这是因为tcp协议的可靠性。

     

     解决办法:

    #加入一条socket配置,重用ip和端口
    
    phone=socket(AF_INET,SOCK_STREAM)
    phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
    phone.bind(('127.0.0.1',8080))
    方法一:在代码中加参数
    vi /etc/sysctl.conf
    
    编辑文件,加入以下内容:
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30
     
    然后执行 /sbin/sysctl -p 让参数生效。
     
    net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
    
    net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    
    net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
    
    net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
    linux系统: 设置内核参数

    tcp协议三次握手与四次挥手

    三次握手:

      

    01.客户端:
    客户端发送syn信息给服务端,然后客户端从closed状态变为syn_send(请求建立连接)状态(三次握手的第一次握手)
    01.服务端:
      ①服务端从closed(关闭状态)状态转换为listen(监听状态)状态(在服务端开启相应服务),只有在listen状态才可以接收客户端建立连接请求
          closed--listen状态,实际上就是创建了一个socket条目信息
    ②服务端在listen状态接收到客户端发送的syn请求,会响应syn和ack信息,并且从listen状态变为syn_rcvd状态(三次握手的第二次握手)
    02.客户端:
    客户端在syn_send状态接收到syn和ack字段信息,然后回复ack确认信息(三次握手的第三次握手)
       syn_send状态变为最终建立连接的状态(established)
    02.服务端:
      服务端在syn_rcvd状态接收到了ack字段信息,从syn_rcvd状态变为established
    tcp三次握手状态集的转换

     四次挥手:

      

    1.客户端:
    在established状态发送fin字段信息给服务端(四次挥手过程第一次挥手)
    然后客户端状态转变为fin_wait1(第一次等待:服务端的确认ack信息)
    2.服务端:
    ① 服务端在established状态接收到客户端发送的fin字段信息,从established状态变为close_wait
    ② 服务端在close_wait发送ack确认字段(四次挥手的第二挥手)
    3.客户端
    ①客户端在fin_wait1状态接收服务端的ack信息,进入到fin_wait2(第二次等待:)
    4.服务端:
     服务端在close_wait发送fin断开连接字段给客户端(四次挥手的第三次挥手)
           服务端从close_wait变为last_ack状态
    5.客户端
    客户端在fin_wait2状态接收服务端的fin信息,然后响应ack信息,并将自己的状态转变为time_wait状态
      (四次挥手的第四次挥手)
    6.服务端:
    服务端在last_ack状态接收到客户端发送的ack字段信息之后,就会最终变为closed状态
    7.客户端:
    在time_wait会等待120秒钟时间,才能进入到closed状态
    tcp四次挥手状态集的转换

    tcp十一种状态集转换

  • 相关阅读:
    HDU3336 Count the string —— KMP next数组
    CodeForces
    51Nod 1627 瞬间移动 —— 组合数学
    51Nod 1158 全是1的最大子矩阵 —— 预处理 + 暴力枚举 or 单调栈
    51Nod 1225 余数之和 —— 分区枚举
    51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP
    51Nod 机器人走方格 V3 —— 卡特兰数、Lucas定理
    51Nod XOR key —— 区间最大异或值 可持久化字典树
    HDU4825 Xor Sum —— Trie树
    51Nod 1515 明辨是非 —— 并查集 + 启发式合并
  • 原文地址:https://www.cnblogs.com/root0/p/10471901.html
Copyright © 2020-2023  润新知