5.4监听socket

监听socket

socket被命名之后,还不能马上接受客户连接,我们需要使用如下系统调用来创建一个监听队列以存放待处理的客户连接:

#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/s/netipv4/tcp_ max_syn_backlog 内核参数定义。backlog参数的典型值是5。

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

下面我们编写一个服务器程序,如代码清单5-3所示,以研究backlog参数对listen系统调用的实际影响。

//testlisten->main.cpp
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.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]; //监听ip地址
    int port = atoi( argv[2] ); //atoi()字符串转为int
    int backlog = atoi( argv[3] );

    //创建socket
    int sock = socket( PF_INET, SOCK_STREAM, 0 ); //IPv4 TCP
    assert( sock >= 0 );

    //创建一个IPv4 socket地址
    struct sockaddr_in address;
    bzero( &address, sizeof( address ) ); //将结构体清零
    address.sin_family = AF_INET; //TCP/IPv4协议族
    inet_pton( AF_INET, ip, &address.sin_addr ); //ip地址转换函数,二进制网络字节序
    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;
}

在linux机器上执行cmake ..make后,执行./testlisten 172.16.160.240 12345 5(本机ip地址)。
在这里插入图片描述
在这里插入图片描述
然后再开一个新的终端输入telnet 172.16.160.240 12345来连接该服务器程序。同时每使用telnet命令建立一个连接,就执行一次netstat命令来查看服务器上连接的状态。
在这里插入图片描述
然后再另外一个机器上(注意关闭防火墙)或者还是在本机上开一个终端输入netstat -nt | grep 12345,显示这一时刻listen监听队列的内容。
在这里插入图片描述
可见,在监听队列中,处于ESTABLISHED状态的连接只有2个(backlog 值加1)。我们改变服务器程序的第3个参数并重新运行之,能发现同样的规律,即完整连接最多有(backlog+1) 个。在不同的系统上,运行结果会有些差别,不过监听队列中完整连接的上限通常比backlog值略大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光开朗男孩

你的鼓励是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值