Thread: Using select() for writing

  1. #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.

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    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]

  3. #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

  4. #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: [email protected]
    aim: pherikx
    Last edited by codec; 05-03-2004 at 02:22 PM.
    C/C++ Support IRC Channel

    Server: irc.dal.net Channel: #csupport

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

  5. #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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. temperature sensors
    By danko in forum C Programming
    Replies: 22
    Last Post: 07-10-2007, 07:26 PM
  2. brace-enclosed error
    By jdc18 in forum C++ Programming
    Replies: 53
    Last Post: 05-03-2007, 05:49 PM
  3. Directional Keys - Useing in Console
    By RoD in forum C++ Programming
    Replies: 38
    Last Post: 10-06-2002, 04:42 PM
  4. FAQ: Directional Keys - Useing in Console
    By RoD in forum FAQ Board
    Replies: 38
    Last Post: 10-06-2002, 04:42 PM