0

TCP/IP 経由で通信する Android プロジェクトに取り組んでいます。通信は特定のプロトコルで機能します。このプロトコルはメッセージ指向です。

  1. Androidデバイスはソケット経由でサーバーにメッセージを送信します
  2. サーバーは応答メッセージを Android デバイスに送信します

問題ありませんが、いくつか質問があります。

接続割り込み (wifi、エッジ、開いているソケットを介して wifi をエッジに変更するなど) と接続タイムアウトを解決する方法がわかりません。Android デバイスが 1 つのメッセージを送信し、この瞬間に接続の問題が発生した場合 - Android デバイスが別のメッセージ (他の要求) を送信した場合 - 回答が正しい順序で配信されることが保証されますか?

ソケット オブジェクトのタイムアウトを設定しようとしましたが、うまくいきませんでした。理由はわかりませんが、タイムアウトを 5 秒に設定し、メッセージを送信する前にサーバーの電源を切った場合、彼女が興奮するまでに 5 秒以上かかりました。

この問題に関するインターネット上の記事は見つかりませんでした。

どうもありがとうございました。

4

1 に答える 1

0

TCP ソケットの場合、タイムアウトを取得するには、select() または poll() を使用します。Android では、SocketChannel() ( java.nio) ノンブロッキング ソケットを処理するクラス。どちらも特定の期間 (たとえば 10 秒または 20 秒) ソケットにクエリを実行し、書き込み可能 (send() を使用できます) または読み取り可能 (recv() を読み取るデータがある) かどうかを通知できます。また、select() コマンドは、ソケットにエラーがあるかどうかを通知します。ほとんどの場合、接続が切断されています。このようなエラーが発生した場合 (中断されたシグナルを除き、これは無視して選択を再発行する必要があります)、できることはソケットを閉じてサーバーで新しいソケットを再度開くことだけです。私の知る限り、方法はありません。 、切断された接続を回復しますが、プロトコルに実装している場合は、ソケットが切断されたときに中断したところから再開できます。プロトコルをどのように実装したかはわかりませんが、しかし、それらのほとんどは、別のメッセージに進む前に、受信者からの肯定的な ACK (承認) を必要とします。また、接続を確立するときに、クライアントはそれが新しい接続か壊れた接続かを指定し、それに応じて動作する必要があります。

アイデアは次のとおりです。

送信者は、処理するコマンドと、ヘッダーの後に送信するデータの長さを指定するヘッダーを送信します。受信者はヘッダーとデータを受信し、処理すると、応答 ACK パケットを送信者に送信します。メッセージを確認するための値。必要に応じてデータを追加します。妥当な期間が経過しても ACK パケットを受信しない場合は、肯定的な ACK を受信するまで同じデータを再送信できます。

クライアントがメッセージを送信し、サーバーがそれを受信して​​処理する状況が発生する可能性がありますが、サーバーが肯定的な ACK パケットを送信すると、接続が切断され、クライアントがパケットを受信しないため、同じメッセージが再送信されます。接続が再確立されます。この状況を回避するには、ヘッダーでメッセージ ID (メッセージが送信されるたびに増加する int) を送信して、それを識別する必要があります。

難しいように聞こえますが、実際はそうです。接続が同じネットワーク (イントラネット) 上にある場合は問題なく動作しますが、通信がインターネット上にある場合、制御できない多くの問題や状況に直面する可能性があるため、明確に定義されたプロトコルが必要です。切断された接続から回復すると、トランザクション/メッセージは複製されません。

于 2013-06-22T12:40:07.010 に答える