|
Page Edited :
MINA :
UDP Tutorial
UDP Tutorial has been edited by Ashish Paliwal (Dec 01, 2008). Content: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.
Building the codeFor 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. The ApplicationThe figure above depicts the sample UDP server. The Server is listening on the port 18567. The Client connects to the Server and sends the memory usage data. The figure above depicts two clients connected to the Server. The Application Execution Flow
Server Code analysisWe will begin by looking at the code found in the org.apache.mina.example.udp package under mina-examples. To keep life simple, we shall concentrate on MINA related constructs only. To construct the server, we shall have to do the following:
Here is the first snippet that addresses Point# 1: NioDatagramAcceptor acceptor = new NioDatagramAcceptor(); acceptor.setHandler(new MemoryMonitorHandler(this)); Here, we create a NioDatagramAcceptor to listen for incoming Client requests, and set the IoHandler.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. LoggingFilter is a very nice way to see MINA in Action. It generate log statements at various stages, providing an insight into how MINA works. 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);acceptor.bind(new InetSocketAddress(PORT)); Of course the last thing that is required here is to call bind().
Lets look at each of them in detail Session Created Event@Override public void sessionCreated(IoSession session) throws Exception { SocketAddress remoteAddress = session.getRemoteAddress(); server.addClient(remoteAddress); } In the session creation event, we just call addClient() function, which internally adds a Tab to the UI Message Received Event[EMAIL PROTECTED] public void messageReceived(IoSession session, Object message) throws Exception { if (message instanceof IoBuffer) { IoBuffer buffer = (IoBuffer) message; SocketAddress remoteAddress = session.getRemoteAddress(); server.recvUpdate(remoteAddress, buffer.getLong()); } } In the message received event, we just dump the data received in the message. Applications that need to send responses, can process message and write the responses onto session in this function. Session Closed Event@Override public void sessionClosed(IoSession session) throws Exception { System.out.println("Session closed..."); SocketAddress remoteAddress = session.getRemoteAddress(); server.removeClient(remoteAddress); } In the Session Closed, event we just remove the Client tab from the UI Client Code AnalysisIn 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 NioDatagramConnector(); 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(); IoBuffer buffer = IoBuffer.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 IoBuffer 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. |
Unsubscribe or edit your notifications preferences
