独自のデータを完全に異なるデバイス上の別のインストールのデータと同期できるようにする必要があるアプリに取り組んでいます。リモート デバイスは、Android、iOS、または Windows である可能性があり、問題なく同期するはずです。全体的にかなり標準的なもの。アイデアは、1 つのデバイスが他のデバイスのデータの要求を送信し、それをコンパイルして送り返すことです。次に、最初のデバイスがそれを処理し、必要なものをローカルに保存してから、2 番目のデバイスが持っていない独自のデータを送信します。 2 番目のデバイスに移動します。
IP 用の UDP ブロードキャストを使用してから、XML over TCP ソケットを使用して、かなりうまく動作させました。それについて特別なことは絶対にありません。
残念ながら、特定のケースでは機能しません。具体的には、iOS デバイスとの通信です。ここには 2 つの特定のケースがあります。上記の説明で Android が最初のデバイス (クライアント) として機能する 1 つ目は、完全に機能します。全く何の問題もありません。しかし、Android が 2 番目のデバイス (サーバー) として機能する 2 番目のデバイスは、最終転送で失敗します。
iOS デバイスからの送信を一度しか読み取れず、二度と読み取れないかのように動作します。読み取ることができるのはソケットごとの最初の書き込みだけですが、tcpdump ログなどからわかることから、データはiOS デバイスによって tcp スタックに書き込まれています。Android フラットアウトは、そこにあることを登録しません。単純な socket.getInputStream().read() は、データを待機して無限にハングアップします。
iOS が Windows と同期しようとすると、これと同じ問題が発生するため、iOS ソケットが邪魔になっているある種の厄介な Apple シェナニガンを行うという漠然とした疑いを超えて、問題が何であるかはわかりません。
このような問題に遭遇したことがあり、それを解決する方法を知っている人はいますか? それとも、方程式のどちら側が問題を引き起こしているのかを知っているだけでしょうか?
事前にどうもありがとうございました。
コメントの人々が尋ねたので、ここにいくつかのコードがあります:
server = new ServerSocket(portNum);
socket = server.accept();
byte[] lenBuffer = new byte[4];
socket.getInputStream().read(lenBuffer, 0, lenBuffer.length);
int lengthToRead = ByteBuffer.wrap(lenBuffer).order(ByteOrder.LITTLE_ENDIAN).getInt();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder buffer = new StringBuilder();
int totalReadSoFar = 0;
String line;
while( totalReadSoFar < lengthToRead && (line = reader.readLine()) != null ){
buffer.append(line);
totalReadSoFar += line.getBytes().length + 1;
}
if( buffer.toString().equals("syncCommand") )
syncOverSocket(socket);
そしてsyncOverSocketはここにあります:
String xml = buildXml(outSyncData);
byte[] encryptedData = encryptXml(xml, localPin);
encryptedData = Base64.encode(encryptedData, Base64.NO_WRAP);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
ByteBuffer byteBuffer = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
byteBuffer.putInt(encryptedData.length);
byte[] bytes = byteBuffer.array();
dataOutputStream.write(bytes);
dataOutputStream.write(encryptedData);
dataOutputStream.flush();
byte[] lenBuffer = new byte[4];
socket.getInputStream().read(lenBuffer, 0, lenBuffer.length);
int lengthToRead = ByteBuffer.wrap(lenBuffer).order(ByteOrder.LITTLE_ENDIAN).getInt();
byte[] finalResult = new byte[0];
byte[] buffer = new byte[1024];
int totalReadSoFar = 0;
int justRead;
while( totalReadSoFar < lengthToRead && (justRead = socket.getInputStream().read(buffer, 0, 1024)) > -1 ){
finalResult = concat(finalResult, buffer, justRead);
totalReadSoFar += justRead;
}
問題は最後の「socket.getInputStream().read(lenBuffer, 0, lenBuffer.length);」です。エラーなしでその行に到達し、データを待機して永久にハングします。iOSデバイスが正しく送信していないか、Androidデバイスがソケットから正しく読み取っていないため、何かがデータの通過を妨げていますが、正直なところわかりません。