Advertisement

Problems with select() and timeout value

Started by December 04, 2003 12:06 PM
3 comments, last by Trond A 21 years, 1 month ago
The following code is from my client I''m trying to make. I''m having problems using the select() function. I have a timeout value set as you can see in the top of the constructor. However, I can''t seem to register any incoming data with the select() if I pass it my timeval value. I can register incoming data if I pass it 0, as in select(...., 0); That works, but the point is kind of gone then, since the select() function blocks if I pass it 0 instead of a timevalue... Excuse the code, I''ve made it pretty ugly with my testing and trying to find the error...

class ClsWSClient
{
private:

	int			returnmsg;
	WSADATA		wsadata;
	SOCKET		sock_client;
	sockaddr_in addr_server;
	timeval		timeout;
	struct hostent *host;

public:

	ClsWSClient()
	{
		timeout.tv_sec	= 0;//2;

		timeout.tv_usec = 500000;
		printf("Creating ClsWSClient\n");

		returnmsg = WSAStartup(0x202, &wsadata);
		if (returnmsg)
		{
			printf("Failed to startup WinSock\n");
		}

		host = gethostbyname("localhost");

		addr_server.sin_family		= AF_INET;
		addr_server.sin_addr.s_addr = inet_addr("128.39.147.14");//128.39.147.14");

//		addr_server.sin_addr.s_addr = *(unsigned long*)host->h_addr;

		addr_server.sin_port		= htons((u_short)4242);

		

		sock_client = socket(AF_INET, SOCK_STREAM, 0);//IPPROTO_TCP);

		if (sock_client == INVALID_SOCKET)
		{
			printf("Failed to create socket\n");
			WSACleanup();
			return;
		}

		if (connect(sock_client, (sockaddr*)&addr_server, sizeof(addr_server)) != 0)
		{
			printf("Failed to connect\n");
			WSACleanup();
			return;
		}
		else
		{
			printf("Connected to server\n");
		}

		fd_set fds_read;
		fd_set fds_write;
		fd_set fds_except;

		FD_ZERO(&fds_read);
		FD_ZERO(&fds_write);
		FD_ZERO(&fds_except);

		sendData();
		printf("Sent data to server\n");
		FD_SET(sock_client, &fds_read);


		u_long nNoBlock = 1;
        ioctlsocket(sock_client, FIONBIO, &nNoBlock);

		nNoBlock = 1;
		setsockopt(sock_client, SOL_SOCKET, TCP_NODELAY, (const char*)nNoBlock, sizeof(nNoBlock));//disabled some kind of algorithm, did not help


		while(1)
		{
			if (GetAsyncKeyState(VK_RETURN))
			{
				printf("Stopped waiting for incoming data\n");
				break;
			}
			printf("Waiting for data\n");
			Sleep(100);
			int s = select(0, &fds_read, &fds_write, &fds_except, 0);//FIXME - why can''t I receive using a valued timeout?? Even if the timeout IS 0? &timeout);

			
			if (s > 0)
			{
				printf("Received som kind of data\n");

				if (FD_ISSET(sock_client, &fds_read))
				{
					printf("Received data on sock_client\n");
					receiveData();
					break;
				}
			}
		}

		receiveData();

		system("pause");
	}

	void sendData()
	{
		int bytessent;
		unsigned long messagesize;

		char text[1024];
		sprintf(text, "I have connected");
		messagesize = strlen(text);
		messagesize = htonl(messagesize);

		bytessent = send(sock_client, (char*)&messagesize, sizeof(messagesize), 0);

		if (bytessent == SOCKET_ERROR)
		{
			printf("Failed to send data size\n");
			return;
		}

		messagesize = ntohl(messagesize);

		bytessent = send(sock_client, text, messagesize, 0);

		if (bytessent == SOCKET_ERROR)
		{
			printf("Failed to send data\n");
			return;
		}
	}

	void receiveData()
	{
		int bytesreceived;
		unsigned long messagesize;
		char datareceived[4096];

		bytesreceived = recv(sock_client, (char*)&messagesize, sizeof(messagesize), 0);

		if (bytesreceived == SOCKET_ERROR)
		{
			printf("Receive failed\n");
			return;
		}

		printf("Messagesize before ntohl: %i bytes\n", messagesize);

		messagesize = ntohl(messagesize);

		printf("Messagesize after ntohl: %i bytes\n", messagesize);


		bytesreceived = recv(sock_client, datareceived, messagesize, 0);

		if (bytesreceived == SOCKET_ERROR)
		{
			printf("Receive failed\n");
			return;
		}


		//null terminate string we got

		datareceived[messagesize] = ''\0'';

		printf("Server: %s\n", datareceived);
	}

	~ClsWSClient()
	{
		closesocket(sock_client);
		printf("Destroying ClsWSClient\n");
		WSACleanup();
	}
};
Thanks for any input! -Trond
-Trond
Reset the timer values before the select().
Advertisement
Thanks, but it didn''t work... I don''t understand, cause I use select() on the server as well, and I there it works perfectly... I don''t reset timer values before each select there.

-Trond
-Trond
Reset the fd_sets in the while loop.

while(1){   FD_ZERO(&rdset);   FD_ZERO(&wrset);   timeout.sec = 0;   timeout.usec = 500000;   s = select(...);   ...}


And remove that line:

ioctlsocket(sock_client, FIONBIO, &nNoBlock);

since you are using a select() anyway to poll the socket state.
I can''t believe I''ve overlooked this for all this time! I had forgot to FD_SET(client, fd_)... I tried to do that before each select, and now it works. Great! Now I''ll try to see if I have to set that each loop...

Thanks for your time,
-Trond
-Trond

This topic is closed to new replies.

Advertisement