

android端末のアプリ使用でTCP切断時、正常であれば『サーバ⇒端末』にFINが投げられた後、即『端末⇒サーバ』へFINを返しています。  
ただ時たま、『サーバ⇒端末』にFINが投げられた後、『端末⇒サーバ』へFINを返す際に120sほどかることがあります。

こちら、遅れる原因としてどういったものが考えられますでしょうか。  
OSの問題でしょうか。  
※端末アプリにはHTTPリクエスト時の共通処理として、ソケットのクローズ処理があります


CC BY-SA 3.0
2015-06-24T06:03:29.430
11669
2017-03-05T07:50:24.437
10267
question
android tcp
TCP接続切断時のandroid端末⇒サーバへのFINが遅延する


AndroidOSに搭載されているTCPプロトコルのソフトウェアのバグの可能性も否定出来ませんが  
TCPのクローズ処理のシーケンスとして以下のような流れになります。

サーバ：FIN（これをもってサーバからデータ送信しない） -> ACK応答（OKわかった。でもクライアントはまだ送信するかもしれないよ）  
クライアント：FIN（これをもってクライアントからデータ送信しない） -> ACK応答（OKわかった）  
サーバ・クライアント：双方FINを認識したのでじゃあクローズとしよう。

つまり、『サーバ -> 端末』でのFIN時点ではTCP切断は成立していません。（shutdown状態）  
また、サーバ側はsend()する事は出来ませんが、shutdown(読込)していなければrecv()は可能）ですし  
クライアント側はsend()もrecv()もする事が出来ます。但し、使用しているソケットに対して  
クライアントがrecv()をした時、TCPプロトコル側に" **受信データがない**
"と戻り値として「0」が返ります。（もうサーバから送られる可能性が無いので）

なのでクライアントからのFINが遅れる原因として考えられる可能性は、  
クライアント側がclose()またはshutdown(書込）を実行してサーバ側にFIN送信をしていないのではないでしょうか。  
具体的にはクライアント側がまだ受信処理をしている、とか送信処理をしているとか。（まだ仕事をしている）  
またはクライアント側のアプリケーションの問題で適切にclose()を発行していないのかもしれませんね。  
話を聞く限り、120秒も掛かっているのでTCPプロトコルかアプリケーションの何らかの問題の可能性が高いかもしれません。  
設定にもよりますが120秒という切りの良い時間ですし、サーバ側が実行したclose()がタイムアウトして切断が成立しているのかもしれません。  
パケットキャプチャ見ないとわかりませんが、サーバがclose()でタイムアウト（TIME-WAIT2 ->
CLOSED）になった後にクライアントからデータ送信が来た場合RSTを返すはずなので  
そういう動きになっていればclose()のタイムアウトで強制切断になっている可能性が高いと思います。


CC BY-SA 3.0
2017-03-05T07:33:24.593
33106
2017-03-05T07:50:24.437
2017-03-05T07:50:24.437
20931
20931
11669
answer