3

アプリケーション

ObjectStream クラスを使用してソケットを介してオブジェクトを送信することで通信するクライアント/サーバー アプリケーションを Java で作成しています。アプリケーションの各ノードは、おおよそ次のようになります。

class Node {
  SocketServer server;
  Socket[] clients;
}

ここで、server変数はこのノードがリッスンするソケットであり、client変数は他のノードがリッスンし、このノードがオブジェクトを送信するソケットです。

クライアント ソケットの 1 つにオブジェクトを書き込むために使用するコードは、次のようになります。

void sendMessage(Message<B, F> msg) throws IOException {
    ObjectOutputStream writer = getWriter();
    writer.writeObject(msg);
    writer.flush();
}

private ObjectOutputStream writer;

ObjectOutputStream getWriter() throws IOException {
    if (writer == null)
        writer = new ObjectOutputStream(
            new BufferedOutputStream(client.getOutputStream()));
    return writer;
}

接続を処理し、ノードのサーバー ソケットからオブジェクトを読み取るために使用するコードは、次のようになります。

// the handler will listen for connections
final Thread handler = new Thread(new Runnable() {

    public void run() {
        try {
            // create a new thread to handle the client
            final Socket client = server.accept();
            final Thread thread = new Thread(new Runnable() {

                public void run() {
                    final ObjectInputStream reader;
                    try {
                        reader = new ObjectInputStream(client.getInputStream());
                        while (true) {
                            try {
                                val msg = reader.readObject();
                                messages.add((Message<B, F>) msg);
                            }
                            catch (EOFException e) {
                                // i noted it seemed to throw eofexceptions
                            }
                            catch (IOException e) {
                                // do something
                            }
                        }
                    }
                    catch (IOException e) {
                        // do something
                    }
                }
            });
          thread.start();
        } catch (IOException e) {
            // do something
        }
    }
});
handler.start();

問題

ここのソケットに何か問題があると思います。すべてのサーバーが単一のクライアントにのみ接続されている場合、すべてが正常に機能します。ただし、複数のクライアントが同じサーバーと通信している場合、事態は悪化し、ObjectInputStream から StreamCorruptedException が発生し、その他の奇妙な動作 (UpdateRequest メッセージのインスタンスを挿入し、Integer(0) のインスタンスといくつかの例外を取得する) が発生します。例えば。)

私の直感では、2 つのオブジェクト/バイト ストリームが何らかの形で混ざり合っており、オブジェクトを逆シリアル化しようとすると奇妙な結果が生じることがわかります。私の質問は、なぜこれが起こっているのか、何が間違っているのか、どうすれば修正できるのでしょうか?

4

2 に答える 2

1

ソケットの配列はありますが、ライターとリーダーの配列はないようです。したがって、すべての接続で同じライターとリーダーを使用している可能性があります。

Runnable を実装し、ソケット、ライター、およびリーダーをインスタンス メンバーとして持つ、接続ごとの Connection オブジェクトが必要です。

また、EOFException をキャッチした場合は、ループから抜け出してライターを閉じる必要があります。

于 2011-06-25T00:27:10.423 に答える
0

この問題は、メッセージが同時に送信されたことが原因で発生しており、その結果、バイトが混在していました。解決策は、メッセージが一度に 1 つだけ受信されるようにすることでした。

于 2011-08-03T13:40:29.400 に答える