0

チャット サーバーを作成していますが、複数の接続を確立できません。これは、ソケットが 1 つしかないためだと思います。スレッドは一度に複数のソケット接続を処理できることを読みましたが、各クライアントには独自のソケットが必要です。コンセントのように。プラグごとに 1 つのコンセントが必要です。各クライアントがサーバーとの通信に使用するソケットを作成するにはどうすればよいですか? 皆さんの支援の基礎となるコードを少し提供します。ここでは、単一のソケット (接続) が受け入れられます。

 private void waitForConnection() throws IOException
 {
     connection = server.accept();
     showMessage("\nNow connected to " + connection.getInetAddress().toString());
     clientCount += 1;
 }

サーバーの起動時にコードが呼び出される場所は次のとおりです。

public void startRunning()
{
  try
  {
     server = new ServerSocket(1337, 10);
     while(true)
     {
        try
        {
            showMessage("Waiting For a Player To Connect...");
            waitForConnection();
            setupStreams();
            whileChatting();

        }
        catch(EOFException eofException)
        {
           showMessage("\n Server ended the connection! ");
        }
        finally
        {
           closeConnections();
        }
     }
  }
  catch(IOException ioException)
  {
     ioException.printStackTrace();
  }
}

これで、このコードは最初に接続されたクライアントに対して完全に機能します。他のすべては単に接続できません。回答を提出してくれたすべての人に事前に感謝します。

4

3 に答える 3

1

スレッドを常に実行しておく必要がありますsocket.accept()。あれは:

  • socket.accept()( 経由で) クライアントを受け取るときはいつでも、
    • Threadこれからそのクライアントを処理する新しい を開始します。Thread(これを拡張クラスと呼びますClientNanny);
    • そして、socket.accept()再び実行に戻ります。

waitForConnection()メソッドは次のようになります。

private List<ClientNanny> clients = new ArrayList<ClientNanny>();

private void waitForConnection() throws IOException
{
     while (true) { /* or some other condition you wish */
         connection = server.accept(); /* will wait here */
         /* this code is executed when a client connects... */

         showMessage("\nNow connected to " 
                                      + connection.getInetAddress().toString());

         ClientNanny nanny = new ClientNanny(connection); /* call a nanny to take
                                                             care of it */
         clients.add(nanny); /* make sure you keep a ref to it, just in case */
         nanny.start(); /* tell nanny to get to work as an independent thread */
         clientCount += 1; /* you dont need this: use clients.size() now */
     }
}

気付かなかった場合は、ClientNanny次のようになります。

class ClientNanny extends Thread {
    ClientNanny(Socket baby) {
        this.myBaby = baby;
    }
    @Override
    public void run() {
        bed.put(myBaby); /* and probably other commands :) */
    }
}

ここで、以下の強調表示されたコードに気付くはずです...

try
{
    showMessage("Waiting For a Player To Connect...");
    waitForConnection();
    setupStreams();  /* <--------- THIS LINE! HI! I'M A HIGHLIGHT! */
    whileChatting(); /* <--------- THIS LINE! HI! I'M A HIGHLIGHT TOO! */
}

waitForConnection()私が提案したように変更しても実行されません(ループwaitForConnection()内でローリングし続けるため)。while(true)たぶん、あなたはsocket.accept()それを独自のスレッドに入れることができます...とにかく、あなたは今からそれを受け入れることができると信じていますよね?

PS .: 最後の指針として、上記の解決策は、問題を説明する最も簡単な方法としてnew Thread()(またはその点で) を使用しています。ただし、この回答ですぐに指摘されているように、new ClientNanny()非常に最適なソリューションには、(大まかに言えばスレッドプール)の使用が含まれる場合があります。ExecutorService

于 2013-04-16T04:14:49.827 に答える
0

ソケット コードは次の PSEUDO-CODE のようになります。

create server socket
while true (or quit received) {
    accept connection
    spawn thread to handle communication
}

つまり、接続ごとにスレッドを生成する必要があります。その後、各スレッドは、メイン スレッドを保持するのではなく、 whileChatting() を実行できます。

例:

while (true) {
    try {
        // listen for client connections
        Socket s = svr.accept();

        // start a separate thread to handle this client's communications
        new ChatClientHandler(s).start();
    }
    catch (IOException e) {
        // print out the error, but continue!
        System.err.println(e);
    }
}
于 2013-04-16T13:08:19.327 に答える
0

コードの構造全体が間違っています:

waitForConnection();
setupStreams();
whileChatting();

これはあなたが必要とすることをすることはできません。ループは何もせずにスピンし、接続を受け入れてから、そのソケットを介したすべての I/O を処理する各スレッドに対して新しいスレッドを開始する必要があります。Java チュートリアルのカスタム ネットワークのセクションを参照してください。

于 2013-04-16T04:13:58.903 に答える