0

サーバーはこのコードをスレッドで実行するため、クライアントが接続するのを待っている間に GUI を操作できます (現在、1 つのクライアントと 1 つのサーバーしか使用していません)。

@Override
public void run() {

    Socket client = null;
    MessageListener listener = null;

    try {
        client = server.accept();
        oos = new ObjectOutputStream(client.getOutputStream());
        ois = new ObjectInputStream(client.getInputStream());
        listener = new MessageListener(ois);
        (new Thread(listener)).start();

    } catch (IOException e) {
        e.printStackTrace();
    }
}

クライアントはこのコードを 1 回実行してサーバーに接続し、入出力ストリームを修正します。

try {
        ois = new ObjectInputStream(server.getInputStream());
        MessageListener listener = new MessageListener(ois);
        oos = new ObjectOutputStream(server.getOutputStream());
        (new Thread(listener)).start();
    } catch (IOException e) {
        e.printStackTrace();
    }

MessageListener はスレッドを実行して、着信メッセージをチェックします。

@Override
public void run() {
    while (true) {
        Message message = null;
        try {
            message = (Message) in.readObject();
            if (message != null) {
                System.out.println(message.getName());
            }
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }

    }
}

ただし、プログラムを起動すると、最初はサーバーからクライアントにしか送信できず、その逆はできません (クライアント GUI と対話することはできません)。サーバーからクライアントに最初のメッセージを送信すると、次のエラー メッセージが表示されます。

java.io.StreamCorruptedException: invalid type code: 6F
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.jale.chat.iohandling.MessageListener.run(MessageListener.java:25)
at java.lang.Thread.run(Unknown Source)

編集:最初のエラー メッセージを受け取った後、クライアントからサーバーにのみ送信できます (送信は実際に機能します) が、エラー メッセージがコンソールにスパムを送信し続けます。

MessageListener の 25 行目:

message = (Message) in.readObject();

google/Stack Overflow では何も見つかりませんでした。取得時の一般的な問題は、人々が複数または単一のソケットをStreamCorruptedException開く場合にあるようですが、私は行っていません。どんな助けでも大歓迎です。InputStreamsOutputStreams

4

3 に答える 3

1

入力/出力ストリームを複数回開いた可能性があると思います。connect-Function が 1 回だけ呼び出されることを確認してください。

于 2013-05-23T13:18:04.407 に答える
1

あなたはそれらを構築ObjectOutputStreamsしてから捨てています。それらは のコンストラクターに渡される必要がMessageListenerあるObjectInputStreams,ため、クライアントごとに有効なものを書き込む必要があります。現在のコードのように、ピアに正しく書き込むことはおそらくできません。おそらく、ObjectOutputStreamどこかで間違ったピアに を再利用しています。

作成する変数ObjectInputStreamObjectOutputStream変数は、周囲のクラスのメンバーではなく、メソッドに対してローカルである必要があります。実際、これらのストリームは両方とも、ループ内run()でインライン化するのではなく、開始しようとしているスレッドのメソッドで構築する必要があります。accept()そうしないと、間違った場所でブロックする危険があります。そして、デッドロックを不可能にするためObjectOutputStreamに、常に の前に を構築する必要があります。ObjectInputStream

于 2013-05-23T00:12:31.933 に答える
-1

うーん、クライアント/サーバー側の両方で同じクラス (id 付き) を使用する必要があります。クライアント/サーバープロジェクトの両方で使用されるライブラリにメッセージメカニズムを入れました。さらに、サーバー/クライアントをコンパイルする場合は、3 つのプロジェクトすべてをコンパイルします。これが役立つかもしれません。

于 2013-05-22T20:43:46.097 に答える