簡體   English   中英

套接字編程:在關閉服務器之前通知所有客戶端

[英]Socket programming: notify all clients before shutting server down

我正在嘗試使用教程實現服務器(具有接受多個客戶端的能力)和客戶端並進行一些擴展。 除了一個功能外,一切正常:當服務器運行1分鍾后,它會關閉,每個客戶端都必須打印“服務器關閉”消息並關閉。

在我對KKMultiServer的模擬中,我用這種方式實現它,在main方法中:

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代碼:31

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

...然后類似於KKClient

那么為什么客戶端不打印消息並退出呢?

如果另一方未確認所有數據,則不應關閉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();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM