设置从accept()返回的客户端套接字的sockopt

时间:2016-09-07 04:03:30

标签: c sockets setsockopt

我正在尝试为accept()函数返回的客户端套接字设置套接字选项。但它们没有正确设置。

我的目标是在特定的不活动时间后让客户超时。但服务器应该仍然能够接受其他客户端连接。

下面是我设置套接字选项的代码。你能告诉我什么是错的吗?

while ((new_sock_fd = accept(socket_fd, (struct sockaddr *) &cli_addr, &clilen)) > 0)
{
    if (new_sock_fd < 0)
        printf("Accept Error");
    else
    {
        struct timeval timeout;      
        timeout.tv_sec = 10;
        timeout.tv_usec = 0;
        if (setsockopt(new_sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
            error("setsockopt failed\n");
        if (setsockopt(new_sock_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
            error("setsockopt failed\n");
        pthread_create(&thread, NULL, client_handler, (void *) (intptr_t)new_sock_fd); //intptr_t is big enough to hold the integer prt
    }
}

1 个答案:

答案 0 :(得分:1)

  

我的目标是在特定时间之后将客户超时   闲置。 [...]你可以建议什么时候错了..?

我怀疑你错误地了解SO_RCVTIMEO和SO_SNDTIMEO的目的是什么。来自man page

  

SO_RCVTIMEO和SO_SNDTIMEO指定接收或发送超时   直到报告错误。参数是struct timeval。如果   这段时间的输入或输出功能块,以及数据   已发送或接收,该功能的返回值将是   转移的数据量;如果没有数据传输和   已达到超时,然后返回-1,并将errno设置为EAGAIN   或EWOULDBLOCK,或EINPROGRESS(用于连接(2))就像套接字一样   被指定为非阻塞。如果超时设置为零(   默认情况下,操作永远不会超时。

...但听起来你想要的是TCP连接会在一段时间后自动关闭,TCP连接上没有流量,这与强制调用send()或recv()在指定的时间后返回。

如果您正在寻找的是关闭空闲TCP连接的机制,您可以通过在套接字上发送或接收数据时记录当前时间来自行实现。在稍后的时间(例如,在发送()或recv()超时之后),您可以从当前时间减去您记录的最后一次流量。如果差值大于idle-timeout值,请自行调用socket上的close()。