5

私はJavaで書かれたネットワークアプリに取り組んでおり、Socketsの上でObjectOutputStreamとObjectInputStreamを使用してメッセージを交換しています。私のコードは次のようになります。

送信者:

ObjectOutputStream out;
ObjectInputStream in;
try{
     Socket socket=new Socket(address, port);
     socket.setSoLinger(true, socketLingerTime);
     out=new ObjectOutputStream(socket.getOutputStream());
     out.writeObject(message);
     out.flush();
     out.close();
}catch (variousExceptions)...

受信者:

Object incoming;
try{
    incoming=myObjectInputStream.readObject();
}catch (SocketException socketError)
{
    if (socketError.getMessage().equals("Connection reset"))
    {
        //this is the exception I get
    }
}

メッセージが正常に処理される場合もありますが、オブジェクトの代わりにマークされた例外が発生する場合もあります。フラッシュはメッセージを反対側に強制的に通過させることになっているのではありませんか?どういうわけか関数を間違って使用していますか?それとも、これは基盤となるJava / OSネットワークコードのある種のバグですか?

ありがとう!

アップデート:

私はこれについてもう少しスヌーピングを行いました、そしてそれはシステムのリソースが何かによって課税されているときにのみ起こるようです。VirtualBoxの外部で複製することはできませんでしたが、それはVirtualBoxにそもそも多くのリソースがないためである可能性があります。この質問については、さらに詳しく調べていくうちに更新していきます。

4

5 に答える 5

9

この問題はNagleのアルゴリズムが原因であることが判明しました。出力バッファはOS内にあるため、フラッシュの影響を受けませんでした。解決策は、Socket.setTcpNoDelay(true)を使用してNagleのアルゴリズムをオフにし、BufferedOutputStreamを使用してユーザーレベルでメッセージをバッファリングすることです。

于 2012-03-01T13:55:10.890 に答える
3

私の場合、それはばかげた問題ですが、私を4時間無駄にします。outStream.writeln( "");を使用する必要があります。またはoutStream.write(mess + "\ n"); reader.readLine ()は、 '\n'文字が見つかるまで読み取ります。したがって、write()だけでは機能しません。

于 2017-06-17T16:54:14.880 に答える
0

接続ごとに1つのオブジェクトを送信できるはずです。

リソースが整然とクリーンアップされるようにするには、出力ストリームだけでなくソケットも閉じるのが最善です。

close()はflushを呼び出すため、冗長にする必要があります。

SO Lingerを設定しないとどうなりますか?

あなたが受けている実際の例外は何ですか?

于 2011-01-28T15:59:07.693 に答える
0

クライアントからサーバーへのパスにあるルーターの1つにあるファイアウォールが、何らかの理由でRSTを送信しているようです。私はあなたのコードに何か問題があるとは思わない。問題を再現しようとしましたが、再現できませんでした。

于 2011-01-28T19:44:35.600 に答える
0

接続のリセットは、もう一方の端ですでに閉じられている接続への書き込みによって発生する可能性があります。検出は、次のI /Oまたは後続のI/O、たとえば読み取りで発生する可能性があります。つまり、アプリケーションプロトコルのバグが原因である可能性があります。SO_LINGERは役に立ちません、これを台無しにしないでください。

于 2011-01-29T00:32:29.570 に答える