0

我正在尝试使用本教程实现一个服务器(能够接受多个客户端)和一个客户端并进行一些扩展。一切正常,除了一个功能:当服务器运行 1 分钟时,它会关闭,每个客户端都必须打印消息“服务器正在关闭”并关闭。

在我对KKMultiServer的模拟中,我以这种方式实现它,在主要方法中:

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 );

而每个启动的线程都被添加到向量中。

在我对KKMultiServerThread的模拟中,此代码应将消息发送给客户端(我对KKProtocol的模拟正确地进行)

public void Close() throws IOException{
    String outputLine=p.processInput("shut");
    out.println(outputLine);
    out.close();
    in.close();
    socket.close();
}

服务器正常停止,但客户端不打印消息“服务器正在关闭”。然后,如果我在服务器关闭时调用客户端,我会得到:

     [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]

代码Client.java:31

 while ((fromServer = in.readLine()) != null) {

...然后模拟到KKClient

那么为什么客户端不打印消息并退出呢?

4

1 回答 1

2

如果对方尚未确认所有数据,则不应关闭 TCP 套接字。这种机制被设计到大多数应用程序协议中。例如对于 HTTP、SMTP、IMAP、POP3,当连接应该关闭时,服务器会发出信号,客户端会关闭套接字,然后服务器会关闭套接字。

在您的情况下,您可以Close按如下方式扩展您的方法:

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();
}
于 2013-07-16T19:30:21.587 回答