1

BufferedOutputStreamに問題があります。ソケット接続を介してAndroidデバイスからJavaサーバーにkmlファイルを送信したいと思います。(接続は正常です。プログラムの他の部分でPrintWriterとデータを交換することはすでに可能です)

kmlファイルを送信するために、バッファをいっぱいにします。しかし、flush()しても、何も起こりません。

        int lu = inFile.read();
        while(lu != -1){
            out.write(lu);
            lu = inFile.read();
        }
        out.flush();
        inFile.close();

inFileは、kmlファイルを読み取るために使用されるストリームです。ソケットのOutputStreamを使用するBufferedOutputStreamです。

アウトオブジェクトを閉じませんが、閉じたくありません。一度だけ使用しません。そしてこれが問題です...close()メソッドはバッファのデータを送信しますが、ソケットも閉じます。flush()メソッドはバッファのデータを送信しません。

ソケットを閉じずにバッファをフラッシュしたい。

mySocket.shutdownOutput();も使用しようとしました。

        int lu = inFile.read();
        while(lu != -1){
            out.write(lu);
            lu = inFile.read();
        }
        out.flush();
        mySocket.shutdownOutput();
        inFile.close();

この方法では、ストリームを閉じてソケットを開いたままにします。これが私が望んでいることです。しかし、新しい出力ストリームを開こうとすると、例外java.net.SocketException:ソケット出力がシャットダウンされます

では、sokcetを閉じずにバッファをフラッシュする方法は、新しい出力ストリームを開くことができませんか?

4

1 に答える 1

3

Socket.close()両方ともSocket.shutdownOutput()EOSをピアに送信します。ピアはソケットを閉じる必要があります。その後、その方向に閉じたため、ソケットに書き込むことができなくなります。

したがって、ソケットへの書き込みを続行する必要がある場合は、これらの方法のいずれも使用できません。

おそらくあなたが探しているのは、アプリケーションプロトコルメッセージを区切る方法です。少なくとも3つのテクニックがあります:

  1. 各メッセージの前に長さの単語を送信します。
  2. 各メッセージの後に帯域外区切り文字を送信します。つまり、メッセージで発生できないバイトまたはバイトシーケンスです。エスケープ付きのSTX/ETXプロトコルは、この例です。
  3. オブジェクトのシリアル化やXMLなどの自己記述型のメッセージ形式を使用します。STX/ETXもその一例です。
于 2012-05-25T10:18:22.327 に答える