Reputation: 955
I'm trying to implement a server (with ability to accept multiple clients) and a client using this tutorial and making some extensions. Everything works fine except for one feature: when the server has been running for 1 minute, it shuts down and each client has to print the message 'server shutting down' and close.
in my analog to KKMultiServer I implement it this way, in the main method:
long in1minute = 10*1000;
Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run() {
for(int i=0;i<startedThreads.size();i++){
try {
startedThreads.get(i).Close();
} catch (IOException e) {
e.printStackTrace();
}
}
listening=false;
}
}, in1minute );
while each started thread was added to the vector.
in my analog to the KKMultiServerThread this code should send the message to the clients (my analog to KKProtocol proceeds it correctly)
public void Close() throws IOException{
String outputLine=p.processInput("shut");
out.println(outputLine);
out.close();
in.close();
socket.close();
}
The Server stops normally, but the clients do not print the message 'server shutting down'. Then, if I invoke the client when server is shut, I get:
[java] Exception in thread "main" java.net.SocketException: Connection rese
tClient: d
[java] at java.net.SocketInputStream.read(SocketInputStream.java:189)
[java] at java.net.SocketInputStream.read(SocketInputStream.java:121)
[java] at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
[java] at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
[java] at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
[java] at java.io.InputStreamReader.read(InputStreamReader.java:184)
[java] at java.io.BufferedReader.fill(BufferedReader.java:154)
[java] at java.io.BufferedReader.readLine(BufferedReader.java:317)
[java] at java.io.BufferedReader.readLine(BufferedReader.java:382)
[java] at ist.assignment2.Client.main(Client.java:31)
[java]
Code for Client.java:31
while ((fromServer = in.readLine()) != null) {
...and then analog to KKClient
So why don't the clients print the message and exit?
Upvotes: 0
Views: 2441
Reputation: 50124
A TCP socket should not be closed, if the other side hasn't acknowledged all data. This mechanism is designed into most application protocols. For example with HTTP, SMTP, IMAP, POP3, the server signals when the connection should be closed, the client closes the socket and afterwards the server closes the socket.
In your case, you can extend your Close
method as follows:
public void Close() throws IOException {
String outputLine = p.processInput("shut");
out.println(outputLine);
// signal the client that the connection should be closed
socket.shutdownOutput();
// wait on ack by blocking until EOF is received
if (in.read() != -1) {
throw new RuntimeException("unexpected data sent by client");
}
// close socket
socket.close();
}
Upvotes: 3