说起TCP的三次握手,大多数小伙伴多少都听说过一些,因此本文不再赘述三次握手的详细流程,而是重点关注三次握手中半连接队列和全连接队列流程,以及二者队列满了时的处理机制,最后分析下常见的三次握手的问题,这些问题大都也是和半连接队列和全连接队列相关的。
TCP三次握手大致流程如下:
三次握手对应抓包如下:
上面说的TCP三次握手并没有提到半连接队列和全连接队列,其实三次握手流程中还涉及到半连接和全连接队列之间的流转动作,对应的流程如下:
如上图所示,这里有两个队列:syns queue(半连接队列);accept queue(全连接队列)。
半连接队列和全连接队列满时有以下3种场景:
tcp_abort_on_overflow
的指示执行,默认为0表示扔掉client发过来的ack(在server端认为连接还没建立起来),为1表示发送一个reset包给client。tcp_abort_on_overflow
指示来执行。半连接/全连接队列的大小到底是多少呢?
准确来说,全连接队列的大小取决于:min(backlog, somaxconn) . backlog是在socket创建的时候传入的,somaxconn是一个os级别的系统参数,也就是/proc/sys/net/core/somaxconn的大小。半连接队列的大小取决于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。不同版本的os会有些差异。
最后我们想一下,TCP为什么需要3次握手呢?
一句话总结就是:3次握手保证了连接的可靠性与效率。3次握手过程中,会交换各自的一些信息,比如窗口大小、初始报文序号等,如果只有2次握手,不能保证客户端一定能收到服务端的响应报文(SYN+ACK)。