Re: Clarification on firewall issues with Java networking APIs
- From: Nigel Wade <nmw@xxxxxxxxxxxx>
- Date: Wed, 12 Dec 2007 11:36:56 +0000
Arne Vajhøj wrote:
Nigel Wade wrote:works
Qu0ll wrote:
I understand that RMI doesn't play well with the internet because it can't
work properly when either the client or the server is behind a proxy unless
tunneling is used and that tunneling is slow and prevents callbacks from
being used. So I get it that RMI is probably not the network API for me.
RMI plays perfectly well with the Internet, but not firewalls. I think RMI
thein a very similar way to portmapper. The rmiregistry listens on a well-known
port. A RMI server registers its service with the rmiregistry, and is either
assigned or tells the registry the port that it actually listen on. A RMI
client asks the rmiregistry for the "location" of a particular service, and
tormiregistry replies telling the client what host/port the server is listening
on.
For the above to work through a firewall the client must be able to connect
bethe server both on the rmiregistry port and the port on which the server is
listening. This will normally cause problems with firewalls because they are
not configured to allow this to happen for dynamic ports. It may be possible
for an RMI server to request a specific port and register that, but I'm not
certain (RMISocketFactory.createServerSocket(int port)?). That way it might
inpossible to open only the rmiregistry port and the specific RMI server ports
callbackthe firewall.
It is possible.
RMISocketFactory.setSocketFactory(new FixedPortRMISocketFactory());
LocateRegistry.createRegistry(60000);
and:
package test.server;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
import java.rmi.server.RMISocketFactory;
public class FixedPortRMISocketFactory extends RMISocketFactory {
private static int socketNumber = 60000;
public Socket createSocket(String host, int port) throws IOException {
return new Socket(host, port);
}
public ServerSocket createServerSocket(int port) throws IOException {
if(port == 0) {
socketNumber++;
port = socketNumber;
}
return new ServerSocket(port);
}
}
will use port 60000 for registry and 60001, 60002, ... for
server.
And I understand that servlets don't have this problem because they
communicate through the standard HTTP port but that servlets don't support
callbacks for non-HTML clients. (Feel free to disagree if appropriate).
Servlets can communicate via any port. The initial connection is made to the
servlet container on whatever port that happens to be listening on. It may be
80, or 8080 or any other port. The socket is passed to the servlet's service
routine and the servlet can send a reply on that already established socket.
There is no requirement for communication to be HTTP unless you extend
HttpServlet. A GenericServlet can use any protocol (layered over TCP/IP).
Servlets can also open any other socket they wish, including initiating
to a client. If you do this in the service method you are likely to get
deadlock if the servlet attempts to initiate a new communication channel with
the client whilst the client is waiting for the servlet to respond to its
initial request. You would have to handle this carefully.
Servlet containers are not written to support long running servlets.
"Long" as in "how long is a piece of string" is a relative term... ;-)
thread
You could also start a background thread in the servlet. The background
could open a socket to the client and send data when it was ready. The client
would have to be listening to accept the connection and be able to read the
data.
Much better concept.
I have tried this specific method and failed. The thread would run perfectly for
anything between 12 to 14 days, and then die without any indication as to why
it had died. There was no output in any of the Tomcat logs, or the servlet
logs, no stack trace, and I was unable to establish any monitor which would
trap the thread's death. It just vanished without a trace. Needless to say, a
thread which runs for 12 to 14 days and then vanishes is rather hard to debug.
So I changed the design to use blocking calls.
In my case the "long" as discussed above is typically of the order of 10s, and I
use a timeout so there is no issue with the container and long running
servlets. Of course this means the client has to handle the problem of a call
returning with no data. But that's a simple matter of having the thread in the
client which reads the data loop over the call, and re-issue it if the return
status indicates a timeout.
calls.
But with this method you are at the mercy of the servlet container as it
may decide to unload the servlet if it doesn't received any new service
I think that is only theoretical.
Maybe...
request
The simplest method is to use blocking calls. The client makes a service
to the servlet as normal, but the servlet does not return until there is
something to return.
I think a non non waiting servlet and a thread is much better.
It would be if it can be made to work. Besides keeping the thread alive, you
have the problem of the servlet being able to establish a connection back to
the client through whatever firewalls are in the way.
With many requests the waiting servlets could lockup the container.
Yep, all the methods have pros and cons. These need to be weighed up in the
context of how the application will be used in practise. I don't think there is
any "one size fits all" solution to this type of problem.
--
Nigel Wade, System Administrator, Space Plasma Physics Group,
University of Leicester, Leicester, LE1 7RH, UK
E-mail : nmw@xxxxxxxxxxxx
Phone : +44 (0)116 2523548, Fax : +44 (0)116 2523555
.
- Follow-Ups:
- Re: Clarification on firewall issues with Java networking APIs
- From: Arne Vajhøj
- Re: Clarification on firewall issues with Java networking APIs
- References:
- Clarification on firewall issues with Java networking APIs
- From: Qu0ll
- Re: Clarification on firewall issues with Java networking APIs
- From: Nigel Wade
- Re: Clarification on firewall issues with Java networking APIs
- From: Arne Vajhøj
- Clarification on firewall issues with Java networking APIs
- Prev by Date: Re: After a while all outbound connections get stuck in SYN_SENT
- Next by Date: Re: Getting output from exec()?ed program
- Previous by thread: Re: Clarification on firewall issues with Java networking APIs
- Next by thread: Re: Clarification on firewall issues with Java networking APIs
- Index(es):
Relevant Pages
|
|