0

この問題の解決策が見つかりません: Android でプログラムを作成して、写真 (jpg 形式) を撮影し、Bluetooth チャネルを介して Embedded Windows XP PC に送信しました。また、画像を受け取る Windows 用の C++ アプリケーションも作成しました。
通信は、Bluetooth ソケットを使用して実装されます。Android では、アプリは 1024 バイトのチャンクでファイルを読み取り、画像が終了するまですべてのチャンクをソケットに書き込みます。Windows 側では、recv(...) 関数が値 > 0 を返すまで、1024 バイトのチャンクでバイトを読み取ります。

その結果、Android 側ではすべてのバイトが正しく読み取られて送信されたように見えますが、Windows 側では (ほぼ) バイトの 70 ~ 80% しか受信しません。jpg を視覚化できるため、受信した正しいバイトを確認することもできます (画像の下部にある不足しているバイトは灰色で表示されます)。全体像を受け取ることはめったにありません。ここに、Android 側のコードの関連部分を投稿します。

String picturePath = "/sdcard/VERDE/PTR-0_15-31-24.jpg";
File picture = new File(picturePath);
if (picture.exists())
{
    Log.d(TAG, "File " + picture.getAbsolutePath() + " exists!");
    try
    {
        FileInputStream fis = new FileInputStream(picture);
        ostream = socket.getOutputStream();
        byte[] buf = new byte[1024];
        int read = 0;
        int totBytes = 0;
        while ((read = fis.read(buf)) != -1)
        {
            totBytes = totBytes + read;
            ostream.write(buf, 0, read);
            Log.d(TAG, "Image - Read: " + read + " - Total "
                                + totBytes + " bytes!");
        }
        ostream.flush();
        ostream.close();
        fis.close();
    } catch (UnknownHostException ex)
    {
        System.out.println(ex.getMessage());
    } catch (IOException ex)
    {
        System.out.println(ex.getMessage());
    }
} else
{
    Log.d(TAG, "File " + picture.getAbsolutePath()
            + " does not exist!");
}

これは、C++ アプリケーションのコードの関連部分です。

if (_outFile != NULL) 
{
    _outFile.open(result.c_str(), ofstream::binary); //"pic.jpg"
    cout << "File opened!" << endl;
} else 
{
    cout << "Can't open file!" << endl;
}
while ((received = recv(client, buf, sizeof(buf), 0)) > 0) 
{
    cout << "R:" << received << " ";
    if (received > 0) 
    {
        totalBytes += received;
        if (_outFile.is_open()) 
        {
            _outFile.write(buf, received); 
            cout << " (Total: " << totalBytes << " B)" << endl;
        } else
        cout << "Error in recv() function, received bytes = "
                        << received << endl;

    } else 
        cout << "R:" << received << " ";
}

このトピックに関する何十ものブログや投稿を見てきましたが、誰も同様の問題を抱えているようには見えません! アイデアがあれば助けてください!

ありがとう!

4

2 に答える 2

0

コードに問題が見つかりました。
受信側だと思っていたら、送信側のAndroidコードでした。
問題は、すべてのバイトが実際に転送される前にsocket.close()関数が呼び出されたことです。
ソケットを閉じる前に最初に Thread.CurrentThread().sleep(2000) を試してみることに気付きましたが、これは最適化されていません。
最善の方法は、画像が完全に転送されるように、クライアントとサーバー間の制御データ交換の小さなプロトコルを実装することです (ここでは疑似コードの例を示します)。

  1. クライアントは「clientName:pictureName:picLengthInBytes」で認証します
  2. サーバーの応答: "AuthenticationOK"
  3. クライアントは画像バイトを送信します
  4. サーバーチェック:

    if (受信バイト数 == picLengthInBytes)

    返信("写真OK")

  5. 必要に応じて他のクライアント操作を実行します (私の場合 -> 写真を削除)
アプリケーションを閉じるとき、またはスレッドを停止するときにのみ、ソケットを閉じます。

于 2012-08-28T12:51:02.857 に答える
0

私はまったく同じ問題を抱えています(ただし、通常のソケットを使用したブルートゥースの代わりに)。これを修正するのに役立つ何かをすでに見つけましたか? 私はすべてを試しましたが、それでも同じエラーが発生します。

そうでなければ、問題が何であるかがわかったと思いますが、これを解決する方法がわかりません。最後のステップで、転送されたバイト数が 1024 バイト未満の場合、バッファを文字列に割り当て、文字列の長さを計算しましたが、これは最後のステップで受信したバイトよりも小さかったです。データが1024バイト未満の場合、最後のステップで彼がすべてを受け取っていないと思います

于 2012-08-09T17:33:39.407 に答える