4

Android から大きなファイルをソケット経由でサーバーに送信したいのですが、サーバーが受信したファイルが不完全です。

アンドロイドのコード:

 Socket client = new Socket(ipStr, 4444);
 OutputStream  outputStream = client.getOutputStream();
 FileInputStream fileInputStream = new FileInputStream(file);
 BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); 
 byte[] buffer = new byte[512];
 byte[] sendLen = getBytes(file.length(), true);
 outputStream.write(sendLen);   
 outputStream.flush();

 int count;

 while ((count = fileInputStream.read(buffer)) > 0)
 {
    outputStream.write(buffer, 0, count);
 }

 outputStream.flush();
 bufferedInputStream.close();
 outputStream.close();
 client.close(); 

サーバー上のコード:

byte[] recvHead = new byte[8];
inStream.read(recvHead, 0, 8);
long recvLength =  getLong(recvHead, false);
FileOutputStream file =  new FileOutputStream(fileName, false);
byte[] buffer = new byte[8192];
int count = 0;

while (count < recvLength) {
    int n = inStream.read(buffer);                  
    if(n == -1)
        break;
    file.write(buffer, 0, n);
    count += n;                 
}   

ただし、サーバーは read(buffer) でブロックします (android が送信したファイルは約 30M です)。

奇妙なことは次のとおりです 。 file の送信中に file に出力を追加すると、サーバーは正常に動作します。

 FileOutputStream file2 =  new FileOutputStream("/sdcard/testfile" , false);


 while ((count = fileInputStream.read(buffer)) >= 0)
 {
     outputStream.write(buffer, 0, count);
     outputStream.flush();

     file2.write(buffer, 0, count);
     file2.flush();

 }

誰でもこれで私を助けることができますか?ありがとうございました!

4

1 に答える 1

1

そのように 8 バイトの長さを読み取るとは想定できません。長さ配列に 1 バイトを読み込むこともできます。そのために DataInputStream.readLong() を使用し、それを書き込むために DataOutputStream.writeLong() を使用します。または、1 つのファイルの後に閉じるときに、長さワードを完全に取り除き、EOS まで読み取るだけにします。

コードの残りの部分は問題ないようです。受信者が read() でブロックした場合でも、データは受信中であり、送信者はまだ送信中です。

于 2012-10-25T05:24:48.970 に答える