1

AndroidとIOS間のソケット接続の実装に少し問題があります。アプリケーションを使用して2つのAndroidを実行しているデバイスを接続している間、すべてが正常に機能します。しかし、iPhoneアプリからデータを受信する必要がある場合、readStream関数がブロックされ、他の部分がソケットを閉じた後、すべてのデータを受信できます。そうすると、応答を返すことができなくなります。これが私が聞くために使っているものです:

try {
    serverSocket = new ServerSocket(5000);
    Log.d("","CREATE SERVER SOCKET");
} catch (IOException e) {
     e.printStackTrace();
}

while(state){
    try {
        if(serverSocket!=null){
            client = serverSocket.accept();
            client.setKeepAlive(true);
            client.setSoTimeout(10000);

            // LOGS
            Log.w("READ","is connected : "+client.isConnected());
            Log.w("READ","port : "+client.getPort());
            Log.w("READ","ipadress : "+client.getInetAddress().toString());



            InputStream is = client.getInputStream();

            Log.w("READ","is Size : "+is.available());

            byte[] bytes = DNSUtils.readBytes(is);
            Log.v("","-------------------------");
            for(int i=0;i<bytes.length;i++){
                Log.w("READ","bytes["+i+"] : "+bytes[i]);
            }
            Log.v("","-------------------------");

            try {
                Log.w("READ","packetType : "+bytes[4]);

                if(bytes!=null)
                    DNSUtils.getPacketType(bytes[4], bytes, client);

            } catch(Exception e){
                e.printStackTrace();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        Log.v("","IOException");
        ResponseERR pack = new ResponseERR();
        ResponseERR.errorMsg = "Socket TimeOut exception!";
        byte[] packet = pack.createNewPacket();

        try {
            if(client!=null){
                OutputStream out = client.getOutputStream();
                out.write(packet);
                out.flush();
                client.shutdownOutput();
                client.close();
                Log.e("READDATAFROMSOCKET","ResponseERR Send.");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}

これが私が変換するために使用している関数InputStreamですByte Array

public static byte[] readBytes(InputStream inputStream) throws IOException {
    // this dynamically extends to take the bytes you read
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();

    // this is storage overwritten on each iteration with bytes
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];

    // we need to know how may bytes were read to write them to the byteBuffer
    int len = 0;
    while ((len = inputStream.read(buffer)) != -1) {
        byteBuffer.write(buffer, 0, len);
    }

    // and then we can return your byte array.
    return byteBuffer.toByteArray();
}

両方のiPhone/Androidアプリは次のように機能します。

  • まず、ソケットを作成して他のデバイスにデータを送信し、OutputStreamを閉じます。
  • 2番目の部分は、バイト配列を解析してから、同じソケットを使用して応答を返します。

ブロックせずに入力ストリームを読み取れるように関数を変更する方法はありますか?

編集:

したがって、問題はIOS側にあり、Apple APIは作成されたソケットの両方のストリームを閉じる必要があるようです:バイト配列を送信できるように読み取り/書き込み、これは本当にばかげているようです。そのようにすると、iphoneアプリは受信できなくなりますそして私の応答を解析します。

4

2 に答える 2

1

あなたの編集のコメントに反して、それはあなたのせいであり、Apple のせいではありません。API を再設計する必要があります。メソッドreadBytes()はストリームを最後まで読み取ります。これは、ピアが接続を閉じたときにのみ発生します。いくつかのバイトを読みたいだけの場合は、read(byte[])すでにそれを行っており、ストリームの終わりを必要とせずに何バイトかを教えてくれます。私はこの方法を捨てるだけです。

于 2014-08-19T22:27:05.603 に答える
0

RIM OS のプログラミングの経験から、これらすべての IO 操作は別のスレッドで実行する必要があると思います。メイン UI スレッドは、invokeLater() タイプのメソッドを使用して別のアプリケーション スレッドを呼び出すように求められます。このメソッドでは、非同期操作が完了したかどうかを確認し、適切なアクションを実行します。そうすれば、入力ストリームを読み取るコードを別のスレッドで実行する必要があります。

于 2012-08-21T11:04:45.407 に答える