1

インターネット上で実行されるマルチプレイヤー ゲームを作成しようとしています。問題は、ストリームで入力を取得しようとしていて、何らかの理由で 1 つのソケットで 2 つのストリームを作成できないことです。説明します。

Socket s=new Socket("127.0.0.1",5001);
ObjectInputStream obj1=new ObjectInputStream(s.getInputStream());
ObjectInputStream obj2=new ObjectInputStream(s.getInputStream());

このコード スニペットが機能しない理由を説明してもらえますか?

編集: 動作しないコード サンプルの別の例を次に示します。

while (true) {
    try {
        objI = new ObjectInputStream(sock.getInputStream());
        objO = new ObjectOutputStream(sock.getOutputStream());
     }catch(Exception e) {
        e.printStackTrace();
     }
}

編集2:答えてくれてありがとう。オブジェクトをフラッシュしようとしましたが、このエラーが発生し続けます:

java.io.StreamCorruptedException: invalid stream header: 33740003
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at Proccess.run(Proccess.java:22)
at java.lang.Thread.run(Unknown Source)
4

3 に答える 3

6

ストリームはステートフルです。ストリームから読み取る場合、ストリーム内のある位置から読み取ることになり、それによって位置が変更されます。

2 つのもの (2 つのラッパー ObjectInputStreams など) が同時に基になるストリームから読み取っている場合、両方ともストリーム内の位置を変更しようとしますが、どちらも他方が何をしているのかわかりません。したがって、一方から読み取ると位置が変更され、もう一方はストリームが残った場所にあると期待しますが、そうではありません。

この答えを、別々の紙に書かれた単語として受け取り、1 つずつ与えられたと想像してください。しかし、あなたが紙片を読んでいる間に、あなたがそれらを見る前に、他の誰かがそれらのいくつかを持ち去っています - あなたが手に入れたものは意味をなさないでしょう. これが起こっていることです - 一方のストリームがデータの一部を取り除き、もう一方のストリームがデータを再度見ると、その一部が失われ、他のストリームによって消費されます。

着信オブジェクトを読み取る ObjectInputStreamを1 つ用意します。これらのオブジェクトを複数のコンシューマーに公開する場合は、着信オブジェクトを送信するもののコレクションを作成し、それらを反復処理して新しいオブジェクトをそれぞれに渡します。

于 2013-08-11T12:29:21.927 に答える
0

ソケットは全二重管です。1 つの入力ストリームと 1 つの出力ストリームがあります。複数のストリームを持つには、その上に多重化プロトコル (TCP) を構築する必要があります。

于 2013-08-11T09:47:48.967 に答える
0

エラー メッセージを知らなくても、コードで起こるべきことは、常に同じ入力/出力ストリームを取得することであり、ObjectInputStream. これは、何らかの理由で、新しく作成されObjectInputStreamた が対応する と通信する必要がObjectOutputStreamあり、接続を待機するためです。私は常に次のコードを使用します。

Socket socket = new Socket("localhost", 12345);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());

flushソケットの反対側の入力ストリームへの呼び出しで、満足して続行します。

Edit2 に関する EDIT: 2 番目の ObjectOutputStreams が、最初の InputStream が読み取るストリームにメタデータを書き込むように見えます (またはその逆)。そのメタデータは不整合として解釈され、例外がスローされます。実際には、ソケットごとに 1 つの入力ストリームと 1 つの出力ストリームのみを開き、それぞれに 1 つの ObjectStream をオーバーレイする必要があります。より多くのストリームが必要な場合は、より多くのソケットを開きます。システムによっては、同時に数 100 個を開くことができます (本当に必要な場合は...)。

于 2013-08-11T09:48:07.043 に答える