tcpip协议listen函数中backlog参数的含义
listen函数的定义如下所⽰:
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr * restrict addr, socklen_t *restrict len);
返回值:若成功则返回⽂件(套接字)描述符,若出错则返回-1
int listen(int sockfd, int backlog);返回值:若成功则返回0;若出错则返回-1
之前看书的时候对listen函数的参数backlog不是很理解,今天看到⼀篇很不错的⽂章⾥⾯刚好有对这个的讲解,所以现在记录下⾃⼰的理解。
对于每⼀个listen socket,内核都会为维护两个队列:
SYN队列:此队列维护着那些已收到了客户端SYN⽹络分组,并发出了SYN/ACK⽹络分组,等待完成三路握⼿的连接,socket的状态是SYN_RCVD;
ACCEPT队列:此队列包含了那些已经完成三路握⼿的连接,socket的状态是ESTABLISHED。
backlog参数历史上被定义为上⾯两个队列的⼤⼩之和,⽽Berkely实现中的backlog值为上⾯两队列之和再乘以1.5。
调⽤accept函数正确返回之后,就表⽰TCP三次握⼿已完成,SYN队列中相应的分组会被加到ACCEPT队列中。
#include <sys/socket.h>
int accept( int sockfd, struct sockaddr * restrict addr, socklen_t *restrict len);
返回值:若成功则返回⽂件(套接字)描述符,若出错则返回-1
当客户端的第⼀个SYN到达的时候,TCP会在未完成队列中增加⼀个新的记录然后回复给客户端三路握⼿中的第⼆个分节(服务端的SYN和针对客户端的ACK),这条记录会在未完成队列中⼀直存在,直到三路握⼿中的最后⼀个分节到达,或者直到超时(Berkeley时间将这个超时定义为75秒)。
如果当客户端SYN到达的时候队列已满,TCP将会忽略后续到达的SYN,但是不会给客户端发送RST信息,因为此时允许客户端重传SYN 分节,如果返回错误信息,那么客户端将⽆法分清到底是服务端对应端⼝上没有相应应⽤程序还是服务端对应端⼝上队列已满这两种情况。
tcpip协议pdf对于应⽤服务器来说,如果ACCEPT队列中有已经建⽴好的TCP连接,却没有及时把它取出来,这样,⼀旦导致两个队列满之后,就会使客户端不能再建⽴新连接,引发严重问题。所以,⼀些服务器会使⽤⼀个主进程来做accept获取连接,⽽让其他⼯作进程来进⾏其他数据处理等⼯作,这样可以防⽌不能及时的去accept获取连接。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论