randy newfield
randy newfield

Reputation: 1221

recv is always reading 0 bytes after second recv call

I have a TCP server running on a platform which reads bytes from a buffer and sends all the bytes over the network in one send call:

send(sSocket.client_sock, base, frb_size, 0);

frb_size is 2_228_224 bytes in size.

On the receiving end I am trying to buffer the data:

while(1) {
    while(total != size) {
        r = recv(my_socket->sock, buf, 8192-total, 0);
        memcpy(buffer+total, buf, r);
        total += r;
    }
  //some code dealing with manipulating the buffer with SDL
}

Where I have a smaller buffer buf that has a size of 8192. When read it uses memcpy to place it into the proper position inside buffer which is size 2_228_224.

My problem is that after the first iteration all proceeding iterations return r being 0 meaning the socket has been closed as per documentation. What is also weird is that no matter what sized buf I use, it always returns the full number of bytes on the first iteration. For example 8192 bytes would be returned in the above code, if I change the sizes to 65507 it will return 65507, but if i change it to 2_228_224 it will never return the full buffer.

Meanwhile when I do:

while(1) {
   r = recv(my_socket->sock, buffer, size, 0);
  //some code dealing with manipulating the buffer with SDL
}

Where size is the size of buffer (2_228_224). r never returns 0 when debugging, but it also never has the full number of bytes that make up the sent input.

Am I doing something wrong with the socket API on windows? Is there a way to make Winsock sockets block until all number of bytes are received?

Thanks.

Upvotes: 1

Views: 1159

Answers (1)

K. A. Buhr
K. A. Buhr

Reputation: 50819

As noted in the comments, using 8192-total isn't right. To read up to size bytes exactly, use something like this:

while(total < size) {
    int bytes = size - total;
    if (bytes > 8192) bytes = 8192;
    r = recv(my_socket->sock, buf, bytes, 0);
    if (r <= 0) {
        /* handle this! */
        break;
    }
    memcpy(buffer+total, buf, r);
    total += r;
}

At each iteration, it attempts to read the number of bytes left out of the total but capped at the size of the input buffer.

It's important to handle r <= 0 and break out of the loop to avoid an infinite loop (if r == 0 repeatedly) or a segfault (if r == -1 repeatedly pushes total negative).

Upvotes: 2

Related Questions