ふと ServerSocket の SO_REUSEADDR ソケットオプションが気になったときのメモ。
Java API 仕様
API 仕様には以下のように記述されている。ということは Java は我関せず?
ServerSocketが作成されるときに、SO_REUSEADDRの初期設定は定義されていません。アプリケーションはgetReuseAddress()を使用して、SO_REUSEADDRの初期設定を確認できます。
http://docs.oracle.com/javase/jp/8/api/java/net/ServerSocket.html#setReuseAddress-boolean-
SO_REUSEADDR ってなに?
SO_REUSEADDR は、サーバに TIME_WAIT 状態のアドレスに bind することを許します。
Programming UNIX Sockets in C - Frequently Asked Questions: サーバアプリケーションの作成 (TCP/SOCK_STREAM)
http://www.kt.rim.or.jp/~ksk/sock-faq/unix-socket-faq-ja-4.html
ちょっと乱暴だが、固定ポートに bind するサーバー以外では気にしなくても大丈夫ぽい*1
SO_REUSEADDR の初期設定
import java.io.IOException; import java.net.ServerSocket; public class PrintReuseAddress { public static void main(String[] args) throws IOException { boolean reuseAddress = new ServerSocket().getReuseAddress(); System.out.printf("SO_REUSEADDR: %s", reuseAddress); } }
これを手近なマシンで試してみた結果が↓これ。
- 普段使いの Windows 機
- 転がってた Windows Server 機
- OS: Windows Server 2008 R2 Sp1
- Java: 1.6.0_45 HotSpot(TM) 64-Bit Server VM
- SO_REUSEADDR: false
- 転がってた Ubuntu
- MBA
- http://www.javarepl.com/console.html
補足
OS X のデフォルトはやっぱり true の模様 http://lists.apple.com/archives/java-dev/2004/Dec/msg00570.html
*1:固定ポートに bind するクライアントもあるらしい