Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I send two buffers together through a socket in C?

Tags:

arrays

c

sockets

I'm writing a function for sending a header containing the size of some data, followed by the data itself, over a socket. send() takes one pointer and one size and reads/sends from that pointer. I want to use a function that takes two pointers and two sizes and reads/sends from the first pointer then switches to the second one once it has reached the end of the first one. That way, I'd be able to send the header before the payload data without making extra calls to the system network stack or copying memory over.

Here's my function currently. I have to use an extra sending loop just to send the header first:

int send_size(int socket, uint8_t* buf, size_t len){
    if (!buf) return INVALID_INPUT;
    uint8_t header[4];
    for (int i = 0; i<4; i++){ // Put size of data into 4-byte header, little endian.
        header[i] = len%256;
        len = len/256;
    }
    size_t bytesRemaining = len + 4;
    size_t sent;
    while (bytesRemaining > len){ // Send header.
        sent = send(socket, header, bytesRemaining - len, SO_NOSIGPIPE);
        if (sent==-1) return NETWORK_ERROR;
        bytesRemaining -= sent;
    }
    while (bytesRemaining > len){ // Send payload.
        sent = send(socket, buf, bytesRemaining, SO_NOSIGPIPE);
        if (sent==-1) return NETWORK_ERROR;
        bytesRemaining -= sent;
    }
    return NO_ERROR;
}

I'd rather have one sending loop that tells my system to send both the arrays together so I don't have to call send() as often.

like image 921
sudo Avatar asked Oct 17 '25 19:10

sudo


1 Answers

you may have a look at writev or sendmsg which allow to send an io-vector, provide concept of scatter/gather.
Working with networking application usually face with a situation that send some buffers together (adapt the protocol). I usually aggregate them into a single big buffer if there are many small buffers(such as char, int, long element, so copy is not expensive). In case of you have some bigger buffer need to send, use scatter/gather is better because it does need to make a memory copy(so call zero-copy).
sendmsg is a bit more advanced than writev, it accept some TCP/IP options. Moreover, if one your buffer is a file, you can use sendfile, which use DMA to avoid extra memory copy.

like image 157
secmask Avatar answered Oct 20 '25 10:10

secmask



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!