Linux-Server ignors my Clients!

I’ve developed a Java server on Win XP and it works great, using the java.nio package.

However - When I put it to the test and ran it from my Linux (Mandrake / RedHat) server where it’s suppose to run, the server just ignore my client. Nothing happens!

The client gets the follow exception:


java.net.ConnectException: Connection refused: connect
      at sun.nio.ch.Net.connect(Native Method)
      at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:457)

I tried to use tutorial examples from sun’s homepage (TimeQuery / TimeServer) and I get the same error : Works great on windows but not at all in Linux.

However, it works when I reverse the roles and let Linux be client and use Windows as Server.

Therefore I make the conclusion that Linux has to be modified in some way (security aspects?) so that it is allowed to listen, connect, accept new connections…
It obviousely works when Linux acts as a client, but not at all as server!

I tried to modify my java.policy file but I can’t make it work!

Thanx for your help!
/Markus

Hi
What port are you trying to run on?, have you got 1.4.2 on the linux box, is there a firewall running on the linux machine at all?

Just things that immediatly spring to mind.

Cheers

Endolf

Nope - No firewall - Standard installation of Mandrake with jdk 1.4.2.

Should work! (but doesn’t…) :frowning:
/Markus

I just tested to run a simple EchoServer that used ServerSocket instead of ServerSocketChannel

Tada - It works! It’s just that I would like to use channels (java.nio)!

So - Now I have a ServerSocket that works and a ServerSocketChannel that doesn’t work!

Any ideas?

Hmm
This one is baffling. Could you posting your code on a website somewhere and posting the link here for us to take a look at?. It seems strange that you get a con refused when using NIO. Have you tried connecting to the linux NIO server from the linux box?

Cheers

Endolf

Yepp… Tried to do it “locally” on the linux-server and that works fine.

I’m trying to make the TimeServer / TimeQuery to work and you can look at them here : http://java.sun.com/j2se/1.4.2/docs/guide/nio/example/index.html

I’m using the same approach frmo my own server and as long as I can’t get the TimeServer to work, I’m lost…:frowning:

It’s very straight forward so I really can’t get why it doesn’t work!

Selectors perhaps?
/Markus

Ok
Imediate thing, are you specifying the port on the TimeQuery side when running against linux. The real time server runs on port 13 and this is what it queries against. When you run the java TimeServer it runs (by default) on port 8013 (a non privilaged port, unlike 13), so when you run the client you need to run it with the port number and the hostname

java TimeQuery 8013 <server hostname/ip>

When doing this, it runs on my home linux box fine, connect from a different linux box. If I don’t specify the port number on the client side then I get con refused too as I have no real time server running on that machine :slight_smile:

You should see something like

java TimeQuery 8013 172.20.0.3
/172.20.0.3:8013 : Thu Jan 08 13:08:43 GMT 2004

in the client and

java TimeServer
/172.20.0.2 : Thu Jan 08 13:08:43 GMT 2004

in the server.

HTH

Endolf

No - I modified the client so that it uses 8013 but still nothing…

However - I just tried to bind my server differently:

I replaced


InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port)

With

InetSocketAddress isa = new InetSocketAddress(port)

and guess what… I got through to my server! The only question is why?

My guess is that getLocalHost returned the loop back interface on your linux box, but the NIC on your windows box, I don’t know how it chooses what to return. new InetAddress(port) will give the wildcard address so I think it will bind to all interfaces, including the NIC and loopback.

Glad it’s sorted

Endolf

Me again :slight_smile:
Just out of interest, could you do a InetAddress.getLocalHost().toString() and dump it out on you windows and your linux boxes, and also, what order do your interfaces get listed in ifconfig on your linux box. Just curious here :slight_smile:

Cheers

Endolf

[quote]My guess is that getLocalHost returned the loop back interface on your linux box, but the NIC on your windows box,
[/quote]
This is a very common problem with moving to 1.4.x; previously, of course, java wouldn’t let you bind to multiple addresses separately (IIRC it just bound to “all”?). The typical behaviour now - of binding to localhost on linux - is security-conscious (although an alternative method (e.g.

getLocalHostNotLoopback()

) that forced a non-localhost bindind OR THREW AN EXCEPTION would be nice).

I have no idea whether the linux behaviour is intentional or accidental (c.f. the quote below that implies it could be due to a silent security refusal), but the FAQ’s on this topic all over the web just say “choose the correct InetAddress manually, or by iterating over all possible ones and binding to everything” and that always seems to work. Sadly there’s a lot of crappy tutorials on the web that neglect to mention any of this :).

Quote (from J2SE 1.4.x docs:

" Returns the local host.

If there is a security manager, its checkConnect method is called with the local host name and -1 as its arguments to see if the operation is allowed. If the operation is not allowed, an InetAddress representing the loopback address is returned."

What it doesn’t say is what it returns if the operation IS allowed - and my belief is that linux returns loopback for this too, whereas windows chooses the NIC. N.B. the definition of what IP address you’ll be given based upon your own hostname is very fluid, and this could well be the cause of confusion - MANY linux systems have their hostname mapped to 127.0.0.1 (partly because lots of crap linux software - e.g. some FTP servers I’ve used - requires a mapping, and their docs often suggest you connect your hostname to 127.0.0.1 if you have a dynamic IP).

Anyway, welcome to the vague and woolly world of java’s API docs…

No worries! And btw, Thanx for your assistance / support :wink:

InetAddress.getLocalHost()[Linux]
Localhost = localhost/127.0.0.1

InetAddress.getLocalHost()[Windows XP]
Localhost = murdockian/192.168.12.42

ifconfig:


eth0      Link encap:Ethernet  HWaddr 00:06:5B:55:26:F0
          inet addr:20.0.0.193  Bcast:20.0.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1597 errors:0 dropped:0 overruns:1 frame:0
          TX packets:1052 errors:0 dropped:0 overruns:0 carrier:0
          collisions:47 txqueuelen:100
          RX bytes:703409 (686.9 Kb)  TX bytes:99376 (97.0 Kb)
          Interrupt:18 Base address:0xdc80

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:90 errors:0 dropped:0 overruns:0 frame:0
          TX packets:90 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:8480 (8.2 Kb)  TX bytes:8480 (8.2 Kb)

Thanx blahblahblahh (?) for the clarification ;). As you said, I’ve searched the web for two days and found ziltch until you guys came along and explained things!

You learn as long as you live…

Thanx!

[quote]What it doesn’t say is what it returns if the operation IS allowed - and my belief is that linux returns loopback for this too, whereas windows chooses the NIC.
[/quote]
But not consistently, as my linux box ran fine with unmodified code :), running 1.4.2_03, I wonder if it changed in the later 1.4.2 series to return a non lo interface?

Cheers

Endolf

For finding the machine’s IP address I use something like:


            // get the current IP address
            InetAddress thisMachine = null;
            try
            {
                  thisMachine = InetAddress.getLocalHost();
            }
            catch( UnknownHostException e )
            {
                  e.printStackTrace();
                  return;
            }
            System.err.println( "This machine is: "+thisMachine.getHostAddress());
            byte [] thisAddress = thisMachine.getAddress();
            
            if( thisMachine.isLoopbackAddress() )
            {
                  System.err.println("Can't get network address, got loopback, trying harder...");
                  try
                  {
                        boolean foundGood = false;
                        Enumeration en = NetworkInterface.getNetworkInterfaces();
                        wayout:
                        while( en.hasMoreElements() )
                        {
                              NetworkInterface ni = (NetworkInterface) en.nextElement();
                              Enumeration iae = ni.getInetAddresses();
                              while(iae.hasMoreElements())
                              {
                                    InetAddress ia = (InetAddress) iae.nextElement();
                                    if( ia.isLoopbackAddress() )
                                          continue;
                                    thisMachine = ia;
                                    thisAddress = ia.getAddress();
                                    foundGood = true;
                                    break wayout;
                              }
                        }
                        
                        if( !foundGood )
                        {
                              // put error code here
                              Toolkit.getDefaultToolkit().beep();
                              return;
                        }
                  }
                  catch( SocketException ex)
                  {
                        // put error code here
                        Toolkit.getDefaultToolkit().beep();
                        return;
                  }