设置UDP套接字的recv fcn超时

设置UDP套接字的recv fcn超时,c,linux,sockets,udp,posix,C,Linux,Sockets,Udp,Posix,我通过sendto发送UDP数据包,然后通过recv接收应答。如果recv没有收到应答,则程序不会继续。但是,udp数据包可能丢失,或者由于某种原因,数据包可能无法传递,因此程序卡在recv行上。我想知道,如果没有数据包到达,例如一分钟,怎么可能为recv设置超时,然后跳过该行并继续编码 我没有粘贴完整的代码,因为它是一个通用的udp代码,我的问题与唯一的recv相关。最后,开发环境是linux unsigned long buf[maxlen]; struct protoent *proto

我通过
sendto
发送UDP数据包,然后通过
recv
接收应答。如果
recv
没有收到应答,则程序不会继续。但是,udp数据包可能丢失,或者由于某种原因,数据包可能无法传递,因此程序卡在
recv
行上。我想知道,如果没有数据包到达,例如一分钟,怎么可能为
recv
设置超时,然后跳过该行并继续编码

我没有粘贴完整的代码,因为它是一个通用的
udp
代码,我的问题与唯一的
recv
相关。最后,开发环境是linux

unsigned long  buf[maxlen];
struct protoent *proto;     //
struct sockaddr_in server_addr;
int s;  // socket
memset( &server_addr, 0, sizeof( server_addr ));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr = inet_addr(hostname);
sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));

recv(s,buf,sizeof(buf),0);

您可以使用
轮询
选择
或类似方法:

struct pollfd fd;
int res;

fd.fd = s;
fd.events = POLLIN;
res = poll(&fd, 1, 1000); // 1000 ms timeout

if (res == 0)
{
    // timeout
}
else if (res == -1)
{
    // error
}
else
{
    // implies (fd.revents & POLLIN) != 0
    recv(s,buf,sizeof(buf),0); // we can read ...
}
我想知道如何为recv设置超时


使用
SO\RCVTIMEO
选项调用
setsockopt()

如何在Linux中设置UDP套接字超时:

#include <sys/time.h>

struct timeval timeout={2,0}; //set timeout for 2 seconds

/* set receive UDP message timeout */

setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval));

/* Receive UDP message */
int recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &slen);
if (recvlen >= 0) {
    //Message Received
}
else{
    //Message Receive Timeout or other error
}
#包括
结构timeval timeout={2,0}//将超时设置为2秒
/*设置接收UDP消息超时*/
setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,(char*)和timeout,sizeof(struct timeval));
/*接收UDP消息*/
int recvlen=recvfrom(fd,buf,BUFSIZE,0,(struct sockaddr*)和remaddr,&slen);
如果(recvlen>=0){
//收到的信息
}
否则{
//消息接收超时或其他错误
}

使插座不阻塞?或使用,例如用于投票?当然,
recv
(这是一个特定于Linux的扩展)有
MSG_DONTWAIT
标志。返回值-1可能表示除超时之外的许多事情。必须检查
EAGAIN/ewoodblock
errno
值,以确定是否发生超时。