0

我正在尝试为从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
    }
}
4

1 回答 1

1

我的目标是在特定时间不活动后让客户超时。[...] 你能建议什么时候出错..?

我怀疑问题在于您误解了 SO_RCVTIMEO 和 SO_SNDTIMEO 的意图。从手册页

SO_RCVTIMEO 和 SO_SNDTIMEO 指定接收或发送超时,直到报告错误。参数是 struct timeval。如果输入或输出函数在这段时间内阻塞,并且数据已经发送或接收,则该函数的返回值将是传输的数据量;如果没有数据被传输并且已经达到超时,则返回 -1 并将 errno 设置为 EAGAIN 或 EWOULDBLOCK 或 EINPROGRESS(对于 connect(2)),就像将套接字指定为非阻塞一样。如果超时设置为零(默认值),则操作将永远不会超时。

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

如果您正在寻找一种关闭空闲 TCP 连接的机制,您可以通过在套接字上发送或接收数据时记录当前时间来自己实现它。稍后(例如在 send() 或 recv() 超时后),您可以从当前时间中减去您记录的 last-traffic-seen-at-time;如果差值大于您的空闲超时值,请自行在套接字上调用 close()。

于 2016-09-07T04:38:03.097 回答