1.tcp三次握手
上图就是三次握手的过程,tcp协议栈其实就是状态机,握手的状态从SYN_SEND -> SYN_RECV -> ESTABLISH
详细过程主要分为以下三步:
1.client调用connect函数发起通信,开始第一次握手(SYN), client进入SYN_SEND状态
2.server监听到有socket连接,发送第二次握手(SYN+ACK),随后将连接置入操作系统的半连接队列,server进入SYN_RECV状态
3.client收到服务端响应后,client就进入ESTABLISH状态,并发送第三次握手(ACK)至server,服务端也进入ESTABLISH状态,并将连接置入操作系统的全连接队列,之后accept函数才结束阻塞从内核态返回用户态
问题1:为什么tcp需要握手,握手次数为什么是三次,而不是两次四次
tcp握手是为了交换syn号,syn是实现tcp确认应答机制的基础
三次握手是保证连接有效建立的最佳次数,如果是两次握手,可能会导致client未收到server的ack导致server端建立起大量无效连接,
如果三次握手都没有建立起连接,四次握手仍然无法保证,不可能无限递归,所以三次握手是最佳选择
2.tcp四次挥手
以上就是四次挥手过程
问题2:为什么tcp握手是三次,挥手要四次
其实握手本质也是四次,只是握手过程中没有数据传输,所以第二次和第三次合并在一起了
挥手的时候,server端可能还有数据发送到client, 等待serve端数据传输完毕,才会主动关闭,所以需要四次
问题3: 为什么要有TIME_WAIT等待2ms
1.防止第四个ack丢失,server再次发送fin能得到正确的响应
2.尽量让此次连接的所有报文都得到处理,防止两端在2ms内重新建立连接有脏数据
问题4:服务器有大量的TIME_WAIT或者CLOSE_WAIT大致什么原因,怎么处理
如果有大量TIME_WAIT,说明此时可能有大量tcp请求,可以适当调整time_wait等待时间
如果有大量CLOSE_WAIT,说明server端没有正确关闭套接字,大概率是程序本身有bug,需要排查程序自身
3.tcp参数调优
握手阶段:
1.调整系统半连接队列大小
2.调整系统全连接队列大小
3.开启系统syn_cookies(可越过三次握手过程直接建立连接)
4.调整syn重传次数
5.调整ack重传次数
数据传输阶段:
1.调整滑动窗口大小
2.调整发送缓冲区大小
3.调整接受缓冲区大小
挥手阶段:
1.调整TIME_WAIT等待时间
2.调整FIN_WAIT2等待时间
3.调整CLOSE_WAIT2等待时间
4.调整FIN重传次数
5.调整孤儿连接个数(孤儿连接就是处于FIN_WAIT1到TIME_WAIT的client连接或者处于CLOSE_WAIT的server连接)
以上参数大都在 /proc/sys/net/ipv4/下,也可以通过sysctl -a |grep tcp查看
参考链接