3

Here is what the code roughly looks like:

int main() {
    // All the details needed before using the send() function here...

    send(socket, buffer, 1024*1024*1024, 0);
    return 1;
}

If send() is supposed to be blocking regardless of the size of the buffer then I think it shouldn't return until the entire buffer has been sent. But from what I have observed, given a large enough buffer, it does return before send() has sent the entire buffer.

However, if I add this code before the return statement:

while(1){}

send() blocks as expected and sent the entire data.

Isn't send() supposed to be blocking like that or is there something wrong with the send() function itself?

Thanks in advance.

neonyte
  • 5
  • 4
Courage
  • 543
  • 5
  • 25
  • C has no `socket` function. If you use POSIX socket then please add the appropriate tag [tag:posix] – phuclv Feb 22 '18 at 11:07

3 Answers3

3

When blocking socket is used, send() function blocks until last data is delivered to queue of local TCP-stack.

So send() may return when part of the data is still queued in local TCP-stack. Because your process exits right after send() call, there can be undelivered data in local TCP stack during exit.

TCP stack may continue the data transfer after exit, if linger is enabled. Or TCP stack may reset the connection without any attempt to transfer undelivered data to the peer, if linger is disabled.

If you close the TCP connection gracefully when linger is enabled, then TCP-stack should (try to) deliver queued data to the peer.

Close the connection gracefully by adding close() call. And make sure that SO_LINGER is enabled with reasonable timeout:

send(socket,buffer, 1024*1024*1024,0);

const struct linger linger_val = { 1, 600 };
setsockopt(socket, SOL_SOCKET, SO_LINGER, &linger_val, sizeof(linger_val));

close(socket);
return 1;

Usually there is no need to change SO_LINGER. More information about SO_LINGER in man page of socket(7):

SO_LINGER
              When enabled, a close(2) or shutdown(2) will not return until
              all queued messages for the socket have been successfully sent
              or the linger timeout has been reached.  Otherwise, the call
              returns immediately and the closing is done in the background.
              When the socket is closed as part of exit(2), it always
              lingers in the background.
SKi
  • 8,007
  • 2
  • 26
  • 57
0

With 0 as flag, send() is like the write() function:

and for write():

The number of bytes written may be less than count if, for example, there is insufficient space on the underlying physical medium, or the RLIMIT_FSIZE resource limit is encountered (see setrlimit(2)), or the call was interrupted by a signal handler after having written less than count bytes. (See also pipe(7).).

Check also this answer:

Blocking sockets: when, exactly, does "send()" return?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Fabio_MO
  • 713
  • 1
  • 13
  • 26
  • thanks reply, send() is up layer function than write(),but this can not explain the while(1){} code thanks again. – Courage Feb 22 '18 at 09:24
0

send() is blocking call, but it is blocked till all the data is pushed to sendbuffer. You can modify the program to exit when all the data is send from the socket. This is possible by reducing the sendbuffer size. you can use setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)send_buffer, send_buffer_sizeof);