-2

クライアントサーバーモードです。サーバーはマルチスレッドを使用してクライアントの要求を処理します。新しいクライアントが特定のサーバーに要求した場合、サーバーはそれを処理するために新しいスレッドを初期化します。ただし、別のサーバーへの要求を初期化するために必要になる可能性があるロジック フローをサーバー スレッドに追加する必要があります。基本的に、サーバー自体は同時にサーバーとクライアントとして動作します。検索に役立ちます。たとえば、クライアントがサーバーに検索要求を送信し、サーバーがローカル ファイルでそれを見つけられない場合、別のサーバーに要求して結果を取得し、クライアントに返すことができます。 .

次のように、サーバー スレッドの run メソッドに request メソッドを追加して、これを実装しようとしています。

// server thread handle request for client
public void run(){
  try{
    // input output stream with client
    PrintWriter out = new PrintWriter(clnt.getOutputStream(), true);
    BufferReader in = new BufferReader( new InputStreamReader( clnt.getInputStream() ) );
    ...
    // try to initial a new request to anther server which is already listening
    reqstAntherServ();
    ...
  }
}

reqstAntherServ メソッド:

public void reqstAntherServ(){
  try{
    // initial a new socket request
    Socket reqstAnthrServ = new Socket(hostname, port);

    // input output stream with anther server
    PrintWriter out = new PrintWriter(clnt.getOutputStream(), true);
    BufferReader in = new BufferReader( new InputStreamReader( clnt.getInputStream() ) );
    ...
  }
}

ただし、実行時に reqstAntherServ メソッドがリクエストを正常に初期化していないように見えることがわかりました。たとえば、サーバー A がメソッドを介してサーバー B をリクエストしたい場合、その結果、既にリッスンしているサーバー B はリクエストを聞いていません。通常、ソケットが作成されたことを示すメッセージがコンソールに出力されます。

それから、スレッドの問題かもしれないと思いました.サーバースレッドは、クライアントとの通信を維持し、同時に新しいリクエストを初期化することはできないと思います. そこで、reqstAntherServ メソッドを別の新しいスレッドに入れようとしました。基本的に、サーバーが別のサーバーにリクエストを送信したい場合、それを処理するために使用される新しいスレッドを作成する必要があります。ただし、どちらも機能しません。

何が問題なのかわからない、またはこのメカニズムを実装する別の方法はありますか? ありがとうございました!

更新しました!reqstAnerthServ メソッドを配置するための最初の新しいスレッドを含めます。私が試したのは、静的クラスをスレッド ハンドラーとして使用し、reqstAnotherServ メソッドの内容を次のように実行メソッドに配置することです。

private static class ThreadRqstAntherServ implements Runnable {
  ...
  public void run() {
    try{
    // initial a new socket request
    Socket reqstAnthrServ = new Socket(hostname, port);

    // input output stream with anther server
    PrintWriter out = new PrintWriter(clnt.getOutputStream(), true);
    BufferReader in = new BufferReader( new InputStreamReader( clnt.getInputStream() ) );
    ...
    }
  }
}

次に、クライアントのサーバー スレッド ハンドラー リクエストで、reqstAntherServ メソッドを直接呼び出す代わりに、上記の ThreadRqstAntherServ を使用して新しいスレッドを初期化します。

// server thread handle request for client
public void run(){
  try{
    // input output stream with client
    PrintWriter out = new PrintWriter(clnt.getOutputStream(), true);
    BufferReader in = new BufferReader( new InputStreamReader( clnt.getInputStream() ) );
    ...
    // try to initial a new request to anther server which is already listening
    Runnable r = new ThreadRqstAntherServ(...);
    Thread t = new Thread(r);
    t.start();
    ...
  }
}

メイン関数には、サーバー プロセス コードの作成も含めます。

public static void main(String[] args) throws IOException{
  try{
    ServerSocket serv = new ServerSocket(port);
    while (true) {
      Socket clnt = serv.accept();
      Runnable rServ = new Threadhandler(clnt, ...); // thread handler for the server thread
      Thread tServ = new Thread(rServ);
      tServ.start();
      ...
    }
  }
}
4

1 に答える 1

-2

問題解決の理由は、サーバー ソケットが同時に 2 つのポートをリッスンするため、2 番目のポートを処理するために追加のスレッドを使用する必要があるためです。そうしないと、通信がブロックされます。

于 2013-10-24T02:47:03.077 に答える