Problem receiving data while using select()

Started by
3 comments, last by Portable591 22 years, 5 months ago
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.
Advertisement
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
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Thanks so much. I really couldn''t find any good resources on how to use it. It works perfectly now.
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
Widelands - laid back, free software strategy
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

This topic is closed to new replies.

Advertisement