UDP Tutorial

This tutorial is designed to help you in writing a client and server using the MINA framework. In this tutorial we will write a server that displays memory usage for clients. This has some real world applicability in that you can place similar logic into any program in order to monitor the amount of memory that your program is using.

Version Note
This tutorial has been verified on MINA 2.0 and above.

Building the code

For now MINA 2.0 isn't released, so you will have to build it yourself from apache subversion server. If you need assistance in building MINA from the trunk, please consult the Developer Guide.

Server Code analysis

We will begin by looking at the code found in the org.apache.mina.example.udp package under mina-examples. I have omitted the GUI portion of this class in order to keep things short and sweet, plus the GUI code is not something that should be used to learn Java, I concentrated on the MINA aspects of this program. Begin by opening up the file MemoryMonitor.java. Here is the first snippet to look at:

DatagramAcceptor acceptor = new DatagramAcceptor();
acceptor.setLocalAddress(new InetSocketAddress(PORT));
acceptor.setHandler(new MemoryMonitorHandler(this));

As you can see, this is normal stuff for any server written using MINA. The variable 'PORT' is just an int. The next step is to add a logging filter to the filter chain that this DatagramAcceptor will use.

DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
chain.addLast("logger", new LoggingFilter());

Next we get into some more specific code for the UDP traffic. We will set the acceptor to reuse the address

DatagramSessionConfig dcfg = acceptor.getSessionConfig();
dcfg.setReuseAddress(true);

Of course the last thing that is required here is to call bind().

Client Code Analysis

In this section, I will try to explain the client code. One note to make is that I left out the debugging/logging for brevity's sake. So here goes....

We will begin by looking at the file MemMonClient.java, found in the org.apache.mina.example.udp.client java package. The first few lines of the code are simple and straightforward.

connector = new DatagramConnector();
connector.setHandler( this );
ConnectFuture connFuture = connector.connect( new InetSocketAddress("localhost", MemoryMonitor.PORT ));

Here we create a DatagramConnector, set the handler and connect to the server. One gotcha I ran into was that you must set the host in the InetSocketAddress object or else nothing seems to work. This example was mostly written and tested on a Windows XP machine, so things may be different elsewhere. Next we will wait for acknowledgment that the client has connected to the server. Once we know we are connected, we can start writing data to the server. Here is that code:

connFuture.addListener( new IoFutureListener(){
            public void operationComplete(IoFuture future) {
                ConnectFuture connFuture = (ConnectFuture)future;
                if( connFuture.isConnected() ){
                    session = future.getSession();
                    try {
                        sendData();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    log.error("Not connected...exiting");
                }
            }
        });

Here we add a listener to the ConnectFuture object and when we receive a callback that the client has connected, we will start to write data. The writing of data to the server will be handled by a method called sendData. This method is shown below:

private void sendData() throws InterruptedException {
        for( int i=0; i<30; i++ ){
            long free = Runtime.getRuntime().freeMemory();
            ByteBuffer buffer = ByteBuffer.allocate(8);
            buffer.putLong( free );
            buffer.flip();
            session.write( buffer );

            try {
                Thread.sleep( 1000 );
            } catch (InterruptedException e) {
                e.printStackTrace();
                throw new InterruptedException( e.getMessage() );
            }
        }
    }

This method will write the amount of free memory to the server once a second for 30 seconds. Here you can see that we allocate a ByteBuffer large enough to hold a long variable and then place the amount of free memory in the buffer. This buffer is then flipped and written to the server.

Added by Mark Webb, last edited by Trustin Lee on Jun 04, 2007  (view change)