TCP连接三次握手四次挥手原理

TCP报文格式

  • URG紧急指针是否有效。为1,表示某一位需要被优先处理
  • ACK确认号是否有效,一般置为1。
  • PSH提示接收端应用程序立即从TCP缓冲区把数据读走。
  • RST对方要求重新建立连接,复位。
  • SYN请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1
  • FIN 希望断开连接。

三次握手

在这里插入图片描述

个人总结:
三次握手是为了client和server互相确认收发都没有问题。
server端是开着监听等待,client是主动发送连接。

第一次握手

进行的操作: client发送请求 标志位syn=1(表示请求建立连接)、seq是个随机数字x
目的: 确认自己是否可以正常发送消息,对方是否可以正常接受消息
结果: 当前client可以正常发送消息

第二次握手

进行的操作: serve回应,接收连接请求将client的seq+1写入ack中,将ACK设置为1表示有效(确认收到消息)将SYN设置为1表示建立连接,然后重新计算seq回复client
目的: 确认自己是否可以正常发送消息,client是否可以正常接收消息
结果: client可以正常发送消息,server可以正常接收消息

第三次握手

进行的操作: client发送请求使用第一次的seq+1赋值到seq标志位,第二次的seq赋值到ack中
目的: 当client和server每个人都发送过一次消息接受过一次消息则说明连接条件可靠,可以建立连接
结果: 建立连接

四次挥手

在这里插入图片描述

个人总结:
TCP是全双工通信,不能单方面完全断开连接,所以需要确认双方都断开了才可以,而且挥手之前一直是server被动接收,server可能有需要返回的数据,所以在此阶段等client发送完毕返回去。

第一次挥手

进行的操作: client发送请求断开连接 发送FIN=1(表示我要关闭连接,这时候client就不在发送数据了)然后发送一个seq随机值
目的: 通知server我要关闭连接了
结果: client进入终止等待状态(正常情况下第二次挥手会立即返回,维持此状态时间很短)

第二次挥手

进行的操作: server收到了client的关闭连接请求,返回seq和ack
目的: 告诉client等我发送完我需要传给你的数据就关闭
结果: server进入关闭等待状态,并且开始发送数据给client(如果有的话)

第三次挥手

进行的操作: server发送完了全部数据,返回FIN=1关闭连接标识
目的: 告诉client我要返回给你的数据全部发完了可以关闭连接了。
结果: server进入最后确认阶段

第四次挥手

进行的操作: client发送关闭确认消息
目的: 中断连接
结果: client进入事件等待状态,服务器接到消息立刻关闭,然后等一段时间没有收到server消息client也关闭

额外知识

参数

linux /etc/sysctl.conf下

vim /etc/sysctl.conf#未收到客户端确认信息的连接请求的最大值
net.ipv4.tcp_max_syn_backlog=5000#timewait数量
net.ipv4.tcp_max_tw_buckets = 6000#改进tcp的拥塞控制机制
net.ipv4.tcp_sack =1#tcp窗口大于64K,必须开启此值
net.ipv4.tcp_window_scaling = 1#增加tcp最大缓冲区
net.ipv4.tcp_mem = 4096 67380 4194304
net.ipv4.tcp_rmem = 4096 67380 4194304
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_fin_timeout = 30#内核放弃建立连接之前发送synack/syn包的数量
net.ipv4.tcp_synack_retries = 3
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_reuse = 0#设置文件最大句柄数
fs.file-max = 102400#修改消息队列长度
kernel.msgmnb = 65536
kernel.msgmax = 65536#设置最大内存共享段大小bytes
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.wmem_max = 16777216
net.core.rmem_max = 16777216#设置同时发起的tcp连接数
net.core.somaxconn = 65535

服务器有大量的TIME_WAIT或者CLOSE_WAIT

  • close-wait状态是因为client已经发出释放连接信号了 已经没有数据传输过来,但是server端还有数据未发送完,这个时候就有close-wait状态了,如果有大量CLOSE_WAIT,说明server端没有正确关闭套接字,大概率是程序本身有bug,需要排查程序自身。
  • 如果有大量TIME_WAIT,说明此时可能有大量tcp请求,可以适当调整time_wait等待时间。

TCP心跳检测

  • TCP的程序往往都有个应用层的心跳检测机制,是为了预防建立好的连接突然客户端故障了,服务器不能一直等待下去,需要一个计时器和探测包来检测.

为什么要有TIME_WAIT等待2ms

  • 防止出现server没有收到最后一条消息的情况,这种情况下server会再次发送释放连接的消息,如果不等待直接关闭有可能server还在组后确认状态呢。

参考

图片复制百度图库
https://www.zhihu.com/question/271701044
https://www.jianshu.com/p/d3725391af59
https://blog.csdn.net/qq_38950316/article/details/81087809
https://www.cnblogs.com/jainszhang/p/10641728.html

猜你喜欢

转载自blog.csdn.net/zhaohan___/article/details/110088797
今日推荐