UDP 套接字设置超时
Posted
技术标签:
【中文标题】UDP 套接字设置超时【英文标题】:UDP Socket Set Timeout 【发布时间】:2012-11-12 22:03:05 【问题描述】:我正在尝试在 UDP 套接字上设置 100 毫秒的超时。我正在使用 C。我在下面发布了我的相关代码。我不确定为什么这没有超时,而是在没有收到段时挂起。这是否仅适用于未使用 bind() 方法绑定的套接字?
#define TIMEOUT_MS 100 /* Seconds between retransmits */
if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
//set timer for recv_socket
static int timeout = TIMEOUT_MS;
setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
if(recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0,
(struct sockaddr *) &servAddr2, &fromSize) < 0)
//timeout reached
printf("Timout reached. Resending segment %d\n", seq_num);
num_timeouts++;
【问题讨论】:
您似乎没有检查来自setsockopt
的返回值以查看它是否返回错误。它可能是。 SO_RCVTIMEO
在 Linux 和 MacOS 上均记录为采用 struct timeval
,但您传递的是 int
。尝试通过 struct timeval
代替。另外,为什么要将&timeout
转换为char *
?这根本不是char *
。
【参考方案1】:
我也有同样的问题。我尝试采用您建议的解决方案,使用 timeval
结构。但它似乎没有用。
我已经阅读了微软的文档,时间应该是DWORD
和毫秒数,但还有另一件事要做,如果套接字是使用WSASocket
函数创建的,那么@987654324 @ 参数必须设置WSA_FLAG_OVERLAPPED
属性才能使超时正常工作。
否则超时永远不会生效。
【讨论】:
接受的答案以 POSIX 套接字为目标。 Windows 提供了自己的套接字 API,因此接受的答案不适用于 Windows。【参考方案2】:SO_RCVTIMEO
选项需要在sys/time.h
中定义的struct timeval
,而不是像您传递给它的整数。 timeval struct
具有秒字段和微秒字段。要将超时设置为 100 毫秒,以下应该可以解决问题:
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
if (setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0)
perror("Error");
【讨论】:
以上是关于UDP 套接字设置超时的主要内容,如果未能解决你的问题,请参考以下文章