6

我正在制作一个程序,它以固定的时间间隔将 UDP 数据包发送到服务器,如下所示:

while (!stop) {
    Sleep(fixedInterval);

    send(sock, pkt, payloadSize, flags);
 }

send然而,由于是阻塞调用(例如,whenfixedInterval是 20ms,而调用send是 > 20ms ) ,因此无法保证周期性。你知道我怎样才能把它send变成一个非阻塞操作吗?

4

4 回答 4

13

您需要使用非阻塞套接字。发送/接收函数与阻塞或非阻塞操作的函数相同,但您必须将套接字本身设置为非阻塞。

u_long mode = 1;  // 1 to enable non-blocking socket
ioctlsocket(sock, FIONBIO, &mode);

另外,请注意,使用非阻塞套接字是完全不同的。您需要确保成功处理 WSAEWOULDBLOCK 错误!:)

因此,使用非阻塞套接字可能会有所帮助,但仍不能保证准确的时间。您最好从计时器驱动它,而不是这个简单的循环,这样调用发送的任何延迟,即使在非阻塞模式下,也不会影响时间。

于 2013-06-21T03:57:41.723 回答
3

API ioctlsocket 可以做到。你可以如下使用它。但是你为什么不在winsock中使用I/O模型呢?

ioctlsocket(hsock,FIOBIO,(unsigned long *)&ul);

于 2013-06-21T03:36:22.577 回答
0

我的记忆在这里很模糊,因为我使用 UDP 非阻塞可能已经有 15 年了。

但是,您应该注意一些事项。

  1. 如果您要通过公共网络,请仅发送较小的数据包。如果没有编写客户端或服务器来处理不完整的数据包,PATH MTU 可能会让您感到困惑。

  2. 确保检查您是否已发送您认为必须发送的字节数。当您期望看到发送 300 个字节而接收端只收到 248 个字节时,它会变得很奇怪。客户端和服务器端都必须意识到这个问题。

  3. 请参阅此处以获取 Linux 人员的一些好的建议。

  4. 有关UDP 的 Unix 套接字常见问题解答,请参见此处

  5. 是一个很好的通用网络编程常见问题解答和示例页面。

于 2013-06-21T05:27:54.963 回答
-1

如何测量发送所花费的时间,然后只是休眠丢失的时间长达 20 毫秒?

于 2013-06-21T13:02:04.880 回答