zoukankan      html  css  js  c++  java
  • tcp/ip协议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队列:此队列维护着那些已收到了clientSYN网络分组。并发出了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

    当client的第一个SYN到达的时候,TCP会在未完毕队列中添加一个新的记录然后回复给client三路握手中的第二个分节(服务端的SYN和针对client的ACK),这条记录会在未完毕队列中一直存在,直到三路握手中的最后一个分节到达,或者直到超时(Berkeley时间将这个超时定义为75秒)。

    假设当clientSYN到达的时候队列已满,TCP将会忽略兴许到达的SYN,可是不会给client发送RST信息,由于此时同意client重传SYN分节,假设返回错误信息。那么client将无法分清究竟是服务端相应port上没有相应应用程序还是服务端相应port上队列已满这两种情况。

    对于应用server来说。假设ACCEPT队列中有已经建立好的TCP连接,却没有及时把它取出来。这样,一旦导致两个队列满之后。就会使client不能再建立新连接,引发严重问题。

    所以,一些server会使用一个主进程来做accept获取连接,而让其它工作进程来进行其它数据处理等工作。这样能够防止不能及时的去accept获取连接。

  • 相关阅读:
    Codeforces Round 546 (Div. 2)
    Codeforces Round 545 (Div. 2)
    Codeforces Round 544(Div. 3)
    牛客小白月赛12
    Codeforces Round 261(Div. 2)
    Codeforces Round 260(Div. 2)
    Codeforces Round 259(Div. 2)
    Codeforces Round 258(Div. 2)
    Codeforces Round 257 (Div. 2)
    《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的分布
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5101523.html
Copyright © 2011-2022 走看看