Larx Larx - 18 days ago 8
Java Question

When Server Socket write, does it waits until Client Socket reads?

I have two java classes one is the Server and the other is the Client. Suppose a case were I need to send 100 MB of data from server to client. When I send this message does the server waits until the client reads?
If you look at the code, Does the endTime variable of Server dont take value until the client reads the 100 MB sent?

Server class:

public class MyServerSocket {

private ServerSocket providerSocket;
private Socket connection = null;
private ObjectOutputStream out;
private ObjectInputStream in;
private String message;

public static void main(String[] args) {
MyServerSocket m = new MyServerSocket ();
m.establishConnection();
}

public void establishConnection(){
//SETUP CONNECTION
providerSocket = new ServerSocket(2004, 10);
connection = providerSocket.accept();
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connectiongetInputStream());
//END SETUP CONNECTION

//Suppose this String contains 100 MB
String x = "Send 100MB of data";

sendMessage("Server sends string x");

//Here is the doubt
String startTime = System.nanotime();
sendMessage(x);
String endTime = System.nanotime();

do{
message = (String)in.readObject();

if (message.contains("bye")){
System.out.println("Server receives bye from Client");
}
}while(!message.contains("bye"));

}

public void sendMessage(String msg)
{
try{
out.writeObject(msg);
out.flush();
}
catch(IOException ioException){
ioException.printStackTrace();
}
}
}


Client Classs:

public class MyClientSocket {

private Socket requestSocket;
private ObjectInputStream in;
private ObjectOutputStream out;
private String message;

public static void main(String[] args) {
MyClientSocket n = new MyClientSocket ();
n.establishConnection();
}

public void establishConnection(){
requestSocket = new Socket("localhost", 2004);
in = new ObjectInputStream(requestSocket.getInputStream());
out = new ObjectOutputStream(requestSocket.getOutputStream());

do{
if(message instanceof String){
message = (String)in.readObject();
}else{
message = "";
}
if(message.contains("Server sends string x")){
//The following line reads the 100 MB String
String x = (String)in.readObject();

sendMessage("bye");
}
}while(!message.contains("bye"));
}

public void sendMessage(String msg)
{
try{
out.writeObject(msg);
out.flush();
}
catch(IOException ioException){
ioException.printStackTrace();
}
}


Thanks in advance

Answer

When I send this message does the server waits until the client reads?

Sockets are asynchronous. The writer only wait for free space in the send buffer. However this buffer is limited, often around 64 KB. If you send a large amount of data, the sender has to wait for space in the send buffer before it can write any more.

In short, if the receiver can read fast enough, the sender never has to wait for it. If the data can't be sent fast enough or read fast enough, the buffer fills and the sender has to wait until there is more space.

Does the endTime variable of Server dont take value until the client reads the 100 MB sent?

The endTime is after the last piece of data is sent. This could be any amount of time until the data is received, however most likely it won't make much difference as the file is much larger than the buffer. For small files, it is pretty meaningless.

The only way to know the data has been received is for the other end to send back a message saying it has received the whole file.

BTW Object Streams are a great way to send any object, however it is one of the slowest. If you are benchmark I would consider using just about anything else. (Using XMLEncoder is worse) Try using a Data Stream or a PrintWriter/BufferedReader.

Comments