40

我正在尝试在 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++;
}
4

2 回答 2

65

SO_RCVTIMEO选项需要一个struct timeval定义的 in sys/time.h,而不是像您传递给它的整数。具有timeval structas 秒字段和微秒字段。要将超时设置为 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");
}
于 2012-11-25T02:55:25.270 回答
4

我也有同样的问题。我尝试采用您建议的解决方案,使用timevalstruct. 但它似乎没有用。

我已经阅读了微软文档,时间应该是DWORD毫秒数,但还有另一件事要做,如果套接字是使用WSASocket函数创建的,那么dwFlags参数必须具有WSA_FLAG_OVERLAPPED设置超时才能起作用的属性适当地。否则超时永远不会生效。

于 2018-03-18T01:08:00.880 回答