TCP报文格式
URG紧急指针是否有效。为1,表示某一位需要被优先处理ACK确认号是否有效,一般置为1。PSH提示接收端应用程序立即从TCP缓冲区把数据读走。RST对方要求重新建立连接,复位。SYN请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1FIN 希望断开连接。三次握手
个人总结:
三次握手是为了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 4194304net.ipv4.tcp_rmem = 4096 67380 4194304net.ipv4.tcp_timestamps = 0net.ipv4.tcp_fin_timeout = 30#内核放弃建立连接之前发送synack/syn包的数量net.ipv4.tcp_synack_retries = 3net.ipv4.tcp_syn_retries = 1net.ipv4.tcp_tw_reuse = 0#设置文件最大句柄数fs.file-max = 102400#修改消息队列长度kernel.msgmnb = 65536kernel.msgmax = 65536#设置最大内存共享段大小byteskernel.shmmax = 68719476736kernel.shmall = 4294967296net.core.wmem_default = 8388608net.core.rmem_default = 8388608net.core.wmem_max = 16777216net.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还在组后确认状态呢。参考
图片复制百度图库
/question/271701044
/p/d3725391af59
/qq_38950316/article/details/81087809
/jainszhang/p/10641728.html