Linux中listen()系统调用的backlog参数分析(2)

接下来我们看如果连接队列满了的话,内核会如何处理。先写个测试程序,构造连接队列满的情况。测试程序说明如下:

1、服务器端地址为192.168.1.188,监听端口为80;客户端地址为192.168.1.192

2、服务器端在80端口建立一个监听套接字,listen()的backlog参数设置的是300,将sysctl_max_syn_backlog和sysctl_somaxconn系统配置都调整为4096,特别要注意的是服务器端一定不要调用accept()来接收连接,在建立起监听后,让进程睡眠等待。关键代码如下:

........
      if ((ret = listen(fd, 300)) < 0) {
                perror("listen");
                goto err_out;
        }


        /* wait connection */
        while (1) {
                sleep(3);
        }
        ........

3、客户端通过一个循环发起1000个连接请求,为了后面进一步的分析,在第401连接建立后打印输出其本地端口,并且发送了两次数据。关键代码如下:

......

ret = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
        if (ret < 0) {
            fprintf(stderr, "connect fail in %d times, reason: %s.\n", i + 1, strerror(errno));
            return -1;
        }

connections[i] = fd;
        fprintf(stderr, "Connection success, times: %d, connections: %d.\n", i + 1,
                check_connection_count(connections, i + 1));
        if (i == 400) {
            len = sizeof(sa);
            ret = getsockname(fd, (struct sockaddr *)&sa, &len);
            if (ret < 0) {
                fprintf(stderr, "getsockname fail, ret=%d.\n", ret);
                return -1;
            }
            fprintf(stderr, "connecton %d, local port: %u.\n", i,ntohs(sa.sin_port));
           
            str = "if i can write ,times 1";
            ret = write(fd, str, strlen(str));
            fprintf(stderr, "first writ in connection %d, ret = %d.\n", i, ret);

str = "if i can write ,times 2";
            ret = write(fd, str, strlen(str));
            fprintf(stderr, "second writ in connection %d, ret = %d.\n", i, ret);
        }
      .......

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/30c2be731595075c8993b6af16dcaabb.html