• Advertisement

Archived

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

fd_set under unix

This topic is 5132 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

I''m struggling with a port of my network module to a unix system. I used to store all sockets in an fd_set structure under windows, and this structure under windows has these nice members called "fd_count" and "fd_array". The first one contains the nr of entries, and the array contains all the actual data. I had the habbit of using fd_count and fd_array to loop through the array when sending something to all connected clients or when shutting down. Now, the Unix fd_set, doesn''t have the fd_count and fd_array members, and I''m kind of baffled on how to accomplish my neat loops. Does anyone know if I can get the count of the set and how I can get to the data?

Share this post


Link to post
Share on other sites
Advertisement
You check the elements with the FD_ISSET() macro. The number of elements you''re supposed to keep track of yourself.

Share this post


Link to post
Share on other sites
Alright... thanks... that clarifies some things.

I also just got input from someone here near me. I now see I didn''t quite understand the structure of the file descriptor set.

The fd set is a structure containing handles to data generators (lacking a better word), right?. The fd_set is a binary set, with every bit representing a file descriptor.

Aparently the windows version keeps an internal list of which fd''s (bits) are set as integer, and the actual list of bits is kept somewhere else (as it''s not in the header). So it''s easier to loop through it.

I think I prefer the windows way. Now I have to loop through the entire fd_set, checking every bit. Or is there a way to do it quicker?

Share this post


Link to post
Share on other sites
No offense, but your use of the fd_set structure in Winsock goes against the recommended use to begin with. The documentation for select() in the API documentation says specifically to treat it as an opaque type. Had you done it the right way in the first place, you wouldn''t be having troubles now.

Share this post


Link to post
Share on other sites
You should have a master FD_SET and a read or write FD_SET. First copy the socket you open for listening to master and read (or write but I'll use the read set alone). Use a list or vector of type socket or of a struct with a socket member. Also copy the initial listening socket to the vector. When you drop out of select for the first time and subsequent times check for socket elements in the read/write set using FD_ISSET against the elements in the vector/list, and proceed accordingly. If after the return from select the listening socket is set in the read/write set then you have a connection request queued, so you'll either reject it or add it to the vector after calling accept as well as adding it to the master set by calling FD_SET. At the end of your loop copy the master set back into the read/write set and continue on. The key is that the read or write fd_set will be reduced to what sockets are in a state to read/write respectively. It will remove sockets from the set you are polling that are in a neutral state. That is why you'll maintain a master set to copy back to the read/write set at the end before calling select once again. Hope this helps.

EDIT: If you are using unix you can use the first parameter from select as the amount of file descriptors and use those for comparison. But the first parameter is ignored in windows, so for cross platform compatibility consider using my method unless you find better.

[edited by - nervo on April 6, 2004 9:40:25 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by SiCrane
No offense, but your use of the fd_set structure in Winsock goes against the recommended use to begin with. The documentation for select() in the API documentation says specifically to treat it as an opaque type. Had you done it the right way in the first place, you wouldn't be having troubles now.


I see it written in the docs now, and I can't do anything but agree with you.
So, I'm going to change my programming to only use the defined macro's instead of fiddling in the set directly. That should fix a load of problems.

Do you have any other tips for the port? Like things to make macros of? things that are often different on different OS-es? This is the first time I program things for anything else than Windows, so I could use a few tips

[edited by - Structural on April 6, 2004 9:38:29 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Nervo
You should have a master FD_SET and a read or write FD_SET. First copy the socket you open for listening to master and read (or write but I''ll use the read set alone). Use a list or vector of type socket or of a struct with a socket member. Also copy the initial listening socket to the vector. When you drop out of select for the first time and subsequent times check for socket elements in the read/write set using FD_ISSET against the elements in the vector/list, and proceed accordingly. If after the return from select the listening socket is set in the read/write set then you have a connection request queued, so you''ll either reject it or add it to the vector after calling accept as well as adding it to the master set by calling FD_SET. At the end of your loop copy the master set back into the read/write set and continue on. The key is that the read or write fd_set will be reduced to what sockets are in a state to read/write respectively. It will remove sockets from the set you are polling that are in a neutral state. That is why you''ll maintain a master set to copy back to the read/write set at the end before calling select once again. Hope this helps.

EDIT: If you are using unix you can use the first parameter from select as the amount of file descriptors and use those for comparison. But the first parameter is ignored in windows, so for cross platform compatibility consider using my method unless you find better.

[edited by - nervo on April 6, 2004 9:40:25 AM]


That helps a lot!

Share this post


Link to post
Share on other sites

  • Advertisement