2

When I use Javaa's Socket class to send out a byte array, does the write call in the following code block until it has verified that the recipient has received the data?

byte data[] = ...;
Socket socket = ...;

socket.getOutputStream().write(data); // blocking ?

The reason I ask, is if I have a list of sockets that I want to send the same data to, I want to send it as efficiently as possible, i.e., is there a better way than this:

ArrayList<Socket> sockets = ...;
byte data[] = ...;

for(int i = 0; i < sockets.size(); i++)
  sockets.getOutputStream().write(data);

1 Answer 1

5

The TCP handshake happens at connect(2) time, not at write(2) time.

Calls to write(2) will block until the OS TCP send buffer is depleted enough to accept more data from the program. (I can't imagine the OS unblocking the write(2) operation for a single free byte.)

The only guarantee you have is that the client has accepted data in the past, and is not further behind than the size of the TCP window for the session plus the size of the internal OS buffers. Whether or not any of that data has reached the application on the other end point is yet another layer of buffers -- the TCP stack on the remote peer will acknowledge received data and store it in buffers before the application has an opportunity to process it.

Sign up to request clarification or add additional context in comments.

5 Comments

So you are saying that it will unblock once the data has reached the tcp layer of the stack, not having to wait until the entire tcp handshake with the client is complete?
@gamemb, your code won't proceed to the write() calls until well after the handshake is complete. (The handshake happens once per session at connect() time.) But otherwise, yes, the code will unblock when the local TCP send buffers have freed up enough space to accept write() calls -- which might be 64KB window + 8KB buffer size ahead of what the remote peer has received and ACKed.
(Note that 64KB window is just a guess -- with TCP window scaling, the window could be megabytes large, almost up to a gigabyte of data. But it would take specialized environments to have one gigabyte of data in transit. :)
Yeah, I know. So, that in mind, is there a better way of sending the same data to mutliple clients that just a simple loop as above?
@gamernb, the two approaches possible are (a) use one thread per TCP session, this way the blocking only affects one thread/connection rather than holding up progress for all data transfers (b) using Java's Selector facility to write data to sockets that are prepared to accept the writes. (This corresponds with the C select(3) function.) This might be a better choice if you're trying to send synchronized game data to clients at nearly the same times.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.