• listen()函数中backlog参数分析


    实例分析1

    将服务器端的listen函数backlog设置为2,用20个客户端与服务器建立连接,查看连接的建立情况。

    服务器代码:

    #include <stdio.h>  
    #include<unistd.h>  
    #include<sys/types.h>       /* basic system data types */  
    #include<sys/socket.h>      /* basic socket definitions */  
    #include<netinet/in.h>      /* sockaddr_in{} and other Internet defns */  
    #include<arpa/inet.h>       /* inet(3) functions */  
    #include<sys/epoll.h>       /* epoll function */  
    #include<fcntl.h>  
    #include<stdlib.h>  
    #include<errno.h>  
    #include<stdio.h>  
    #include<string.h>  
      
      
    int main(int argc,char*argv[])  
    {  
        int listenfd,connfd;  
        struct sockaddr_in cliaddr,servaddr;  
        int queuelen=5;  
      
        if(argc!=2){  
            puts("usage# ./aworker listenqueuelen");  
            exit(0);  
        }     
        queuelen=atoi(argv[1]);  
      
        listenfd = socket(AF_INET,SOCK_STREAM,0);  
      
        bzero(&servaddr,sizeof(servaddr));  
        servaddr.sin_family = AF_INET;  
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  
        servaddr.sin_port = htons(2989);  
          
        bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));  
          
        listen(listenfd,queuelen);  
        sleep(60); //将这个注释,会出现另一种情况哟~~    
        while(1)  
        {  
            connfd = accept(listenfd,NULL,0);  
            if(connfd == -1)  
            {  
                perror("accept error");  
                continue;  
            }  
            puts("new connection...");  
        }  
        return 0;  
    }  

    client代码

    #include "client.h"  
      
    //void cli_hander(int sockfd,)  
      
    int main()  
    {  
        int sockfd;  
        int rc;   
        int cpid;  
        struct sockaddr_in servaddr;  
          
        bzero(&servaddr,sizeof(servaddr));  
        servaddr.sin_family = AF_INET;  
        inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);  
        servaddr.sin_port = htons(2989);  
          
        for(int i=0;i<20;i++)  
        {     
            cpid = fork();  
            if(cpid == 0)  
            {     
                sockfd = socket(AF_INET,SOCK_STREAM,0);  
                rc = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));  
                if(rc == -1)   
                {     
                    perror("connect error");  
                    exit(0);  
                }     
                printf("pid#%d connected...
    ",getpid());  
                sleep(3);  
                close(sockfd);  
                exit(0);  
            }     
        }     
      
        while(1)  
        {     
            cpid = wait(NULL);  
            if(cpid==-1){  
                perror("end of wait");  
                break;  
            }  
            printf("pid#%d exit...
    ",cpid);  
        }  
        return 0;  
    }  

    实验结果

    服务器端显示:

    root@cloud2:~/slp/NetWrokProgram/server# ./aworker 2  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection... 

    客户端显示:

    root@cloud2:~/slp/NetWrokProgram/client# ./a.out   
    pid#16697 connected...  
    pid#16699 connected...  
    pid#16698 connected...  
    pid#16697 exit...  
    pid#16699 exit...  
    pid#16698 exit...  
    pid#16700 connected...  
    pid#16701 connected...  
    pid#16700 exit...  
    pid#16701 exit...  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    connect error: Connection timed out  
    pid#16702 exit...  
    pid#16703 exit...  
    pid#16704 exit...  
    pid#16705 exit...  
    pid#16706 exit...  
    pid#16707 exit...  
    pid#16708 exit...  
    pid#16709 exit...  
    pid#16710 exit...  
    pid#16711 exit...  
    pid#16712 exit...  
    pid#16713 exit...  
    pid#16714 exit...  
    pid#16715 exit...  
    pid#16716 exit...  
    end of wait: No child processes  

    结果分析:

    同时建立连接的客户端进程共有20个,可是只有5个完成了连接的建立,其他15个没有成功。有趣的是,建立的5个链接中有3个是马上建立的,2个是过了一段时间后后来才建立的。

    实例分析2

    将server端的代码中的sleep(60)注释,即服务端listen即开始进入while循环中的accept阻塞:
    ...  
    listen(listenfd,queuelen);  
    sleep(60); //将这个注释,会出现另一种情况哟~~    
    while(1)  
    {  
        connfd = accept(listenfd,NULL,0);  
        ....  

    同样的运行服务端结果如下:

    root@cloud2:~/slp/NetWrokProgram/server# ./aworker 2  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  
    new connection...  

    客户端

    root@cloud2:~/slp/NetWrokProgram/client# ./a.out   
    pid#16736 connected...  
    pid#16737 connected...  
    pid#16738 connected...  
    pid#16739 connected...  
    pid#16740 connected...  
    pid#16741 connected...  
    pid#16742 connected...  
    pid#16743 connected...  
    pid#16744 connected...  
    pid#16745 connected...  
    pid#16746 connected...  
    pid#16747 connected...  
    pid#16748 connected...  
    pid#16749 connected...  
    pid#16750 connected...  
    pid#16751 connected...  
    pid#16752 connected...  
    pid#16753 connected...  
    pid#16755 connected...  
    pid#16754 connected...  
    pid#16736 exit...  
    pid#16737 exit...  
    pid#16738 exit...  
    pid#16739 exit...  
    pid#16740 exit...  
    pid#16741 exit...  
    pid#16742 exit...  
    pid#16743 exit...  
    pid#16744 exit...  
    pid#16745 exit...  
    pid#16746 exit...  
    pid#16747 exit...  
    pid#16748 exit...  
    pid#16749 exit...  
    pid#16750 exit...  
    pid#16751 exit...  
    pid#16752 exit...  
    pid#16753 exit...  
    pid#16755 exit...  
    pid#16754 exit...  
    end of wait: No child processes  
    结果分析:
    由于每个连接在建立之后,已完成队列中的连接马上就被accept给读取了,所以已完成和未完成队列中的连接数之和根本不可能超过backlog限定的个数。

    转自:http://blog.csdn.net/ordeder/article/details/21551567

  • 相关阅读:
    laravel 控制器方法里存get值 和 blade 模板获得闪存值的方法
    获取对象中的值的方法
    python3 语法小结
    集合一些方法陷阱
    文件的读写操作
    字符编码
    数字,字符串,列表,元祖,字典,集合类型内置方法
    if判断,while循环,for循环
    交互,格式化输出,运算符,解压缩!
    python基础知识
  • 原文地址:https://www.cnblogs.com/yorkyang/p/7808302.html
Copyright © 2020-2023  润新知