Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

send() not deliver all bytes?

Why doesn't send() in winsock guarantee delivery of the all bytes you request?

This is TCP and it's blocking sockets.

Similarly, this happens when non-blocking. How can you guarantee that you send everything?

I've noticed recv() does the same.

like image 395
user1255454 Avatar asked Oct 18 '25 02:10

user1255454


2 Answers

If it didn't send everything, just call send again on the rest. If blocking, you can do it immediately. If non-blocking, you can either wait or use a socket discovery method (like select or I/O completion ports). The same goes for recv. If you didn't get all you wanted, call recv again. This is one of the reasons both recv and send return the number of bytes sent or received.

The number of bytes you pass to send or recv is just a limit. It can send less than that (though, unless non-blocking, usually won't). But it can definitely receive less than that. (The OS has no control over how much data it receives or when it receives it.)

TCP is implemented for you. But if you have an application protocol that involves application-level messages, then the application has to implement them. It won't happen by magic. TCP doesn't "glue the bytes together" into a message for you. TCP is a byte-stream protocol, not a message protocol. If you want messages, you have to implement them.

like image 74
David Schwartz Avatar answered Oct 20 '25 15:10

David Schwartz


This behaviour is "by design".

You can use an outer loop as shown in this example:

int sendBuffer (SOCKET ClientSocket, const char *buf, int len, int flags) 
  {
    int num_left = len;
    int num_sent;
    int err = 0;
    const char *cp = buf;

    while (num_left > 0) 
      {
        num_sent = send(ClientSocket, cp, num_left, flags);

        if (num_sent < 0) 
          {
            err = SOCKET_ERROR;
            break;
          }

        assert(num_sent <= num_left);

        num_left -= num_sent;
        cp += num_sent;
      }

    return (err == SOCKET_ERROR ?  SOCKET_ERROR : len);
  }
like image 45
Axel Kemper Avatar answered Oct 20 '25 15:10

Axel Kemper



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!