Server Port wird doppelt gebunden

Added by david 4 months ago

Hallo Zusammen,

mir ist aufgefallen, dass ich den Server Prozess doppelt starten kann, ohne dass es zu einer BindException kommt.

In TCPView bzw. netstat sehe ich auch zwei java prozesse, welche am Serverport lauschen.
Eingehende Clientverbindungen bekommt der zuerst gestartete Prozess ab.

Eine BindException kann ich aber provozieren, indem ich vor dem Simon.createRegistry() Aufruf auf dem gleichen Port einen ServerSocket() erstelle oder einen laufenden Simon Server habe und dann versuche über ServerSocket() den selben Port zu binden.

Versuche ich Simon z.B. auf dem mysql Port lauschen zu lassen, gibts auch keinen Fehler. ServerSocket() wirft in diesem Fall aber die BindException.

Viele Grüße,
David

Simon Version ist 1.1.2


Replies (6)

RE: Server Port wird doppelt gebunden - Added by achristian 4 months ago

Hallo David,

hab eben im 1.1.2 Tag folgendes ausprobiert:

 1
 2@Test
 3    public void testCreateRegistryTwice() {
 4
 5        try {
 6            Registry r = Simon.createRegistry(22224);
 7            Registry r2 = Simon.createRegistry(22224);
 8            r.stop();
 9            r2.stop();
10        } catch (Exception ex) {
11            throw new AssertionError(ex);
12        }
13
14    }

Der JUnit-Test schlägt fehl:

testCreateRegistryTwice(de.root1.simon.test.TestSimon)  Time elapsed: 0.17 sec  <<< FAILURE!
java.lang.AssertionError: java.net.BindException: Die Adresse wird bereits verwendet
    at de.root1.simon.test.TestSimon.testCreateRegistryTwice(TestSimon.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
    at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
    at $Proxy0.invoke(Unknown Source)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:74)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)
Caused by: java.net.BindException: Die Adresse wird bereits verwendet
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:344)
    at sun.nio.ch.Net.bind(Net.java:336)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:199)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.apache.mina.transport.socket.nio.NioSocketAcceptor.open(NioSocketAcceptor.java:248)
    at org.apache.mina.transport.socket.nio.NioSocketAcceptor.open(NioSocketAcceptor.java:48)
    at org.apache.mina.core.polling.AbstractPollingIoAcceptor.registerHandles(AbstractPollingIoAcceptor.java:525)
    at org.apache.mina.core.polling.AbstractPollingIoAcceptor.access$200(AbstractPollingIoAcceptor.java:66)
    at org.apache.mina.core.polling.AbstractPollingIoAcceptor$Acceptor.run(AbstractPollingIoAcceptor.java:406)
    at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

Gleicher Fehler kommt, wenn ich den test nicht auf Port 22224, sondern auf 8888 umstelle. 8888 wird von einem anderen Dienst bereits auf meinem System benutzt.

Könnte es sein dass du die BindException irgendwo in deiner Anwendung aus versehen "geerdet" hast?
Kannst du das Problem auf ein kurzes Sample runterstrippen?
Welches OS benutzt du? Welche Java Version?
Firewall? Virenscanner?

Gruß
Alex

RE: Server Port wird doppelt gebunden - Added by david 4 months ago

Hi Alex,

habe es einmal mit dem Session Pattern Beispiel aus dem Wiki probiert.
Gleiches problem.

Folgender Code läuft auch Problemlos:

 1public class Server {
 2
 3    public static void main(String[] args)
 4            throws UnknownHostException, IOException, NameBindingException {
 5
 6        // create the serverobject
 7        ServerInterfaceImpl serverImpl = new ServerInterfaceImpl();
 8
 9        // create the server's registry ...
10        Registry registry1 = Simon.createRegistry(44444);
11        Registry registry2 = Simon.createRegistry(44444);
12
13        // ... where we can bind the serverobject to
14        registry1.bind("server", new ServerInterfaceImpl());
15        registry2.bind("server", new ServerInterfaceImpl());
16
17        System.out.println("Server up and running!");
18
19        // some mechanism to shutdown the server should be placed here
20        // this should include the following command:
21        // registry.unbind("server");
22        // registry.stop();
23    }
24}

Betriebssystem ist Windows 7 x64

java.runtime.version: 1.7.0-ea-b110
java.vm.version: 19.0-b06
java.specification.version: 1.7

Keine Firewall und kein Virenscanner ;-)

Habe noch einen Windows 2003 Server in einer VM - werde das noch einmal testen.

Viele Grüße,
David

RE: Server Port wird doppelt gebunden - Added by david 4 months ago

ok problem scheinbar gefunden.

scheint an java 1.7 zu liegen.

mit der 1.6er Version krieg ich die BindException.

Viele Grüße,
David

RE: Server Port wird doppelt gebunden - Added by achristian 4 months ago

Ist das ein Oracle oder OpenJDK?

Klappt bei mir mit Oracle Java7 problemlos (Ich bekomm die Exception).

RE: Server Port wird doppelt gebunden - Added by david 4 months ago

Beides mal Oracle.

Mit der 1.6er hab Ichs unter MacOS getestet.

Das OS meldet scheinbar auch sauber, dass die Ports geöffnet wurden.
In netstat sind nämlich zwei Java Prozesse zu sehen, welche beide den entsprechenden Port (22222) gebunden haben.

RE: Server Port wird doppelt gebunden - Added by achristian 4 months ago

Hmm, sehr seltsam.

Muss das am Montag nochmal im Büro testen. Hab hier nur Ubuntu und Debian :-) Melde mich dann nochmal mit dem Ergebnis.

Gruß
Alex

(1-6/6)