Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what happens when I write data to a blocking socket, faster than the other side reads?

suppose I write data really fast [I have all the data in memory] to a blocking socket. further suppose the other side will read data very slow [like sleep 1 second between each read].

what is the expected behavior on the writing side in this case? would the write operation block until the other side reads enough data, or will the write return an error like connection reset?

like image 641
Aviad Rozenhek Avatar asked Jan 09 '13 16:01

Aviad Rozenhek


People also ask

What happens with a read on a non-blocking socket if all the requested data is not available?

If data is not available to the socket, and the socket is in blocking and synchronous modes, the READ call blocks the caller until data arrives.

Does writing to a socket block?

If O_NONBLOCK is set, write() does not block the process. If some data can be written without blocking the process, write() writes what it can and returns the number of bytes written. Otherwise, it sets errno to EAGAIN and returns -1.

What are the differences between blocking and non-blocking sockets why would you use one or the other?

In blocking socket mode, a system call event halts the execution until an appropriate reply has been received. In non-blocking sockets, it continues to execute even if the system call has been invoked and deals with its reply appropriately later.

Is reading from socket blocking?

Even when sockets are in "blocking" mode, the read and write operations on them do not necessarily read and write all the data available to be read or written. In order to write an entire buffer into a socket, or read a known quantity of data from a socket, they must be called in a loop.


1 Answers

For a blocking socket, the send() call will block until all the data has been copied into the networking stack's buffer for that connection. It does not have to be received by the other side. The size of this buffer is implementation dependent.

Data is cleared from the buffer when the remote side acknowledges it. This is an OS thing and is not dependent upon the remote application actually reading the data. The size of this buffer is also implementation dependent.

When the remote buffer is full, it tells your local stack to stop sending. When data is cleared from the remote buffer (by being read by the remote application) then the remote system will inform the local system to send more data.

In both cases, small systems (like embedded systems) may have buffers of a few KB or smaller and modern servers may have buffers of a few MB or larger.

Once space is available in the local buffer, more data from your send() call will be copied. Once all of that data has been copied, your call will return.

You won't get a "connection reset" error (from the OS -- libraries may do anything) unless the connection actually does get reset.

So... It really doesn't matter how quickly the remote application is reading data until you've sent as much data as both local & remote buffer sizes combined. After that, you'll only be able to send() as quickly as the remote side will recv().

like image 62
Brian White Avatar answered Nov 13 '22 16:11

Brian White