【问题标题】:UDP Socket Set TimeoutUDP 套接字设置超时
【发布时间】: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 代替。另外,为什么要将&amp;timeout 转换为char *?这根本不是char *

标签: c sockets udp


【解决方案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");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 2022-11-05
    • 2010-10-15
    • 2011-03-04
    • 1970-01-01
    相关资源
    最近更新 更多