読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

Socketの作成で「Address already in use: connect」が発生する

Java

Windows XP環境で、次のコードを実行すると、

for ( int i = 0 ; i < 20000; i++ ) {
    System.out.println( i );
    Socket s = null;
    try {
        s = new Socket("hogehoge.com", 80);
    } finally {
        if (s != null) { s.close(); }
    }
}

4000回目くらいで以下のエラーになる。

....
3958
3959
3960
3961
3962
3963
Exception in thread "main" java.net.BindException: Address already in use: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:516)
    at java.net.Socket.connect(Socket.java:466)
    at java.net.Socket.<init>(Socket.java:366)
    at java.net.Socket.<init>(Socket.java:179)
    ....

上記コードをLinux環境で実行した場合、エラーは発生しない。(20000回まで確認)

原因

Windowsにおけるソケットの最大値とTIME_WAITの時間を修正しようより、WindowsXPでは、「ソケットの最大数」が決まっており(デフォルトは5000)、さらにcloseしたソケットも一定期間は使えないらしい。なので、上みたいなコードを書くとあっという間に枯渇する。

対策

  • ソケットを短時間に大量に生成/破棄するようなコードを書かない。
  • レジストリの設定でソケットの最大数を増やす。
  • レジストリの設定でTIME_WAITの時間を短くする。

こんな話もあるんだなー。

補足:Windows Server 2003ではどうなの