C Board  

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

Reply
 
LinkBack Thread Tools Display Modes
Old 04-03-2004, 10:16 PM   #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.
codec is offline   Reply With Quote
Old 04-04-2004, 12:13 PM   #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.
anonytmouse is offline   Reply With Quote
Old 04-04-2004, 04:10 PM   #3
End Of Line
 
Hammer's Avatar
 
Join Date: Apr 2002
Posts: 6,240
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]
Hammer is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

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


All times are GMT -6. The time now is 05:58 PM.


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