users@grizzly.java.net

Re: suitability for writing UDP servers

From: Radim Kolar SF.NET <hsn_at_sendmail.cz>
Date: Thu, 25 Oct 2007 03:31:20 +0200

> Can you explain how to handle that with NIO? Grizzly uses SelectionKey, but
> the creation is made by the NIO layer of the JDK.

> If I understand the issue properly, you would like to have one packet per SelectionKey?
no, i would like to have one selection key per (client ip:client port:server ip:server port).

statefull firewalls can do something like this and it can be possibly simulated in Java:
Code something like ACCEPT for UDP:

After receiving UDP packet on server socket, check own database of client ip/client port combos. If client ip/port combo is found in database it is probably
safe to ignore packet because it should arrive on second channel too.

If no known client is found, create new UDP channel and bind it to server ip,port (with addr reuse) and then connect() it to client ip/port. you will get
new SelectionKey - unique to client

This is a bit OS dependent because UDP packet from client can be received by both channels or just by newly created channel. Modern OSes should forward received UDP packet just to new channel but it needs some testing.

>> * at lot of places in code filters/other components are canceling
>> SelectionKeys on io errors (such as UDP output buffer full). If they
>> cancel SelectionKey, server socket is closed and nobody other
>> can use server until server is restarted.
>
> Hum, that would be a bug if that's the case. When the SelectionKey is
> cancelled, it means the connection is either closed by the client of
> something unexpected happens. Do you have a test case I can use to
> reproduce the problem?
Its timing dependent. test case is like this:
 client creates UDP socket connect it to server, sends packet,closes socket.
server reads packet,sends reply (UDP stack returns error because client closed socket), server closes socket
and no other client can connect to it.

>> * DefaultSelectionKeyHandler closes server socket after 30 secs of
>> inactivity
>
> Yes that's a design decision we took. You can disable the feature by doing:
you are closing listening socket if no client connects to TCP server in last 30
seconds by default? Because in UDP case, it closes socket but Controller select
loop is still running, so result is that nobody can connect to it anymore.
While it can be good design decision to close client sockets after 30 seconds,
it should not close server socket.

> It close socket only when an exception happens. Are you seeing something
> different? If yes, it means there is a bug :-)
UDPSelectorHandler needs
protected Boolean isClient = false; field
when running in client mode, don't create server socket, when running in
server mode, never close sockets on errors.