Click here to Skip to main content
15,889,462 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have written some server code which has a method which handles the receiving of data from the client. It has a select method with checks for data to read from the socket and has a timeout value. The client sends a message to my server every second. If I set my code running, then stop the client, I would have expected the select method to return a value of -1. But this doesn't appear to happen. If the client closes, the return value appears to be > 0 but then when the recv method is called, the bytes received is zero.

I have put the code below, with comments and questions. Could somebody please explain exactly what is going on please. I can get my code to do what i want, but not how I expected, so I really don't understand why my code works! Many, many thanks.

C++
//initialise the fd_set rxSet (file descriptor set) values
FD_ZERO(&rxSet);
//add m_clientSocket to the set of file descriptors in rxSet
FD_SET(m_clientSocket, &rxSet);
maxFD = m_clientSocket;//not needed, just for comaptibility with linux select()

//wait for the specified timeOutVal to see if there is any data to read
//on the m_clientSocket
sockVal = select(maxFD, &rxSet, NULL, NULL, &timeOutVal);
		
//see if there is some data to read on the socket
if(sockVal > 0)
{
	//read the data from the socket
	int bytesReceived = recv(m_clientSocket, recvBuf, recvBufLen - 1, 0);
	//add a null terminator at the end of the data to avoid storing an garbage
	recvBuf[bytesReceived] = '\0';
	//check if there was an error on the socket
	if(bytesReceived == -1)
	{
                //this does not get reached if the client disconnects
                //what would cause this code to be reached?
		printf("server socket error\n");
		break;
	}
	if(bytesReceived > 0)
	{
		//bytes were received
		//read the message, form the response and send response to controller
		RespondToAllMessagesFromController(recvBuf);
						
		noDataReceivedCount = 0;//reset the count
	}
	if(bytesReceived == 0)
	{
	        //this is reached if the client disconnects - but I don't understand 
                //why because i would have thought that sockVal would not be > 0 in
                //this case

		break;//leave while loop, leave Digitiser running		
	}
}
else if(sockVal < 0)
{
	//there was an error on the socket - but this doesn't get reached if the
        //controller disconnects. What would cause this to be reached?
	//even if the if(bytesReceived == 0){} above is removed.
	int test = 0;
}
else //if(sockVal == 0) because select timed out
{
       //this gets reached when the socket hasn't disconnected but no messages arrive,
       //as I would expect
}
Posted
Updated 21-May-12 6:16am
v2
Comments
Richard MacCutchan 21-May-12 12:21pm    
See here for details about return values from this statement.
Jackie Lloyd 22-May-12 2:57am    
Thanks - I see from reading through this that what I am seeing is what should happen, and it's my fault for not reading this. Sorry, I read it a while ago and had remembered it wrong. (feeling really stupid now)

1 solution

Hi,

when reading through it, it seems that you are really doing something wrong with the select. As the maxFD value is not required in (i assume) win32 you can better leave it at 0 or 1 or something like that; you are currently setting it to the address of the client socket, as it is(or should be) ignored I fail to see why it would go wrong though.

one other piece of advice; you are using the returned byte count of the recv to set a '\0' in an array and one line below that you come to the conclusion that the value may turn out to be a bit lower than 0, which naturally is a valid statement. It would be a shame it it would actually happen though as that has a not so nice effect on the the memory preceding your array.

Hope this helps,

AT
 
Share this answer
 
Comments
Jackie Lloyd 22-May-12 2:53am    
Hi, yes, the maxFD was left in like that as the code was ported from linux but I had thought it would be ignored too. Adding the '\0' as the last character was put in to avoid reading past the valid data. Before that was in I had some problems - but I can't remember the exact details now, but it did fix it. So I don't understand what might happen to the memory before the array. Many thanks for your suggestions.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900