简体   繁体   English

如何在 winsock 中使“发送”非阻塞

[英]How to make 'send' non-blocking in winsock

I am making a program which sends UDP packets to a server at a fixed interval, something like this:我正在制作一个程序,它以固定的时间间隔向服务器发送 UDP 数据包,如下所示:

while (!stop) {
    Sleep(fixedInterval);

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

However the periodicity cannot be guaranteed because send is a blocking call (eg, when fixedInterval is 20ms, and a call to send is > 20ms ).然而,不能保证周期性,因为send是一个阻塞调用(例如,当fixedInterval是 20ms 并且对send的调用大于 20ms 时)。 Do you know how I can turn the send into a non-blocking operation?你知道我怎样才能把send变成非阻塞操作吗?

You need to use a non-blocking socket.您需要使用非阻塞套接字。 The send/receive functions are the same functions for blocking or non-blocking operations, but you must set the socket itself to non-blocking.发送/接收函数与阻塞或非阻塞操作的函数相同,但您必须将套接字本身设置为非阻塞。

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

Also, be aware that working with non-blocking sockets is quite different.另外,请注意使用非阻塞套接字是完全不同的。 You'll need to make sure you handle WSAEWOULDBLOCK errors as success!您需要确保成功处理 WSAEWOULDBLOCK 错误! :) :)

So, using non-blocking sockets may help, but still will not guarantee an exact period.因此,使用非阻塞套接字可能会有所帮助,但仍不能保证确切的时间段。 You would be better to drive this from a timer, rather than this simple loop, so that any latency from calling send, even in non-blocking mode, will not affect the timing.您最好从计时器而不是这个简单的循环中驱动它,以便调用 send 的任何延迟,即使在非阻塞模式下,也不会影响计时。

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

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

My memory is fuzzy here since it's probably been 15 years since I've used UDP non-blocking.我的记忆在这里很模糊,因为我使用 UDP 非阻塞可能已经 15 年了。

However, there are some things of which you should be aware.但是,有些事情您应该注意。

  1. Send only smallish packets if you're going over a public network.如果您要通过公共网络,则仅发送较小的数据包。 The PATH MTU can trip you up if either the client or the server is not written to take care of incomplete packets.如果没有写入客户端或服务器来处理不完整的数据包,则 PATH MTU 可能会使您绊倒。

  2. Make sure you check that you have sent the number of bytes you think you have to send.确保检查您发送的字节数是否达到您认为必须发送的字节数。 It can get weird when you're expecting to see 300 bytes sent and the receiving end only gets 248. Both client side and server side have to be aware of this issue.当您期望看到 300 个字节发送而接收端只收到 248 个字节时,这可能会变得很奇怪。客户端和服务器端都必须注意这个问题。

  3. See here for some good advice from the Linux folks.请参阅此处从 Linux 人员那里获得一些好的建议。

  4. See here for the Unix Socket FAQ for UDP有关 UDP 的 Unix 套接字常见问题,请参见此处

  5. This is a good, general network programming FAQ and example page.是一个很好的通用网络编程常见问题解答和示例页面。

如何测量 Send 花费的时间,然后只是睡眠时间丢失了 20 毫秒?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM