Archived

This topic is now archived and is closed to further replies.

what does FD_ISSET macro really do?

This topic is 5401 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

There''s an article by Richard Hallet explaining the basics of creating a Non-Blocking server here on GameDev.net. I''m not going to paste all the code here - the idea is quite clear. The main thing I''m interested in is below. Here''s an excerpt from the article: //////////////////////////////////////// // The Actual Select Function sees if data coming in and stores it in s s = select(nfds,&input_set,NULL,&exc_set,&timeout); if (s > 0) // Is there data coming in? { // Look Through all the clients to see which one is giving error or data for (int i=0; i < ClientsConnected { if (FD_ISSET(Client.ClientSocket,&exc_set)) // There was an Error? { // For this Server we assume it was a disconnection or something so close the socket. // Store the IP of the Client that Just Disconnected char *ClientIp = inet_ntoa(Client[i].clnt_addr.sin_addr); cout << "This Client Has Disconnected: " << ClientIp << endl; Disconnect(i); } if ((FD_ISSET(Client[i].ClientSocket, &input_set))) // Actual Data coming through? { // Get whatever message the client sending, and carry out appropriate response Get_Message(i); } i++; // Next Client } } ////////////////////////////////////////////// I''m not sure, but I think there''s a little problem (actually it is a HUGE problem! =)): Imagine we have a bunch of clients. Their connection descriptors are written to the ''input_set''. Now we call the ''select()''. The SECOND client is ready to send the data, so ''s'' is bigger than 0. Now we''re entering the loop checking for each client. So the descriptor of the FIRST client is in the ''input_set'' - ''FD_ISSET'' macro returns TRUE and we''re trying to ''Get_Message()'' from the first client. But there''s no data coming from the first client (which is in the ''input_set'' descriptor list). And the ''Get_Message()'' calls ''recv()'' which will cause blocking! So the server would be blocked until some data comes from the first client. Or does ''FD_ISSET'' macro check the state of the descriptor in the list to see if the descriptor has changed? The documentation for FD_ISSET macro says that it checks to see if the descriptor is in the list only. But the server would block then! Or am I misunderstanding something? Any comments?

Share this post


Link to post
Share on other sites
You misunderstand. After the call to select(), the only bits that remain set in input_set are those corresponding to the client with the error.

I suggest you read the manual page for select(). It's very informative.


But... but that's what HITLER would say!!

[edited by - sneftel on March 3, 2003 9:02:05 PM]

Share this post


Link to post
Share on other sites