TCP协议中的三次握手和四次挥手

介绍

TCP 数据包简单介绍

  • 标识位

    • SYN – synchronous 建立连接
    • ACK – acknowledgement 确认
    • FIN – finish 结束
  • 其他

    • seq 顺序号码
    • ack 确认号码
  • tcp首部详解


三次握手

  • 流程

    • 第一次握手
      发送方首先发送一个带有 SYN 标志的数据包给对方, 表示请求建立连接
      数据包内容: SYN = 1, seq = m(随机数)

    • 第二次握手
      接收方收到后, 回复一个带有 SYN/ACK 标志的数据包(传递确认信息), 表示我收到了
      数据包内容: SYN = 1, ACK = 1, ack = m+1, seq = n(随机数)

    • 第三条握手
      发送方回复一个带有 ACK 标志的数据包, 表示连接建立成功
      数据包内容: ACK = 1, ack = n+1


  • 图解

在这里插入图片描述


四次挥手

  • 流程

    • 第一次挥手
      A(申请断开方)发送一个带有 FIN 标志的数据包, 表示我不再发送数据了
      数据包内容: FIN=1, seq=x(随机数)

    • 第二次挥手
      B(接收方)收到后, 回复一个带有 ACK 标志的数据包, 我收到了, 但此时接收方可能会继续发送数据
      数据包内容: ACK = 1, ack=x+1

    • 第三次挥手
      B(接收方)发送一个带有 FIN 标志的数据包, 表示我发完了, 并且我也不再发送数据了
      数据包内容: FIN=1, seq=y(随机数)

    • 第四次挥手
      A(申请断开方)回复一个带有 ACK 标志的数据包, 表示连接断开
      数据包内容: ACK=1, ack = y+1


  • 图解

在这里插入图片描述


QA

为什么要有三次握手和四次挥手

  • TCP协议面向连接的, 所有传输数据前必须先建立连接
  • 三次握手是为了建立连接的,建立连接时 接收方的ACK和SYN是在一个报文中发送的
  • 四次挥手是为了断开连接,断开连接时, 接收方的ACK和FIN是分两次发送的

为什么四次挥手的ACK和FIN要分开发送

  • 因为FIN只表示发送方"我"不再发送收据, 但仍可以接收数据
  • 这时己方可以选择直接断开连接, 也可以选择继续发送数据给对方,直到发送完成后,再断开连接

问题处理

timewait 过多

  • 原因

    • timewait 是“断开发起方”的状态
    • 该状态处于已经向“被断开方发”送 ack 之后,等待系统销毁期间
    • 所以过多的原因一般是因为短期内断连太多导致
  • 处理

    # from https://blog.csdn.net/MiSiTeLin/article/details/115218672
    
    /etc/sysctl.conf
    
    # 对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间
    net.ipv4.tcp_syn_retries=2
    #net.ipv4.tcp_synack_retries=2
    
    # 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
    net.ipv4.tcp_keepalive_time=1200
    net.ipv4.tcp_orphan_retries=3
    
    # 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
    net.ipv4.tcp_fin_timeout=30
    
    # 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
    net.ipv4.tcp_max_syn_backlog = 4096
    
    # 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
    net.ipv4.tcp_syncookies = 1
    
    # 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
    net.ipv4.tcp_tw_reuse = 1
    
    # 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
    net.ipv4.tcp_tw_recycle = 1
    
    # 减少超时前的探测次数
    net.ipv4.tcp_keepalive_probes=5
    
    # 优化网络设备接收队列
    net.core.netdev_max_backlog=3000
    

closewait 过多

  • 原因

    • 接收请求断开并回复后,被动断开方就处于 closewait 状态
    • 过多表示没有发送自己的 fin
    • 检查当时是否有数据未发送完成,如果流量为空,需要检查后端代码是否调用 socket close() 方法
  • 处理

    • 有流量表示数据未传输完成
    • 无流量表示代码未释放 socket 连接

相关连接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值