I'm new to networking and I want to write a simple, Client-side TCP/IP script; however, I encounter an issue when using select()
to receive the server's answer.
I want to use select because I need the timeout functionality. I am using select()
in a custom function with a non-zero timeout value, generating a DLL out of it, then calling the function in a client main()
.
Everything works as intended, except the timeout. Either I receive the message instantly (which is good), or the select()
function times out instantly (which is not). It seems to me like the timeout value is not taken into account at all.
Here is the code I am using. I included the function in which select()
is placed, as well as the client-side implementation.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <time.h>
#pragma comment(lib, "Ws2_32.lib")
int ReceiveClientMessage()
{
int iResult = -1;
FD_SET ReadSet;
int Socket_notifs = 0;
struct timeval timeout;
timeout.tv_sec = 20000000;
timeout.tv_usec = 0;
FD_ZERO(&ReadSet);
FD_SET(socket_Client, &ReadSet);
Socket_notifs = select(0, &ReadSet, NULL, NULL, &timeout);
if (Socket_notifs == SOCKET_ERROR)
{
printf("Select returned with error %d\n", WSAGetLastError());
return 1;
}
printf("Select successful\n");
if (Socket_notifs > 0)
{
int receiving_buffer_length = DEFAULT_BUFLEN;
char receiving_buffer[DEFAULT_BUFLEN] = "";
// Start receiving
iResult = recv(socket_Client, receiving_buffer, receiving_buffer_length, 0);
if (iResult > 0)
// Message received, display save yada yada
else
// Error receiving
}
else if (Socket_notifs == 0)
{
// Timeout
printf("Select timed out\n\n");
return 2;
}
else
{
// Other issue with select
printf("Unknown error with Select\n\n");
return 3;
}
return 0;
}
//----------------------------------------------------------------
// Client main()
string message, response;
while (true)
{
/* Part where we send a message, irrelevant here */
// Receive a message on client side
iResult = -1;
iResult = ReceiveClientMessage();
cout << iResult << endl;
if (iResult != 0)
// Error, clean up and break
else
// Display message
}
I tried to remove most irrelevant parts of my code, and only left the parts relevant to the select, timeout and receive implementation.
I have already tried setting various values for timeout.tv_sec
and timeout.tv_usec
(from 20 to 20000000), in case it wasn't a value in seconds or something, without results. Sometimes I send a message, and instantly see the "Select timed out" prompt (which, from my understanding, should not happen). Any idea on how to solve this (either by finding out why the timeout values are not taken into account, or by using another method that has a timeout functionality)?