1

サーバーとクライアントのプログラミングにOracleのKnockKnockの例を使用しています。これにより、クライアントがサーバーに接続すると、KnockKnockジョークを受信して​​対話します。すべてが順調に進んでいます。

私の質問は、クライアントが完了してサーバーから切断されると、サーバープログラムも終了することです。サーバーが終了した場合、サーバー側を手動で再起動せずに別のクライアントの要求を受け入れることができるように、サーバーを再度自動実行するにはどうすればよいですか?

以下は私のコードで、コメントは私が立ち往生している場所を示しています。vmwareプレーヤーで実行されている2つのcentosvmを使用しています。

import java.net.*;
import java.io.*;

public class KnockKnockServer {
    public static void main(String[] args) throws IOException {
    server(); 
    /*HERE IS WHERE I AM STUCK
     * If I call server() above in my main method everything runs great.
     * However, I would like to put a timer or something inside main so that 
     * every second it checks to see if server() is still running and if not
     * then start it up again.
     */
    }


    public static void server() throws IOException{
    ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Accept failed.");
            System.exit(1);
        }

        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(
                clientSocket.getInputStream()));
        String inputLine, outputLine;
        KnockKnockProtocol kkp = new KnockKnockProtocol();

        outputLine = kkp.processInput(null);
        out.println(outputLine);

        while ((inputLine = in.readLine()) != null) {
             outputLine = kkp.processInput(inputLine);
             out.println(outputLine);
             if (outputLine.equals("Bye."))
                break;
        }
        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();
    }
}
4

2 に答える 2

2

serverSocket1つの接続を処理した後、を閉じます。

serverSocket.close();

これを維持し、受信したクライアント接続をワーカースレッドに渡す必要があります。

あなたのmain方法では、次のようになります。

while (serverIsActive) {
   clientSocket = serverSocket.accept();
   new ClientWorker(clientSocket).launch();
}

ClientWorkerRunnableクライアント接続を処理します。

public class ClientWorker implements Runnable {

public ClientWorker(Socket clientSocket) {
   this.clientSocket = clientSocket;
}

public void launch() {
   new Thread(this).start();
}

@Override
public void run() {
   PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
   ...
于 2012-10-17T21:25:40.480 に答える
2

接続処理コードを追加のスレッドに移動できます(KnockKnockHandlerと呼びます)。

public class KnockKnockHandler extends Thread {
    private Socket socket;
    public KnockKnockWorker(Socket socket) {
       this.socket = socket;
    }
    public void run() {
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
            new InputStreamReader(
            socket.getInputStream()));
        String inputLine, outputLine;
        KnockKnockProtocol kkp = new KnockKnockProtocol();

        outputLine = kkp.processInput(null);
        out.println(outputLine);

        while ((inputLine = in.readLine()) != null) {
             outputLine = kkp.processInput(inputLine);
             out.println(outputLine);
             if (outputLine.equals("Bye."))
                break;
        }
        out.close();
        in.close();
        socket.close();
    }
}

誰かがサーバーに接続したら、KnockKnockHandlerの新しいインスタンスを作成して起動します。

try {
    clientSocket = serverSocket.accept();
    KnockKnockHandler handler = new KnockKnockHandler(clientSocket);
    handler.start();
} catch (IOException e) {
    System.err.println("Accept failed.");
    System.exit(1);
}

これをループに入れると、サーバーがシャットダウンすることはありません(例外がスローされるか、JVMが終了する場合を除く;-)):

while(true) {
    try {
        clientSocket = serverSocket.accept();
        KnockKnockHandler handler = new KnockKnockHandler(clientSocket);
        handler.start();
    } catch (IOException e) {
        System.err.println("Accept failed.");
        System.exit(1);
    }
}

クライアントが接続すると、サーバーは新しいスレッドを開始し、ループの次の反復に入り、次のクライアントが接続するのを待ちます。

于 2012-10-17T21:37:55.810 に答える