2016-04-06 2 views
0

Definitionen
bekannten Port
        Portnummer im Bereich [0, 1023]
Registrierte Hafen
        Hafen Nummer im Bereich [1024, 49151]
Dynamischer Port
        Portnummer im Bereich [49152, 65535]Socket löst immer BindException für Dynamic Ports

Ich versuche, ein SocketServer Objekt zu erstellen. Wenn ich SocketServer erlaube, einen dynamischen Port auszuwählen (durch Bindung an Port 0), funktioniert es wie erwartet. Wenn ich einen registrierten Port explizit angeben, funktioniert es wie erwartet. Wenn ich jedoch einen dynamischen Port angabe, wird immer ein BindException mit der Nachricht "Adresse bereits verwendet: JVM_Bind" geworfen. Der obere Teil des Stack-Trace für die Ausnahme ist:

at java.net.DualStackPlainSocketImpl.bind0(Native Method) 
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106) 
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387) 
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190) 
at java.net.ServerSocket.bind(ServerSocket.java:375) 
at java.net.ServerSocket.<init>(ServerSocket.java:237) 
at java.net.ServerSocket.<init>(ServerSocket.java:128) 

ich JDK bin mit 1.8u74 auf einem Windows 7 Enterprise SP1 x64-Maschine. Der Code lautet wie folgt:

SocketServer createServer(final int port) throws IOException { 
    // Create a new socket server 
    SocketServer server; 
    try { 
     // Try to bind to all interfaces 
     server = new ServerSocket(port, 1, null); 
    } catch (BindException e) { 
     // If that fails, try to bind to the primary IP address 
     final InetAddress address = InetAddress.getLocalHost(); 
     server = new ServerSocket(port, 1, address); 
    } 
    return server; 
} 

Ich habe auch die folgende Alternative versucht:

SocketServer createServer(final int port) throws IOException { 
    // Create a new socket server 
    final SocketServer server = new SocketServer(); 
    server.setReuseAddress(true); 
    try { 
     // Try to bind to all interfaces 
     server.bind(new InetSocketAddress(port), 1); 
    } catch (BindException e) { 
     // If that fails, try to bind to the primary IP address 
     final InetAddress address = InetAddress.getLocalHost(); 
     server.bind(new InetSocketAddress(address, port), 1); 
    } 
    return server; 
} 

Beiden Alternativen werfen einen BindException wenn port ein dynamisch Port ist. Ich habe überprüft, dass alle der etwa 50 dynamischen Ports, die ich getestet habe, gemäß den Ergebnissen von netstat -an verfügbar sind. Gibt es eine Möglichkeit, einen SocketServer für einen bestimmten dynamischen Port zu erstellen?

+0

Ich schlage vor, dass Sie den Wert von "Port" verfolgen. Diese Art von Code funktioniert für alle anderen. – EJP

Antwort

0

Obwohl nicht ideal, da es Registrierungsänderungen betrifft, gibt es eine Antwort auf Server Fault.

Windows kann so eingerichtet werden, dass Ports aus dem Bereich dynamischer Ports ausgeschlossen werden. Einfach den Bereich ausschließen hinzufügen (en) auf dem Multi-String-Wert:

HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters \ ReservedPorts

So haben in meinem Fall habe ich eine Anforderung Um die Ports 55101-55107 zu verwenden, habe ich diesen Text zum Registrierungswert hinzugefügt und den Computer neu gestartet. Während diese Lösung mir erlaubt, diese Ports zu verwenden, ist es enttäuschend, dass ich die Registrierung auf jedem Windows-Rechner bearbeiten muss, auf dem ich sie verwenden möchte. Wenn ich in der Zukunft einen weiteren dynamischen Port hinzufügen muss, muss ich die Registrierung erneut bearbeiten.