7

私の質問は、問題をグーグルで調べながら読んだときにこれらを信じているため、真実であることを願っている次の仮定にあります。

  1. ソケットの OutputStream を閉じると、ソケットも閉じます
  2. OutputStream の flush() メソッドは何もしません

したがって、基本的に、アプリが機能するためには、OutputStream オブジェクトからデータをフラッシュする必要があります。

詳細に興味がある場合は、次の 2 つのリンクを参照してください。

. 奇妙な動作: Android フォンから Java サーバーに画像を送信する (コードが機能する)

この問題は、OutputStream を閉じることで解決されました。それを行うと、すべてのデータがソケットの反対側にフラッシュされ、アプリがさらに機能するようになりましたが、この修正によりすぐに問題番号 2 が発生しました。対応するソケットも閉じられます。

. SocketException - isConnected() が true を返しても「ソケットが閉じられています」

4

7 に答える 7

6

close の代わりに、OutputStream の flush メソッドを呼び出すことができます。OutputStream から継承する具象クラスは、flush() をオーバーライドして、何もしない以外のことを行います (データをファイルに書き込むか、ネットワーク経由で送信します)。

于 2012-04-15T22:31:56.527 に答える
3

OutputStream の flush() メソッドは何もしません。

これは正しくありません。

クラスflush()によって提供されるの基本実装が何もしないことは事実です。OutputStreamただし、アプリは、使用している実際のストリーム クラスによって提供されるメソッドのバージョンを呼び出します。ストリーム クラスに直接書き込みセマンティクスがない場合は、オーバーライドflush()して必要なことを行います。

つまり、フラッシュが必要な場合 (およびソケット出力ストリームに必要な場合)、呼び出しflush()は正しいことを行います。(インターネットの情報源がそうでないと言っている場合、それは間違っているか、誤解しています。)


参考までに、ベースがノーオペレーションとしてOutputStream実装される理由は次のとおりです。flush()

  • 一部の出力ストリーム クラスは、フラッシュ時に何もする必要はありません。ByteArrayOutputStreamなど_
  • flush()no-op ではないストリーム クラスの場合、基本クラス レベルで操作を実装する方法はありません。

彼らは (理論的には) ストリーム API を設計して、それをOutputStream抽象クラス (およびflush()抽象メソッド) またはインターフェースにすることができたはずです。しかし、この API は Java 1.0 より前に事実上凍結されており、その当時、API 設計が最適ではないことに気付くには、実際の Java プログラミングの経験が十分ではありませんでした。

于 2012-04-16T00:13:02.450 に答える
1

ソケットの OutputStream を閉じると、ソケットも閉じます

真実。

OutputStream の flush() メソッドは何もしません

間違い。オーバーライドがあります。FilterOutputStream.flush()、、、BufferedOutputStream.flush()のJavadoc を参照してくださいObjectOutputStream.flush()

したがって、最初の問題は存在しないため、問題 2 を引き起こす「解決策」は必要ありません。

于 2012-04-15T22:30:48.710 に答える
0

刺してみます。私は同じ問題を抱えていました。出力ストリームを閉じることが、データを「フラッシュ」できる唯一の方法です。しかし、私はまだオプションではない出力ストリームが必要なので。最初に、バイト配列の長さ out.writeInt を送信し、次に配列自体を送信します。すべてのバイトが読み取られたとき、つまり buffer.length == in.readInt() ループを破る

    ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    byte[] fileBytes;
    int n;
    int length;

    try
    {
        size = in.readInt();

        while((n = in.read(buffer)) != -1)
        {
            dataBuffer.write(buffer, 0, n);

            if(dataBuffer.toByteArray().length == length)
            {
                fileBytes = dataBuffer.toByteArray(); break;
            }
        }
    }
于 2013-08-24T17:28:25.897 に答える
0

私も同じ問題を抱えていました。ストリームの末尾に「\n」を追加します。フラッシュは機能しますが、宛先はメッセージが終了したかどうかを知りません

于 2014-01-29T09:04:55.137 に答える
-1

本当に流す必要がありますか?また、c# サーバーのリスナーが android から送信されたデータを受信できないという問題もありました (データを同期的に取得しようとしました)。

これは、Android 側で次のコードがフラッシュされなかったためだと確信していました。

OutputStream str = btSocket.getOutputStream();
str.write(data_byte);
// "This implementation does nothing"
str.flush();

サーバーのリスナーで非同期データ取得を使用すると、データが取得され、クライアント側で flush() は必要ないことが判明しました!

于 2013-04-19T09:19:52.853 に答える