TCP三次握手和backlog参数

来源:互联网 发布:嵌入式linux驱动开发 编辑:程序博客网 时间:2024/04/30 02:04

1 三次握手


TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP窗口大小信息




为什么非要三次握手呢?谢希仁的《计算机网络》中这样说:为了防止已失效的连接请求报文段突然又传送到了服务端因而产生错误。


已失效的连接请求报文段的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段,但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样server的很多资源就白白浪费掉了。采用三次握手的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。这就有效的防止了服务器端的一直等待而浪费资源。



2 backlog


backlog这个参数值和三次握手的概念有着密切关联。backlog队列大小 = 未完成三次握手队列 +  已经完成三次握手队列。


未完成三次握手队列:服务器处于listen状态时,收到客户端syn报文(connect)时放入未完成队列中。


已完成三次握手队列:三次握手的第二个状态即服务器syn+ack响应client后,此时第三个状态ack报文到达前(客户端对服务器syn的ack)一直保留在未完成连接队列中。若三次握手完成,该条目将从未完成连接队列搬到已完成连接队列尾部当server调用accept时,从已完成三次握手队列中的头部取出一个socket连接给进程。


backlog参数设置既可在linux内核参数设置(修改文件/etc/sysctl相关参数),也可在socket系统调用listen函数时设置(第二个参数)。这二者区别是前者为全局性的,影响所有socket,后者为局部性的,影响当前socket。

backlog设置过小可能会出现以下情况:server的accpet速度跟不上,导致A、B队列满了,导致新的客户端无法连接。


参考地址:

http://www.jellythink.com/archives/705

http://www.2cto.com/net/201307/224634.html


1 0
原创粉丝点击