Set timeout for winsock recvfrom

c, network-programming, networking, sockets

Solution

I looked into the select function and as laura said I should do and got it to work real easily! Thanks!

fd_set fds ;
int n ;
struct timeval tv ;

// Set up the file descriptor set.
FD_ZERO(&fds) ;
FD_SET(mHandle, &fds) ;

// Set up the struct timeval for the timeout.
tv.tv_sec = 10 ;
tv.tv_usec = 0 ;

// Wait until timeout or data received.
n = select ( mHandle, &fds, NULL, NULL, &tv ) ;
if ( n == 0)
{ 
  printf("Timeout..\n");
  return 0 ;
}
else if( n == -1 )
{
  printf("Error..\n");
  return 1;   
}

int length = sizeof(remoteAddr);

recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length); 

Problem

I'm trying to set up a blocking socket to timeout after 16 ms of trying to recvfrom() on a port. Platform is Windows. I've looked at tons of examples online and it seems really simple I just can't seem to get it to work. Any help would be appreciated! ``` #include <winsock2.h> #include <string> #pragma comment(lib, "ws2_32.lib") #define PORT_NUM 8001 int main(void) { std::string localIP; sockaddr_in localAddr; sockaddr_in remoteAddr; hostent* localhost; char buffer[1024]; WSADATA wsData; int result = WSAStartup(MAKEWORD(2,2), &wsData); // winsock version 2 localhost = gethostbyname(""); localIP = inet_ntoa(*(in_addr*)*localhost->h_addr_list); localAddr.sin_family = AF_INET; localAddr.sin_port = htons(PORT_NUM); // Set Port Number localAddr.sin_addr.s_addr = inet_addr(localIP.c_str()); // Set IP Address int mHandle = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0); if(mHandle == INVALID_SOCKET) return 1; if(bind(mHandle, (SOCKADDR*)&localAddr, sizeof(localAddr)) == SOCKET_ERROR) return 1; timeval tv; tv.tv_sec = 0; tv.tv_usec = 1600; // Set Timeout for recv call if(setsockopt(mHandle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char*>(&tv), sizeof(timeval))) return 1; int length = sizeof(remoteAddr); // <-- Blocks here forever recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length); return 0; } /* I've also tried passing the time like so: int ms = 16; if(setsockopt(mHandle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char*>(&ms), sizeof(int))) return 1; */ ```

Original source