Reputation: 1282
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?
#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++;
}
Upvotes: 43
Views: 102270
Reputation: 51
I have the same problem. I tried to adopt the solution you suggested, using the timeval
struct. But it did not seem to work.
I have read on the Microsoft documentation and the time should be a DWORD
with the number of milliseconds, but there is also another thing to do, If the socket is created using the WSASocket
function, then the dwFlags
parameter must have the WSA_FLAG_OVERLAPPED
attribute set for the timeout to function properly.
Otherwise the timeout never takes effect.
Upvotes: 5
Reputation: 6992
The SO_RCVTIMEO
option expects a struct timeval
defined in sys/time.h
, not an integer like you're passing to it. The timeval struct
has as field for seconds and a field for microseconds. To set the timeout to 100ms, the following should do the trick:
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");
}
Upvotes: 74