Archived

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

Portable591

Problem receiving data while using select()

Recommended Posts

My program currently uses select to attempt to discover when a socket has been sent new data to read. My program works with 1 client when i comment out the "if" and select function call, but when I try to use select, my program acts as though data is never sent to it. I am guessing that the select is not polling the socket quickly enough to discover when it has been sent new data, but I am not sure. Has anyone else had this problem, and how did you resolve it? bool Network::SendPacket() { fd_set readfds, activefds; timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; send(current->connection, buffer, bufferPos, 0); bufferPos = 0; FD_ZERO(&activefds); FD_SET(current->connection + 1, &activefds); readfds = activefds; select(FD_SETSIZE, &readfds, 0, 0, &tv); if(FD_ISSET(current->connection, &readfds)) { recv(current->connection, buffer, 32768, 0); return HandlePacket(); } return true; } As you can probably see, I''ve just copied most of the select-related code directly from a gnu tutorial on using select.

Share this post


Link to post
Share on other sites
Now, assuming current->connection is a SOCKET handle, the mistake I see is:

FD_SET(current->connection + 1 , &activefds);

That + 1 shouldn''t be in there, at least not if you are using Winsock/Win32. FD_SET is a macro that takes a descriptor and a fd_set data structure. By incrementing current->connection you are passing an invalid socket handle to FD_SET.

Remove the + 1 and it should work.



Dire Wolf
www.digitalfiends.com

Share this post


Link to post
Share on other sites
select(FD_SETSIZE, &readfds, 0, 0, &tv);

The first parameter to select() should be the highest fd number + 1 (that might be where you got that +1 from). Assuming that FD_SETSIZE is the maximum fd # that fits into an fd_set + 1 your code will work as well, but it gives the kernel additional work to do (it can''t just skip all the high bits in the fd_set).

cu,
Prefect

Share this post


Link to post
Share on other sites
I also think your lay out is a bit off. If your function is only to send packets, then you wouldn't need to do perform a select() call. Just use your FD for that client to send.

If your function is polling too, then you might not want to do your FD_ZERO(). Since you zero out the activefds, then assign them to readfds, after adding a single client connection, you are only really checking that one client FD for incoming data.

You might want to avoid FD_ZERO() in that function call and only use it to initialize the structre. Right now from what I see, I don't know how you're checking multiple clients?

Also, keep in mind that Select alters the readfds list you pass to it. You'll want to keep a master fd list of all connected clients, and then just copy the master fd list to the readfds list before you select. That way you can always get your master list back before each call to select. Then just do your FD_ISSET() on the readfds. Make sense?

Rube.

Edited by - Rube on November 15, 2001 4:29:19 PM

Share this post


Link to post
Share on other sites