5

現在、ネットワーク上の別の TCP ベースのデバイスに生データを簡単に送受信するためのアプリを Blackberry で作成しています。MDS シミュレーターを実行し、会社の MDS サーバーと通信する物理電話を使用している Blackberry シミュレーターでも同じ問題が発生しています。この問題は、MDS 経由ではなく Wi-Fi を直接使用する場合には発生しないことに注意してください。

問題は、最初に read() を呼び出さない限り、InputStream の available() 関数がゼロを返すことです。最初に read を呼び出すと (使用可能なデータがあることを知って..wireshark に感謝します)、データが返され、その後に available() を呼び出すと、読み取れなかったデータが残っていることが示されます。問題は、データが存在することが常に保証されるとは限らないため、ブロックされる可能性があることです。誰かがこれを認識していますか?これは問題ですか、それとも設計上のものですか?

read() メソッドが available とは別に呼び出す前にブロックされるかどうかをテストする方法を知っている人はいますか?

これが基本的に私がやっていることです:

SocketConnection s = (SocketConnection)Connector.open("socket://1.2.3.4:port;deviceside=false", Connector.READ_WRITE);

OutputStream o = ((StreamConnection)s).openOutputStream();
InputStream i = ((StreamConnection)s).openInputStream();

o.write("こんにちは");
Thread.sleep(いつか);
if (i.available() > 0) {
   バイト[] データ = 新しいデータ[10];
   int bytesRead = i.read(データ);
   System.out.println("Read [" + new String(data) + "] (bytes = " + bytesRead + ")");
}

これが機能するには、条件付きの if をコメントアウトする必要があります。

4

2 に答える 2

3

InputStream.available() メソッドの一般契約は、「この入力ストリームのメソッドの次の呼び出し元によってブロックされることなく、この入力ストリームから読み取る (またはスキップする) ことができるバイト数を返す」ことです。したがって、ほとんどの実装では、読み取られているストリームの Content Length が返される保証はありません。したがって、次のように読むとよいでしょう。

byte[] readFromStream(InputStream is) throws IOException
{
    byte[] data = new byte[4096];
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);

    int count = is.read(data, 0, data.length);
    while (count != -1)
    {
        dos.write(data, 0, count);
        count = is.read(data, 0, data.length);
    }

    data = baos.toByteArray();

    return data;
}

readFromStream() メソッドを呼び出して、返された byte[] を取得します。

于 2009-08-24T06:39:52.287 に答える
0

上記のコメントで示したように、接続しているデバイスがそこにないかどうかを判断する方法が必要でした。これは、「ping」がデータを返すかどうかを確認することによって行います。デバイスがそこにない場合、ブロックされます。私はその行動に頼ることはできません。これを解決する際に発生したもう 1 つの問題は、必要なデータよりも大きなバッファーを指定すると、RIM InputStream クラスの read(...) メソッドがブロックされることです。しかし、available() が 0 を返す場合、どのくらいのデータがあるかを知るにはどうすればよいでしょうか? バイトごとに読み取ることがこれを行う唯一の方法ですが、データがない場合でもブロックされます。

これに対処するために、最初の回答のテーマに従いましたが、このメソッドを独自のスレッドに配置し、別のバイト バッファーに書き込むようにしました。InputStream を拡張し、available() と read(...) を実装するクラスを作成しました。Available は、バイト バッファーにあるバイト数を返し、read only は、バッファーにある量または呼び出し元が要求した量のいずれか少ない方を返します。

この設定により、InputStream インターフェイスを使用できますが、舞台裏では、接続が切断されるまで継続的に実行されているリーダー スレッドにすぎません。その時点で読み取りがブロックされると、接続が閉じられたことを示すために例外がスローされます。この動作は簡単に処理できるので問題ありません。

この問題に協力してくれた上記のすべての人に感謝します。あなたの思考が解決へと向かいます。

于 2009-09-11T19:13:20.793 に答える