ソケット通信が出来ない原因の犯人はTIME_WAIT
とあるサーバーにアプリを使ってアクセスしようとしたら ソケットが開けない、と言ったエラーが出ました。
ざっと見サーバー側もおかしなことが起こってないような感じでしたが、
$ netstat -anp
としてみると、大量の
tcp 0 0 192.0.2.0:50000 192.0.2.0:39210 TIME_WAIT
みたいなTIME_WAIT
な物が出てました。
ここで、50000
が実際サーバー側で使ってるTCPサーバーなプログラムが
使ってるポートです。
なんか暴走して沢山開こうとしているみたい。
プログラムを再起動してみると、最初のうちは繋がるんですが、 やはりどんどんポートを使い尽くしていってやがて使えなくなります。
実際に今使えるポートの数を調べるには
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
みたいな感じでip_local_post_range
を見ます(Linuxです)。
この2つの数字の間が使えるので全部で61000-32768+1
=28233
だけ使えます。
さて、繋がらなくなった状態でどれだけポート使ってるか調べてみると
$ netstat -anp|grep TIME_WAIT|wc -l
283233
と綺麗に全部使ってます。なのでつながらないのは当たり前。 勿論違う物も全て繋がらなくなります。
TIME_WAITはサーバー側から接続を切る様な場合に、 ソケットを閉じる際に相手からのデータを全て最後まで受信出来たか確認するために 暫く待つための時間です 1。
通常は60秒に設定されてます。
その辺色々設定変更するのはちょっと面倒。
逆にTIME_WAITな状態で60秒経っても終了せずに残ってしまう様なのがある場合、 これを消すのも結構面倒です。
TCPIP/TIME_WAIT状態ソケットの強制終了 Tipi: http://tunes.sakura.ne.jp/tipi/?TCPIP%2FTIME_WAIT%BE%F5%C2%D6%A5%BD%A5%B1%A5%C3%A5%C8%A4%CE%B6%AF%C0%A9%BD%AA%CE%BB
まあ、問題が無いなら再起動してしまうのが一番簡単。
と、今回の件はひたすら終了しないTIME_WAITが残ってしまう様な状態でした。
で、結局どうしたか、というと、単にバグがあって ちょっと他のプログラムと衝突して暴走してただけでした。
ということで、実際処置をどうこうした、と言う話ではないのですが、 ポートの使用状況を調べたりTIME_WAITとかに関するメモです。