Skip to Main Content

Java APIs

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Weird ServerSocket.accept() behaviour on Windows

843790Sep 14 2009 — edited Sep 16 2010
hi all,
i've come across a very strange problem, that i've been able to reproduce only on one machine (by now).
See the code snippet below: basically, i'm creating 2 different ServerSocket instances, each bound to the loopback address but (of course) on a different port, and launching the accept() method from 2 different threads.
First question: is there anything wrong with that? Do you know of any thread-safety issue with creating ServerSockets and accepting connections from parallel threads? Note that we're talking of 2 different instances.

Well, this is what happens when i launch this code from a customer's machine (WinXP SP3 Media Center Edition):

1- I run the program, it prints out "0: before accept on 8082" and waits there. That's what i expected.
2- Now i open another command prompt, and run "telnet 127.0.0.1 8082". Telnet lets me connect, not giving any error message, it just clears the screen and waits for input. Everithing fine but...
2.1- Meanwhile, the test program did NOT print out "0: after accept on 8082". The ss2.accept() method just hangs there forever.
3- Leaving the telnet window open, now i open another prompt, and run another "telnet 127.0.0.1 8082". Same as before: telnet lets me in, but still nothing is printed out from the test app.
4- At this point, i open a third telnet session, on port 11111: as soon as i hit enter, the main thread is somehow unlocked, and the program prints out in sequence:
0: after accept on 8082
1: before accept on 8082
1: after accept on 8082

It looks like accept() is synchronizing on some global mutex. How this can be?

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;

public class AcceptTest
{
  public static void main(String[] args) throws IOException
  {
    // Starting a separate thread that creates a ServerSocket and listens on port 11111
    Thread t = new Thread()
    {
      public void run()
      {
        try
        {
          new ServerSocket(11111, 0, InetAddress.getByAddress(new byte[]{127,0,0,1})).accept();
        }
        catch(IOException ex)
        { ex.printStackTrace(); }
      }
    };
    t.setDaemon(true);
    t.setPriority(Thread.MIN_PRIORITY);
    t.start();
    
    
    // Creating another ServerSocket instance from the main thread, and accepting connections on port 8082
    ServerSocket ss2 = new ServerSocket(8082, 0, InetAddress.getByAddress(new byte[]{127,0,0,1}));
    int c = 0;
    while(true)
    {
      System.out.println(c+": before accept on 8082");
      ss2.accept();
      System.out.println(c+": after accept on 8082");
      c++;
    }
  }
}
To be sure it wasn't an error in the code, i tried installing and running Apache Tomcat on that machine. I chose it because it basically does the same thing: creates separate threads, and accepts simultaneously on different ports (at least 3, by default: 8080-http, 8009-ajp and 8005-shutdown). Well, tomcat doesn't work either!
If i point the browser to localhost:8080, it just hangs there waiting for data. Then i run telnet on port 8005 or 8009 (sometimes one sometimes the other), and immediately the tomcat default page is displayed.
Looks like the accept call which arrives first takes over and locks all the others...

The machine is running a firewall application called "Ashampoo firewall". I tried disabling it as well as the Windows Firewall, but no change. I checked the output of "netstat -ao", and it seems that the ports are owned by our process, as expected. No other program seems to "hijack" them.
I also tried creating a brand new windows user and repeat the test, but same story.

I don't know if this is enough to file a bug to Sun, especially because i didn't manage to create a testcase that can reproduce this on other machines.

Anybody have a clue? I don't know where to bang my head, our application is going to be distributed to lots of users in many different countries, and we're afraid there could be other cases like this.

sorry, i wrote too much...

thanks for your patience,
alberto

ps.
A colleague of mine has found an old thread on comp.lang.java.programmer, that seems describing a similar problem...

http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2008-07/msg00733.html
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 14 2010
Added on Sep 14 2009
9 comments
253 views