ホスト に TCP/IP 接続できませんでした。 java.net.BindException: Address already in use: connect
Windows 2000 や XP では、TCP/IP 接続を確立すると空いている TCP/IP ポート番号が順次割り当てられます。
割り当てられる TCP/IP ポート番号の範囲はレジストリパラメータ MaxUserPortで設定されており、デフォルトでは 1024番 ~ 5000番となっています。
使用されたポート番号は TCP/IP 接続が解除されると解放されますが、すぐに解放されるわけではなく、一定時間 TIME_WAIT状態を維持した後、解放されるようです。
TIME_WAIT状態が維持される時間はレジストリパラメータ TcpTimedWaitDelay で設定されており、デフォルトでは 60秒と設定されています。
ここにワナが潜んでいるわけです。
つまり、短時間に JDBC で DB への接続と切断を繰り返した場合、TIME_WAIT状態の TCP/IPポート番号が大量に発生することにより、使用可能な TCP/IPポート番号がなくなり上記のようなエラーが発生するというわけです。
確かにプログラムの実行中に netstatコマンドでネットワーク接続状況を確認してみると TIME_WAITの接続が大量に出現していました。
C:\>netstat Active Connections Proto Local Address Foreign Address State TCP mypc:microsoft-ds localhost:3046 ESTABLISHED TCP mypc:2883 localhost:microsoft-ds TIME_WAIT TCP mypc:3046 localhost:microsoft-ds ESTABLISHED TCP mypc:2884 mypc:netbios-ssn TIME_WAIT TCP mypc:2885 mypc:ms-sql-s TIME_WAIT TCP mypc:2886 mypc:ms-sql-s TIME_WAIT TCP mypc:2887 mypc:ms-sql-s TIME_WAIT TCP mypc:2888 mypc:ms-sql-s TIME_WAIT TCP mypc:2889 mypc:ms-sql-s TIME_WAIT TCP mypc:2890 mypc:ms-sql-s TIME_WAIT TCP mypc:2891 mypc:ms-sql-s TIME_WAIT TCP mypc:2892 mypc:ms-sql-s TIME_WAIT TCP mypc:2893 mypc:ms-sql-s TIME_WAIT TCP mypc:2894 mypc:ms-sql-s TIME_WAIT TCP mypc:2895 mypc:ms-sql-s TIME_WAIT TCP mypc:2896 mypc:ms-sql-s TIME_WAIT TCP mypc:2897 mypc:ms-sql-s TIME_WAIT TCP mypc:2898 mypc:ms-sql-s TIME_WAIT TCP mypc:2899 mypc:ms-sql-s TIME_WAIT TCP mypc:2900 mypc:ms-sql-s TIME_WAIT . . .
このエラーは、MaxUserPort(5000~65534)または TcpTimedWaitDelay(30秒~300秒)の設定を調整することで回避することも可能です。
ただ、そもそも DBへの接続と切断を頻繁に繰り返すようなプログラムの作りのほうが悪いので、そちらを改善するのが本筋でしょう。
DBへの接続と切断の回数を減らすことによってパフォーマンスも向上します。
参考:5000 を超える番号の TCP ポートから接続しようとすると 'WSAENOBUFS (10055)' エラーが表示される