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