【问题标题】:C++ recvfrom timeoutC++ recvfrom 超时
【发布时间】:2016-10-03 21:42:39
【问题描述】:

我需要实现以下行为:当服务器启动时,它应该使用广播检查现有服务器。然后它等待答案。

但是,如何设置等待的超时时间?

int optval = 1;
char buff[BUFF_SIZE];
SOCKADDR_IN addr;
int length = sizeof(addr);

if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(optval)) == SOCKET_ERROR) throw(errors::SETSOCKOPT);

addr->sin_family = AF_INET;
addr->sin_port = htons(this->serverPort);
addr->sin_addr.s_addr = INADDR_ANY;
sendto(s, this->serverName.c_str(), this->serverName.length() + 1, NULL, (SOCKADDR*)&addr, sizeof(addr));

memset(&addr, NULL, sizeof(addr));

recvfrom(s, buff, BUFF_SIZE, NULL, (SOCKADDR*)&addr, &length);

【问题讨论】:

  • 可以使用select(2),也可以设置成非阻塞使用epoll (2)

标签: c++ sockets recvfrom


【解决方案1】:

使用setsockopt()SO_RCVTIMEO 设置读取超时,并处理触发超时时发生的EAGAIN/EWOULDBLOCK

【讨论】:

  • SO_RCVTIMEO 仅适用于 recv() ,或者不?这告诉这里msdn.microsoft.com/en-us/library/windows/desktop/…
  • 它适用于任何recv() 系列方法,也适用于read(),Winsock 系统除外。
  • @user207421 我们如何“处理”EAGAIN/EWOULDBLOCK,因为我设置了超时但我的recvfrom 似乎慢得离谱
【解决方案2】:

常见的方法是使用select()poll() 来等待一组文件描述符上的事件。这些函数还允许您指定超时。在您的情况下,在 recvfrom() 调用之前添加以下内容:

struct pollfd pfd = {.fd = s, .events = POLLIN};
poll(&pfd, 1, 1000);

这将等待 1000 毫秒。这将在数​​据包到达套接字s 时退出,或在 1 秒后退出,以先到者为准。你可以查看poll()的返回值,看看是不是因为发包还是因为超时而返回。

【讨论】:

  • 正确的想法,不幸的是,使用指定的初始化列表,您会遇到 C 和 C++ 之间的语法差异之一。
  • @user4581301:它在 C99 和 C++11 中都有效。
  • 有人谈论将其滑入 C++14,但在 C++17 草案中,我仍然没有在 [dcl.init.aggr] 中看到它。 GCC 似乎将其作为扩展提供。
  • 虽然看起来有些措辞已更改为明确说明 revents 如果您 struct pollfd pfd = {s, POLLIN}; 会发生什么。读起来好像它被视为 struct pollfd pfd = {s, POLLIN, {}}; 应该给出 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
相关资源
最近更新 更多