4

我通过 发送一个 UDP 数据包sendto,然后通过 .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);
4

3 回答 3

12

如何在 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
}
于 2015-02-12T18:07:39.103 回答
8

您可以使用pollorselect或类似的东西:

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 ...
}
于 2013-04-23T07:33:45.947 回答
3

我想知道如何为 recv 设置超时

setsockopt()使用SO_RCVTIMEO选项调用。

于 2013-04-23T10:36:53.900 回答