C语言 UDP 套接字设置超时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13547721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:33:06  来源:igfitidea点击:

UDP Socket Set Timeout

csocketsudp

提问by rharrison33

I am trying to set a 100ms timeout on a UDP Socket. I am using C. I have posted relavent pieces of my code below. I am not sure why this is not timing out, but just hangs when it doesn't receive a segment. Does this only work on sockets that are not bound using the bind() method?

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

回答by Neal

The SO_RCVTIMEOoption expects a struct timevaldefined in sys/time.h, not an integer like you're passing to it. The timeval structhas as field for seconds and a field for microseconds. To set the timeout to 100ms, the following should do the trick:

SO_RCVTIMEO选项需要在 中struct timeval定义sys/time.h,而不是像您传递给它的整数。在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");
}

回答by user9510357

I have the same problem. I tried to adopt the solution you suggested, using the timevalstruct. But it did not seem to work.

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

I have read on the Microsoft documentation and the time should be a DWORDwith the number of milliseconds, but there is also another thing to do, If the socket is created using the WSASocketfunction, then the dwFlagsparameter must have the WSA_FLAG_OVERLAPPEDattribute set for the timeout to function properly. Otherwise the timeout never takes effect.

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