简体   繁体   English

如何在Linux C中取消阻止recv()或recvfrm()函数

[英]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. 如果该操作将阻止,则此调用返回EAGAINEWOULDBLOCK错误代码。

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.

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