Donnerstag Feb 26, 2009

Writing a UNIX daytime server (RFC 867) using Grizzly 1.9.x

This week, i started to write some kind of "Hello, World" programs for the superb Grizzly NIO framework. I used Jean-Francois Arcand's intro documentation as a foundation.

My goal was to create a simple Grizzly version of the UNIX daytime server (RFC 867). I based my tiny little program on Grizzly 1.9.7 therefore i had to remove the DefaultPipeline/setPipeline code which was needed with Grizzly 1.0.x in his examples. The tricky part was to tell Grizzly to process the ProtocolFilter on an accepted connection, rather than waiting for some data coming upstream. This is how the daytime server works - you connect to it, you get the date/time and the server closes the connection. 

Thanks to Oleksiy Stashok's reply on the grizzly users mailinglist this was fixed quite fast.  

Here's my poor man's version of a unix daytime server: 

 24 public class Main {
 25 
 26     private static int PORT = 1405;
 27 
 28     public static void main(String[] args) {
 29         Controller controller = new Controller();
 30 
 31         TCPSelectorHandler tcpSelectorHandler = new TCPSelectorHandler() {
 32 
 33             @Override
 34             public boolean onAcceptInterest(SelectionKey key,
 35                     Context ctx) throws IOException {
 36                 SelectableChannel channel = acceptWithoutRegistration(key);
 37 
 38                 if (channel != null) {
 39                     configureChannel(channel);
 40                     SelectionKey readKey =
 41                             channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
 42                     readKey.attach(System.currentTimeMillis());
 43                 }
 44                 return false;
 45             }
 46         };
 47 
 48         tcpSelectorHandler.setPort(PORT);
 49         
 50         controller.addSelectorHandler(tcpSelectorHandler);
 51 
 52         ProtocolChainInstanceHandler pciHandler =
 53             new ProtocolChainInstanceHandler() {
 54 
 55                 final private ProtocolChain protocolChain = new DefaultProtocolChain();
 56 
 57                 public ProtocolChain poll() {
 58                     return protocolChain;
 59                 }
 60 
 61                 public boolean offer(ProtocolChain instance) {
 62                     return true;
 63                 }
 64             };
 65             
 66         controller.setProtocolChainInstanceHandler(pciHandler);
 67 
 68         ProtocolChain protocolChain = pciHandler.poll();
 69         protocolChain.addFilter(new DaytimeWriterFilter());
 70 
 71         try {
 72             System.out.println("Starting Daytime server running on port " + PORT);
 73             controller.start();
 74         } catch (IOException ex) {
 75             Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
 76         }
 77 
 78     }
 79 }
 80 
 81 class DaytimeWriterFilter implements ProtocolFilter {
 82 
 83     public boolean execute(Context ctx) throws IOException {
 84         if (ctx.getProtocol() == Controller.Protocol.TCP) {
 85             SelectableChannel channel = ctx.getSelectionKey().channel();
 86 
 87             String now = (new Date()).toString() + "\\n";
 88 
 89             ByteBuffer buffer =  ByteBuffer.wrap(now.getBytes());
 90 
 91             OutputWriter.flushChannel(channel, buffer);
 92 
 93             channel.close();
 94             buffer.clear();
 95         }
 96 
 97         return false;
 98     }
 99 
100     public boolean postExecute(Context ctx) throws IOException {
101         return false;   // game over
102     }
103 
104 }
About

schmidtm

Search

Archives
« April 2014
MoDiMiDoFrSaSo
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Heute