send() function in C how to handle if not all bytes are sent?

19,226

Solution 1

Yes, you have to advance the buffer pointer and repeat the send call until either the entire buffer is consumed or you get a hard error. The standard idiom looks something like this:

int
send_all(int socket, const void *buffer, size_t length, int flags)
{
    ssize_t n;
    const char *p = buffer;
    while (length > 0)
    {
        n = send(socket, p, length, flags);
        if (n <= 0)
            return -1;
        p += n;
        length -= n;
    }
    return 0;
}

Note that if you are sending datagrams whose boundaries matter (e.g. UDP) you cannot use this technique; you have to treat a short send as a failure.

Solution 2

You could try something like:

int ret, bytes = 0;
while (bytes < buflen) {
    ret = send(sock_fd, buf+bytes, buflen-bytes, flags);
    //check for errors
    if (ret == -1) {
        // handle error
    }
    bytes+=ret;
}

Solution 3

Yes, you do have to worry about the value returned by send (or write and so on). There is no extremely clever way around it, but there are a few functions written by the excellent Richard Stevens, namely readn and writen.

This article on informit seems to have a version of these functions.

Share:
19,226
Ahmed
Author by

Ahmed

Updated on October 02, 2022

Comments

  • Ahmed
    Ahmed over 1 year

    I need to send data across to the socket, basically transferring a file ,

    According to send() function docs, it says,

    If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter. Otherwise, a value of SOCKET_ERROR is returned,
    

    The line that I am worried about is, the return value may be less than requested value. Because I am reading from a file and writing to a socket, because it may not send all the bytes, I guess I would have to retry if the full buffer was not sent ? in which case I guess I would have to somehow advance the pointer on the same buffer by bytes read and send it again ??

    I just want know if that's the way about it ? or is there a much clever way to it, so that all the requested data gets sent without me having to worry about when not all data was sent ?

    Thanks,