Reputation: 543
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.
Upvotes: 3
Views: 1491
Reputation: 701
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?
Upvotes: 0
Reputation: 8476
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.
Upvotes: 3
Reputation: 196
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);
Upvotes: 0