C Board  

Go Back   C Board > General Programming Boards > Networking/Device Communication

Reply
 
LinkBack Thread Tools Display Modes
Old 04-29-2004, 12:59 PM   #1
Registered User
 
Join Date: Apr 2004
Posts: 21
Using select() for writing

Hello all,

Ive wrote a server in c using select to handle the data received by the clients however im using the select function only for receiving data and not sending. When i need to send Im currently looping through a linked list of connected sockets and using a send() system call to send out the data.

This would appear to be a bad idea as if I have 200 clients connected I have to loop through the entire list each time I need to send some data out.

A friend had told me I could use a buffer for each socket structure, fill it up with data and then send with selects "write". Im having some trouble getting my head around this though.

If i add a buf_out in the socket structure do I still need to loop through the list but just somehow pass it into the select to write ?

Ive searched around the web, found loads of examples using selects read but very few regarding the write.

Could anyone post a little code or point me in the right direction as to where I can learn about sending data from buffers with selects write.

Thank you.

Thoroughly Stumped Stan.
StanleyC is offline   Reply With Quote
Old 04-29-2004, 03:47 PM   #2
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
If you're talking about the select() function, you can use it to test the output stream to see if it is immediately available for writing, but that in itself doesn't actually send anything. You still need to send to the socket directly. I don't know of a function that will write to multiple sockets in one go (that doesn't mean there isn't one )
__________________
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Hammer is offline   Reply With Quote
Old 04-29-2004, 04:20 PM   #3
Registered User
 
Join Date: Apr 2004
Posts: 21
Ok thanks Hammer, i must have got the wrong end of the stick.

I guess he means adding something like

Code:
struct sockets
{
  int sock;
  char out_buf[1024];
};
Then rather than sending inside a function based on some data coming in, ill simply add the outgoing data to the buffers of the players connected.

Then each game turn loop through my connected sockets list and send out_buf to the players if theres any data which needs to go out.

Not sure how this would be more efficent though as I would have to loop my entire socket list every game turn though even if there was no data to be sent out.

Ahh well im even more confused now, thanks for reply anyway

Stan
StanleyC is offline   Reply With Quote
Old 05-03-2004, 02:19 PM   #4
sockets mad
 
Join Date: Mar 2002
Posts: 126
There are a lot of select() tutorials around the net, but most of them do not include much detail on how to correctly handle writing of data to sockets, which can be a pain.

To save you looping through the entire list of connected sockets to check for any data in the output buffer, you can create an FD_SET of all the sockets that have data waiting to be sent out and pass that to select() in addition to your FD_SET of sockets to check for data waiting to be read.

select() function:

Code:
int select(
  int nfds,                           
  fd_set FAR *readfds,      // [in, out] Optional pointer to a set of sockets to be checked for readability          
  fd_set FAR *writefds,     // [in, out] Optional pointer to a set of sockets to be checked for writability          
  fd_set FAR *exceptfds,             
  const struct timeval FAR *timeout  
);
So you could do something like this when you need to send data to a client socket:

1) Add the data to the output buffer of the appropriate client.
2) Call a function which tries to send as much of the buffer as possible.
3) If it all sends then, finished.
4) If not, add the socket to your FD_SET of sockets you need to write data to.
5) Pass the FD_SET to select (third paramter).
5) Use the output from select() to know when you can try and write the rest of the data. When you can, goto step 2. Once it's all written. Remove the socket from the FD_SET.

The code around a select statement can become quite complex. I've recently done a lot of research into this subject, so if you need some extra help or just want me to explain this a bit more contact me and I'm sure I'll be able to help out. I might write a guide at some point.

e-mail/msn: daniel.briley@ntlworld.com
aim: pherikx
__________________
C/C++ Support IRC Channel

Server: irc.dal.net Channel: #csupport

Come along and help make it a great resource for the community.

Last edited by codec; 05-03-2004 at 02:22 PM.
codec is offline   Reply With Quote
Old 06-02-2004, 07:44 AM   #5
Registered User
 
Join Date: Jul 2002
Posts: 47
The buffer idea might be nice but could actually cause more problems than you think. First of all. No matter what you are going to have to loop through the list in some way. With this buffer you are only slowing down the loop. Because rather than reading a SOCKET descripter for the user to send data to and write to you are actaully writing the data into memory. Not once but twice. When you send data through a socket it still gets written to memory for handling by the operating system. You are essentially slowing down this process even more now.

The loop is currently probably the fastest way to transfer data unless you learn how to do multicasting and it is supported by your network.

Since we have yet to find a more efficient way of writing data to a socket you need to focus on making everything else in your server VERY responsive. You only want to store stuff in variables or memory when you really need it. The more memory access and file access in your server...The slower it becomes.

HINT: When using a for loop to send the data.. Try and use a stack integer for this rather than heap. It surprisingly helps significantly in the speed. And 200 clients is not that bad as long as you dont send huge buffers at a time. Maybe 255bytes per transmit. That would spread out the lag more evenly and keep everyone more in seek than say a 1024byte buffer because it would slow down the loop.

I hope this info helps you on your venture
Chronom1 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
temperature sensors danko C Programming 22 07-10-2007 07:26 PM
brace-enclosed error jdc18 C++ Programming 53 05-03-2007 05:49 PM
Directional Keys - Useing in Console RoD C++ Programming 38 10-06-2002 04:42 PM
FAQ: Directional Keys - Useing in Console RoD FAQ Board 38 10-06-2002 04:42 PM


All times are GMT -6. The time now is 11:29 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22