0

PC(サーバー側)から、C#.Netアプリケーションは22000バイトのデータをWi-Fi経由でAndroidデバイス(クライアント側)に送信する必要があります。しかしdataInputStream、Androidデバイスでは2048バイトしか表示されていません。

dataInputStream = new DataInputStream(workerSocket.getInputStream());
byte[] rvdMsgByte = new byte[dataInputStream.available()];
for (int i = 0; i < rvdMsgByte.length; i++)
    rvdMsgByte[i] = dataInputStream.readByte();
String rvdMsgStr = new String(rvdMsgByte);

私は次のことと混同しています:

  1. PCは2048バイトのデータしか送信できませんか?
  2. または、Androidデバイスにはデータを受信するための2048バイトの容量しかありませんか?
  3. または、dataInputStreamデバイスがすべてのバイトを受信した後でも、2048バイトしか表示されませんか?

    (data_received <= 2048バイト)上記のコードは完全に機能します。

4

1 に答える 1

5

基本的には使用しないでくださいInputStream.available()これは、現在利用可能なデータの量を示しています。まだネットワーク経由で送信されている場合は、メッセージ全体ではない可能性があります。

ストリームがメッセージの最後で終了する場合は、ループを続けて、完了するまで一度に1つのブロックを読み取る必要があります(できれば、一度に1バイトを読み取るだけではありません)。例えば:

byte[] readFully(InputStream input) throws IOException {
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[8 * 1024]; // 8K buffer
    int bytesRead;
    while ((bytesRead = input.read(buffer)) > 0) {
        output.write(buffer, 0, bytesRead);
    }
    return output.toByteArray();
}

ストリームをメッセージに分割する必要がある場合は、その方法を検討する必要があります。通常、データの前に「メッセージ長」プレフィックスを送信するのが最適なオプションです。

すべてのデータを読んだら、これを行うべきではありません。

String rvdMsgStr = new String(rvdMsgByte);

プラットフォームのデフォルトのエンコーディングを使用して、バイトをテキストに変換します。これが純粋にテキストデータである場合は、エンコーディングを明示的に指定できる文字列コンストラクタのオーバーロードを使用する必要があります。

純粋にテキストデータでない場合は、そのように扱うべきではありません。本当に文字列として表現する必要がある場合は、base64を使用してください。

DataInputStreamまた、私が知る限り、ここで使用する必要はないことに注意してください。

于 2012-06-27T07:35:16.960 に答える