2

まず第一に、混乱しないように説明する方法がよくわからないので、簡単にしようと思います。2 プレーヤー ゲームの一部として、2 つのクライアントを "ペアリング" するサーバー アプリがあります。最初のクライアントがサーバーに接続すると、ソケット接続が受け入れられ、そのクライアントで新しい ClientProtocol スレッドが作成されますが、開始されません。別のクライアントがサーバーに接続すると、そのクライアントは前のスレッドに追加され、スレッドが開始されます。スレッドは、クライアントごとに 1 つずつ、2 つの入力ストリームと 2 つの出力ストリームを認識します。ただし、クライアント側またはサーバー側から読み取ろうとしても何も起こりません。これは、単一のスレッドで単一のクライアントに対して正常に機能します。ここにいくつかのコードがあります:

サーバー側 (メインスレッド)

public static Queue<ContestProtocol> contesters;

public static void main(String[] args) throws IOException {
    ServerSocket serverSocket = null;
    contesters = new LinkedList<ContestProtocol>();

    try {
        serverSocket = new ServerSocket(4444);
    } catch (IOException e) {
        System.err.println("Could not listen on port: 4444.");
        System.exit(-1);
    }

    while (true) {
        Socket socket = serverSocket.accept();

        ObjectInputStream ois;
        ObjectOutputStream oos;

        try {
            ois = new ObjectInputStream(socket.getInputStream());
            oos = new ObjectOutputStream(socket.getOutputStream());

            synchronized (contesters) {
                if (contesters.size() == 0) {
                    Contester contester1 = new contester(ois, oos);
                    contesters.add(new ContestProtocol(contester1));
                } else {
                    Contester contester2 = new Contester(ois, oos);
                    contesters.poll().hook(contester2).start();
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

サーバー側 (ContestProtocol)

private Contester contester1, contester2;

public ContestProtocol(Contester contester1) {
    super("ContestProtocol");
}

public ContestProtocol hook(Contester contester2) {
    this.contester2 = contester2;
    return this;
}

public void run() {
    try {
        contester1.getOOS().writeInt(-1);
        contester2.getOOS().writeInt(-2);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

サーバー側 (コンテスト):

public Contester(ObjectInputStream ois, ObjectOutputStream oos) {
    this.ois = ois;
    this.oos = oos;
}

public ObjectInputStream getOIS() {
    return ois;
}

public ObjectOutputStream getOOS() {
    return oos;
}

クライアント側:

try {
            socket = new Socket(serverAddr, 4444);
            oos = new ObjectOutputStream(socket.getOutputStream());
            ois = new ObjectInputStream(socket.getInputStream());
            int selectedChampion = ois.readInt();
} catch (Exception e) {
                e.printStackTrace();
}

ContestProtocol スレッドは問題なく実行を終了しますが、両方のクライアントが readInt() でハングします。私はなぜなのか理解していない。

4

2 に答える 2

0

クライアント側の入力ストリームをループする必要があります。

while(true){
if(ois.avaible() > 0)
ois.readInt();
}

ヒント:パフォーマンスを向上させるには、nettyを使用した非同期ネットワークを調べてください。

于 2012-04-25T14:42:48.570 に答える
0

これは、リソースにアクセスする際にミューテックスまたはセマフォの問題を解決する必要があります。使用しているストリーム (この場合は出力ストリームと入力ストリーム) は、同じリソースの読み取りと書き込みを試みています。これらのプロセスはすべて 1 つのスレッドで継続的に実行されるため、それらのスレッドは互いに割り込み、互いに待機プロセスを作成します。
1 つの解決策は、ストリーム オブジェクトにイベント リスナーを登録することです。これにより、一方が終了すると、他方のみが開始されます。

于 2012-04-25T15:02:18.920 に答える