ネットワークプログラミングでcloseは難しい

http://q.hatena.ne.jp/1284128151
コメントにも書いたけどこれって難しい。


基本は回答した通りcloseしたら0バイトの受信が発生するだけ。
けれど現実のプログラムでは正しく通信を正しくできるかどうか?を考え出すと意外と問題がある。

  • 相手側のプログラムにバグがあり、受信処理が行うけどそれ以外の処理が出来ていない。これはcloseだけの問題じゃあないけど。
  • 相手側がハードウェア側で問題があったら? 例えば停電で電源が落ちたらどうなる?
  • 通信中にケーブルが突然抜けたら?
  • 無線通信を考えると、通信が出来なくなった場合は? 例えばA、B間で無線通信を直接行っていて通信できない距離まで移動したらどうなる?
  • そもそも自分のプログラムにバグがあったら? 例えば、受信処理にバグがあって正しく受信していない。そしてOS側の受信バッファがいっぱいになったらどうなる?

...


考え出すとキリがない。そこで、行うのがコメントにも書いたけどKeepAlive。
TCPレベルで行うKeepAliveもあるけど、あれじゃあclose検知には遅すぎて役に立たない。
また、これならば送受信だけでも出来ていれば、お互いにそれ以外にバグが対応できます。


KeepAliveを自前で行う方法は、一定時間送受信をしていなければ意味は無いけど1バイトでも良いので通信を行うことです。
これにより、上記の問題は解決します。

  • 相手側のプログラムにバグがあり、受信処理が行うけどそれ以外の処理が出来ていない。これはcloseだけの問題じゃあないけど。
  • そもそも自分のプログラムにバグがあったら? 例えば、受信処理にバグがあって正しく受信していない。そしてOS側の受信バッファがいっぱいになったらどうなる?

このあたりのバグ系は存在してても、最低限通信さえ出来ていればKeepAliveの通信は可能です。
それ以外で問題があっても仕方ありません。最悪自分さえ通信ができていれば、相手側に問題があっても関係ないです。

  • 相手側がハードウェア側で問題があったら? 例えば停電で電源が落ちたらどうなる?
  • 通信中にケーブルが突然抜けたら?
  • 例えば、受信処理にバグがあって正しく受信していない。そしてOS側の受信バッファがいっぱいになったらどうなる?

これは結構やっかいで通信相手がいなくなるのに、closeは受信しないはずです。
でもKeepAliveさえやっておけば、通信相手がいなくなった事は分かりますので、KeepAliveができなくなった時点でこちら側もcloseすれば問題ありません。


あと気をつけたいのは、closeの種類。
closeは送信側だけ、受信側だけ、送受信の3パターンでクローズできます。Pythonで出来るかは知らないけど。
丁寧にするのであれば、先に送信側をcloseして確実に相手側にこちら側はcloseしたよと通知すること。
これは相手がデータを送信して、こちら側が受信前に全closeをすると、相手側が送信したデータをこちら側は受信できなくなるからです。
できれば、受信側のclose後、少しまってから受信側をcloseするのが良い方法です。