Reputation: 125
I have client code that looks like:
Socket s = new Socket(server.getHostName(), server.getPort());
PrintWriter p = new PrintWriter(s.getOutputStream());
p.println(message);
p.flush();
s.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String newLine;
StringBuffer response = new StringBuffer();
while((newLine = br.readLine()) != null)
response.append(newLine);
System.out.println(response.toString());
p.close();
br.close();
and server code that looks like:
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String nextLine;
StringBuffer request = new StringBuffer();
System.out.println("Starting read....");
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
System.out.println("Message recived!!");
System.out.println("Request: " + request);
PrintWriter p = new PrintWriter(s.getOutputStream());
p.println("Hello, fileclient!");
System.out.println("Message sent!!");
p.close();
br.close();
Before I put the line s.shutDownInput()
the server code would hang at br.readLine().
The way I managed to fix that is to close the PrintWriter
some how, either through p.close()
or through the current way which doesn't
shutdown the socket like closing the PrintWriter
through p.close()
does. After that, the interaction between client and server is perfect.
Why does the PrintWriter
or the BufferedReader
not send/receive until the PrintWriter
is closed somehow?
Upvotes: 0
Views: 1174
Reputation: 11
In case someone arrives here six years later, the block below is what allowed me to keep the input & output streams open, and send the bytes to a protocol for parsing:
// KOTLIN
reader!!.available().let {avail ->
if (avail > 0) {
val buffer = ByteArray(avail)
reader!!.readFully(buffer, 0, avail)
protocol!!.readData(buffer)
}
}
Upvotes: 0
Reputation: 310957
It doesn't have anything to do with PrintWriter
. It is an application protocol error on your part.
The server is looping reading lines until end of stream.
The client is sending one line and then not closing the socket, so no end-of-stream got sent (until you added the shutdown).
The server is then responding.
The client is then reading.
So the client doesn't read anything until the server gets out of the loop, and the server doesn't get out of its loop because the client is reading not closing.
So make up your mind. Probably the server should only read one line.
Upvotes: 1
Reputation: 180351
Both sides are behaving exactly as you told them to do. In particular, you instruct the server specifically to read everything the client sends before dispatching any response:
String nextline;
while((nextline = br.readLine()) != null){
System.out.println(nextline);
request.append(nextline);
}
It is important to understand that that will not stop reading until an error or end of stream, where end of stream on a socket corresponds to the other end having been closed and all data having been read. In other words, your server waits for the end of the whole conversation, not the end of a single message, before dispatching a response.
Since that's apparently not what you want, you need to implement a different strategy at the server for determining when to process the data received so far and send a response. If you can be confident that your messages will not contain internal newlines, then that might be as simple as the server performing only one br.readLine()
before sending each response.
Upvotes: 1