[英]How to unblock recv() or recvfrm() function in linux C
I want to send a UDP packet to a camera from the PC when the PC resumes from sleep. 当PC从睡眠恢复时,我想从PC发送UDP数据包到摄像机。 Since it takes some time (unknown) to the network interface to become alive after the PC resumes, I keep sending packets to the camera in a loop.
由于PC恢复后需要一段时间(未知)才能使网络接口恢复活动,因此我一直循环将数据包发送到摄像机。 When the camera receives the packet, it sends an acknowledge signal to the PC.
相机收到数据包后,会向PC发送确认信号。 My problem is "for receiving the UDP packet from the camera (ack signal), I use recvfrm() function which blocks the loop. How do I unblock this function so that it exit the loop only when it receives acknowledge signal from the camera.
我的问题是“为了接收来自摄像机的UDP数据包(ack信号),我使用了阻止循环的recvfrm()函数。如何取消阻止此函数,以便仅当它从摄像机接收到确认信号时才退出循环。
Use MSG_DONTWAIT
flag passed to recvfrom
function. 使用传递给
recvfrom
函数的MSG_DONTWAIT
标志。 It enables non-blocking mode. 它启用非阻塞模式。 If the operation would block this call returns
EAGAIN
or EWOULDBLOCK
error code. 如果该操作将阻止,则此调用返回
EAGAIN
或EWOULDBLOCK
错误代码。
A more portable solution to maverik's answer (which is otherwise correct) would be to fcntl
the socket to O_NONBLOCK
. 较为简单的解决方案,maverik的回答(这是正确的,否则)将
fcntl
套接字O_NONBLOCK
。
MSG_DONTWAIT
, although available under Linux and BSD and most Unices is only standardized in SUSv4 for sending (why, I wouldn't know... but M. Kerrisk says so). MSG_DONTWAIT
,尽管在Linux和BSD下可用,并且大多数Unices仅在SUSv4中标准化用于发送(为什么,我不知道...但是M. Kerrisk这么说)。 One notable platform which doesn't support it is Winsock (at least it's not documented in MSDN). Winsock是一个不支持它的著名平台(至少在MSDN中没有记录)。
Alternatively, if you don't want to tamper with obscure flags and fcntl
, you could select
the descriptor for readiness (with a zero timeout, or even with a non-zero timeout to throttle the packets you send -- it's probably a good idea not to flood the network stack). 另外,如果您不想篡改晦涩的标志和
fcntl
,可以select
准备就绪的描述符(超时为零,甚至超时为非零,以限制发送的数据包,这可能是个好主意不要淹没网络堆栈)。 Keep sending until select
says something can be read. 继续发送,直到
select
表示可以读取某些内容为止。
最简单的方法(但不是最好的代码)是等待回复一段时间,即在调用recvfrom()之前使用select 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.