Thread: handling partial send()s

  1. #1
    sockets mad
    Join Date
    Mar 2002
    Posts
    126

    handling partial send()s

    NOTE to Moderators I have also posted this topic in the C++ programming board due to the relatively low traffic on this board. Please feel free to delete this copy.

    Hi,

    I'm trying to decide as to the best way to handle when the socket function send() does not send all the data that you ask it to send.

    I have a select() based server with non-blocking client sockets. I've found one suggestion of how to handle it, which is below:

    Code:
        #include <sys/types.h>
        #include <sys/socket.h>
    
        int sendall(int s, char *buf, int *len)
        {
            int total = 0;        // how many bytes we've sent
            int bytesleft = *len; // how many we have left to send
            int n;
    
            while(total < *len) {
                n = send(s, buf+total, bytesleft, 0);
                if (n == -1) { break; }
                total += n;
                bytesleft -= n;
            }
    
            *len = total; // return number actually sent here
    
            return n==-1?-1:0; // return -1 on failure, 0 on success
        }
    This to me seems bad because my program could end up looping, trying to send data to one single client with saturated bandwidth (or some other problem), when it could be serving some other client. Wouldn't it be better to do something like the following?

    1) Append the data that you wish to send to some sort of send buffer for the socket concerned.

    2) Attempt to send all the data in the buffer. If it's all sent, clear the buffer and that's it, done. Otherwise, update the buffer so it contains only the data that is still waiting to be sent (remove what was sent).

    3) Add the socket concerned to an fd_set for use with select() if it has data in it's send buffer.

    4) Specify the fd_set as the third parameter to select() (sockets to check for writability), so that you can then wait until it's possible to write to the socket again.

    5) Process the fd_set once it has gone through select() and goto step 2.

    If you do it this way, then you're not wasting any time trying to send to one particular client, when you could be servicing others.
    You don't need to worry about how long it takes to get all the data to the transport layer.

    Any select() experts out there that can give me some advice?

    Many thanks,

    Daniel Briley
    Last edited by codec; 04-03-2004 at 10:30 PM.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    I'd say your proposed approach is spot on. However, instead of moving the left over data around in the buffer, you may want to consider having a variable that records what position the sending is up to.

  3. #3
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    With regards to the code you've posted, to make it safer and avoid a high number of loops, simply put a looper counter in there. If it exceeds 5 (for example), exit the loop and return.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. signal handling and exception handling
    By lehe in forum C++ Programming
    Replies: 2
    Last Post: 06-15-2009, 10:01 PM
  2. UDP socket partial reading
    By mynickmynick in forum Networking/Device Communication
    Replies: 0
    Last Post: 03-25-2009, 11:43 AM
  3. event handling is serialized in MS Visual Studio C++ 2005 ??
    By mynickmynick in forum Windows Programming
    Replies: 3
    Last Post: 08-07-2008, 04:47 AM
  4. need help on error handling.
    By broli86 in forum C Programming
    Replies: 9
    Last Post: 06-19-2008, 11:55 AM