lvxuzhou


私信TA

用户名:lvxuzhou

访问量:97341

签 名:

lvxuzhou

等  级
排  名 48
经  验 11191
参赛次数 0
文章发表 56
年  龄 0
在职情况 学生
学  校 西安
专  业

  自我简介:


一、环境:

    Ubuntu 18.04.1 LTS

二、头文件

    #include<sys/socket.h>

三、函数简介

    int listen(int sockfd,int backlog);

    sockfd参数指定被监听的socket。backlog参数提示内核监听队列的最大长度。监听队列的长度如果超过backlog,服务器将不受理新的客户连接,客户端也将收到ECONNREFUSED错误信息。在内核版本2.2之前的Linux中,backlog参数是指所有处于半连接状态(SYN_RCVD)和完全连接状态(ESTABLISHED)的socket的上限。但自内核版本2.2之后,它只表示处于完全连接状态的socket的上限,处于半连接状态的socket的上限则由/proc/sys/net/ipv4/tcp_max_syn_backlog内核参数定义。backlog参数的典型值是5。

    listen成功时返回0,失败则返回-1并设置errno。

四、网络状态图

微信图片_20210922232215.png

    测试代码:以研究backlog参数对listen系统调用的实际影响。

    #include <sys/socket.h>    
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdbool.h>
    #include <libgen.h>
    static bool stop = false;
    static void handle_term(int sig)
    {
        stop = true;
    }
    int main(int argc, char *argv[])
    {
        signal(SIGTERM, handle_term);
        if (argc <= 3)
        {
            printf("usage:%s ip_address port_number backlog\n", basename(argv[0]));
            return 1;
        }
        const char *ip = argv[1];
        int port = atoi(argv[2]);
        int backlog = atoi(argv[3]);
        int sock = socket(PF_INET, SOCK_STREAM, 0);
    
        assert(socket >= 0);
    
        /*创建一个IPv4 socket地址*/
        struct sockaddr_in address;
        bzero(&address, sizeof(address));
        address.sin_family = AF_INET;
        inet_pton(AF_INET, ip, &address.sin_addr);
        address.sin_port = htons(port);
        int ret = bind(sock, (struct sockaddr *)&address, sizeof(address));
        assert(ret != -1);
        ret = listen(sock, backlog);
        assert(ret != -1);
        /*循环等待连接,直到有SIGTERM信号将它中断*/
        while (!stop)
        {
            sleep(1);
        }
        /*关闭socket,见后文*/
        close(sock);
        return 0;
    }

五、测试流程:

1、./ser 192.168.244.154  12345 1

微信图片_20210922232215.png

ser是上面代码编译后的可执行程序,12345是端口号,1表示backlog

2、在服务器端执行 watch -n 1 "netstat -tnp | grep 12345" 如图:
微信图片_20210922232215.png

3、启动3个客户端程序 nc 192.168.244.154  12345 ,查看服务器网络链接状态

微信图片_20210922232215.png

因为backlog设置为1,所以服务端最多只能接受2个客户端链接,

微信图片_20210922232215.png

可以看到第三个客户端链接超时了。

总结:backlog表示完全连接状态(ESTABLISHED)的socket的上限+1


 

0.0分

1 人评分

看不懂代码?想转换其他语言的代码? 或者想问其他问题? 试试问问AI编程助手,随时响应你的问题:

编程语言转换

万能编程问答  

代码解释器

代码纠错

SQL生成与解释

  评论区