【问题标题】:Setting sockopt for client socket returned from accept()为从 accept() 返回的客户端套接字设置 sockopt
【发布时间】:2016-09-07 12:38:13
【问题描述】:

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

【问题讨论】:

  • 你怎么知道没有设置选项? setsockopt() 是否因错误而失败? getsocktop() 是否返回您不期望的值?套接字的行为是否与预期不同?如果是这样,怎么做?这段代码在什么平台上运行?在大多数平台上 SO_RCVTIMEOSO_SENDTIMEO 确实将 timeval 结构作为输入。但在 Windows 上,他们使用DWORD
  • 另外,你的Accept Error 消息永远不会被报告,因为你的循环只有在new_socket_fd &gt; 0 时才进入循环体。如果你想对accept() 进行错误处理,你应该把它移到循环中。

标签: c sockets setsockopt


【解决方案1】:

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

我怀疑问题在于您误解了 SO_RCVTIMEO 和 SO_SNDTIMEO 的用途。来自man page

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()。

【讨论】:

  • 或者,只需使用select()epoll() 来实现超时。将套接字置于非阻塞模式,然后 1) 在读取之前,用超时轮询可读性; 2) 如果发送失败并出现 `EAGAIN` 或 EWOULDBLOCK,则使用超时轮询可写性。如果任一操作超时,请关闭连接。
猜你喜欢
  • 2012-08-07
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 2016-03-18
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
相关资源
最近更新 更多