Introduction
Abbrevation for Mina is ‘Multipurpose Infrastructure for Network Applications’, which is a network application framework to develop highly scalable and performant network applications. In this article, let us see how to create a simple client/server application using Apache Mina 2.0.x.
Required jars
- Apache Mina 2.0.x jars
- slf4j-api.jar
- slf4k-jdk14.jar
Server part
For the server part, Two classes named “MinaServer” and “MinaServerHandler” has been used. The “MinaServer” class contains a main method and an interface named “IoAcceptor” is used to accept the incoming connections from the client and that fires the event to the handler. Two filters has been used, the first one is the “LoggingFilter” which logs all the events and requests and the second one is the “ProtocolCodecFilter” which is used to convert an incoming ByteBuffer into message POJO. The code for the “MinaServer” class is given below,
MinaServer.java
package com.sample.timeserver;
/**
* @author giftsam
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MinaServer
{
private static final int PORT = 1234;
public static void main(String[] args) throws IOException
{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
acceptor.setHandler(new MinaServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.bind(new InetSocketAddress(PORT));
}
}
Next let us create a custom handler named “MinaServerHandler”, which contains four methods. The first method “sessionOpened” is called when the session is opened and it is used to set the session idle time. The second method “receiveMessage” is used to receive the message sent by the client. The other two methods “sessionIdle” is used to close the session when it was idle for 10 secs and the fourth method “exceptionCaught” is used to close the session when an exception occured. The code for the “MinaServerHandler” class is given below,
MinaServerHandler.java
package com.sample.timeserver;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author giftsam
*/
public class MinaServerHandler extends IoHandlerAdapter
{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
@Override
public void sessionOpened(IoSession session)
{
// set idle time to 10 seconds
session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
session.setAttribute("Values: ");
}
@Override
public void messageReceived(IoSession session, Object message)
{
logger.info("Message received in the server..");
logger.info("Message is: " + message.toString());
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
{
logger.info("Disconnecting the idle.");
// disconnect an idle client
session.close();
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
{
// close the connection on exceptional situation
session.close();
}
}
Client part
For the client part “MinaClient” and “MinaClientHandler” class has been used. In the “MinaClient” class the “IoConnector” interface is used to communicate with the server and that fires the event to the handler. Like the server part, The same “LoggingFilter” and “ProtocolCodecFilter” has been used. An interface named “ConnectFuture” is used to windup the asynchronous connection requests.The code for the “MinaClient” class is given below,
MinaClient.java
package com.sample.timeserver;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**
* @author giftsam
*/
public class MinaClient
{
private static final int PORT = 1234;
public static void main(String[] args) throws IOException, InterruptedException
{
IoConnector connector = new NioSocketConnector();
connector.getSessionConfig().setReadBufferSize(2048);
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
connector.setHandler(new MinaClientHandler("Hello Server.."));
ConnectFuture future = connector.connect(new InetSocketAddress("172.108.0.12", PORT));
future.awaitUninterruptibly();
if (!future.isConnected())
{
return;
}
IoSession session = future.getSession();
session.getConfig().setUseReadOperation(true);
session.getCloseFuture().awaitUninterruptibly();
System.out.println("After Writing");
connector.dispose();
}
}
For the handler, Like the server part the same methods “sessionOpened”, “messageReceived” and “exceptionCaught” has been used. The code for the “MinaClientHandler” class is given below,
MinaClientHandler.java
package com.sample.timeserver;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author giftsam
*/
public class MinaClientHandler extends IoHandlerAdapter
{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
private final String values;
private boolean finished;
public MinaClientHandler(String values)
{
this.values = values;
}
public boolean isFinished()
{
return finished;
}
@Override
public void sessionOpened(IoSession session)
{
session.write(values);
}
@Override
public void messageReceived(IoSession session, Object message)
{
logger.info("Message received in the client..");
logger.info("Message is: " + message.toString());
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
{
session.close();
}
}
Now its time to test the preceding codes, First the code “MinaServer” should be executed and then execute the “MinaClient”, the outcome of the codes will looks like the below,
MinaServer – Output
Dec 8, 2010 8:31:49 PM org.apache.mina.filter.logging.LoggingFilter log INFO: CREATED Dec 8, 2010 8:31:49 PM org.apache.mina.filter.logging.LoggingFilter log INFO: OPENED Dec 8, 2010 8:31:49 PM org.apache.mina.filter.logging.LoggingFilter log INFO: RECEIVED: HeapBuffer[pos=0 lim=5 cap=2048: 54 65 73 74 0A] Message received in the server.. Message is: Hello Server.. Dec 8, 2010 8:32:00 PM org.apache.mina.filter.logging.LoggingFilter log INFO: IDLE Dec 8, 2010 8:32:00 PM com.sample.timeserver.TimeServerHandler sessionIdle INFO: Disconnecting the idle. Dec 8, 2010 8:32:00 PM org.apache.mina.filter.logging.LoggingFilter log INFO: CLOSED
MinaClient – Output
Dec 8, 2010 8:31:49 PM org.apache.mina.filter.logging.LoggingFilter log INFO: CREATED Dec 8, 2010 8:31:49 PM org.apache.mina.filter.logging.LoggingFilter log INFO: OPENED Dec 8, 2010 8:31:49 PM org.apache.mina.filter.logging.LoggingFilter log INFO: SENT: HeapBuffer[pos=0 lim=0 cap=0: empty] Dec 8, 2010 8:32:00 PM org.apache.mina.filter.logging.LoggingFilter log INFO: CLOSED Client completed..
Thats all folks. I hope this article clearly explains the simple client/server application using Apache Mina 2.0.x. If you find this article is useful for you, dont forget to leave your valuable comments. Have a joyous code day.
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Since
* @author giftsam
*/
public class MinaServerHandler extends IoHandlerAdapter
{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
@Override
public void sessionOpened(IoSession session)
{
// set idle time to 60 seconds
session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
// initial sum is zero
session.setAttribute(“Values: “);
}
@Override
public void messageReceived(IoSession session, Object message)
{
System.out.println(“Message received in the server..”);
System.out.println(“Message is: ” + message.toString());
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
{
logger.info(“Disconnecting the idle.”);
// disconnect an idle client
session.close();
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
{
// close the connection on exceptional situation
session.close();
}
}
package com.sample.timeserver;
/**
* @Since
* @author giftsam
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MinaServer
{
private static final int PORT = 9123;
public static void main(String[] args) throws IOException
{
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast(“logger”, new LoggingFilter());
acceptor.getFilterChain().addLast(“codec”, new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName(“UTF-8″))));
acceptor.setHandler(new MinaServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.bind(new InetSocketAddress(PORT));
}
}
package com.sample.timeserver;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Since
* @author giftsam
*/
public class MinaClientHandler extends IoHandlerAdapter
{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
private final String values;
private boolean finished;
public MinaClientHandler(String values)
{
this.values = values;
}
public boolean isFinished()
{
return finished;
}
@Override
public void sessionOpened(IoSession session)
{
session.write(values);
}
@Override
public void messageReceived(IoSession session, Object message)
{
logger.info(“Message received in the client..”);
logger.info(“Message is: ” + message.toString());
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
{
session.close();
}
}
package com.sample.timeserver;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Since
* @author giftsam
*/
public class MinaServerHandler extends IoHandlerAdapter
{
private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());
@Override
public void sessionOpened(IoSession session)
{
// set idle time to 60 seconds
session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
// initial sum is zero
session.setAttribute(“Values: “);
}
@Override
public void messageReceived(IoSession session, Object message)
{
System.out.println(“Message received in the server..”);
System.out.println(“Message is: ” + message.toString());
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
{
logger.info(“Disconnecting the idle.”);
// disconnect an idle client
session.close();
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
{
// close the connection on exceptional situation
session.close();
}
}
Output – server
Dec 8, 2010 6:31:49 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: CREATED
Dec 8, 2010 6:31:49 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: OPENED
Dec 8, 2010 6:31:49 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: RECEIVED: HeapBuffer[pos=0 lim=5 cap=2048: 54 65 73 74 0A]
Message received in the server..
Message is: Test
Dec 8, 2010 6:32:00 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: IDLE
Dec 8, 2010 6:32:00 PM com.sample.timeserver.TimeServerHandler sessionIdle
INFO: Disconnecting the idle.
Dec 8, 2010 6:32:00 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: CLOSED
Output – client
Dec 8, 2010 6:31:49 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: CREATED
Dec 8, 2010 6:31:49 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: OPENED
Dec 8, 2010 6:31:49 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
Dec 8, 2010 6:32:00 PM org.apache.mina.filter.logging.LoggingFilter log
INFO: CLOSED
After Writing
[...] Quite some time back, I had wrote an article to create a simple client/server application using Apache Mina 2.0.x. In that article the transaction between the client and server is [...]
Well-loved. Like or Dislike:
13
6
Great Post. I liked the examples that you provided. I never used MINA.. i will give a shot
Well-loved. Like or Dislike:
10
1
[Reply]
I have a java program which compares the data between two text file. These text files are large enough (in GBs) and i have multiple files coming in for comaprision. If i start comparison on one machine it gives me memory error. Is it possible to use MINA in this scenario to distribute the task to multiple machines
[Reply]
giftsam Reply:
December 17th, 2010 at 8:23 pm
Hi Deekay,
Apache MINA is a network application and It provides an abstract event-driven asynchronous API over various transports such as TCP/IP and UDP/IP through Java NIO.
But I reckon your requirement is quite different. Seems you need the concept of load balancing.
[Reply]
rmruano Reply:
August 25th, 2012 at 12:25 am
@deekay: Apache Hadoop, it’s what you were looking for, you can import the data and create a MapReduce Job to distribute the processing between a cluster of servers.
More info at http://hadoop.apache.org/
“The Apache Hadoop software library is a framework that allows for the distributed processing of large data sets across clusters of computers using a simple programming model.”
[Reply]
Very helpfull. I will give it a try to synchronize data to the the server.
But I have a question: ist it possible to use Mina to measure the bandwidth? (with TCP socket on the client side)
[Reply]
How u think MINA performs to apache-commons-http ?
[Reply]
Hi
I want to make a UDP server with multithreading/threadpool support..
Can someone please provide an example
– Anish Sneh
[Reply]
i am new to use apache Mina, so kindly let me know using the above code, i will set the connection. how to transfer file for that i should use normal tcp\ip java program.
[Reply]
Hi,
Great post and simple implementation for TCP/IP.
We have to use Apache MINA for HTTP protocol, can you share similar example/code/sample for client and server.
[Reply]
Can someone help me how to write a multithreaded server listening on multiple ports using Apache Mina pls?
[Reply]
hi,
Can someone provide sample code for http server implementaion using apache mina.
[Reply]
Hi…thanks for sharing
I’m need to implement a Client that can handle reconnection in case comunication with the server is lost…Any suggestions
Thanks again
[Reply]
i copied this sample program , compiled and tried to execute. But don’t see the output. It just hangs .
[Reply]
This is a very simple and very helpful post to understand the apace mina.
Thanx a lot
[Reply]
Hi,
I tryed this example ,its working very well.
Problem:
1. if ssl client and server are using different .jks file, then server will through an exception like “Invalid certificate”
2. Another scenario is actually my SSL client is in C++,here Mina SSL Server is able to accept any kind of message from C++ SSL Client even though client is using different(invalid certificate) certificate.
Please help me to resolve this issues,its very urgent for me.
[Reply]
What does the RECEIVED and SENT in the log actually signify ? Sometimes the entered data is split across two RECEIVED; this seems to match a wireshark trace as there are two frames going in. In a server implementation of mine, I notice that whenever such a split occurs, messageReceived is not invoked…sort of keeps waiting endlessly. Anyway, I can tackle this ?
[Reply]
Good post,
i have nver used the mina socket connetion, can u tell the advantage of Mina socket over normal socket connetion, so in future i can use this.
[Reply]
your explanation and example is very good…and excellent…i want to run that client program on user defined port..can you pls tell me how to do that???
[Reply]
Thanks for the nice example. It makes it very easy to get started with Mina.
I want to warn anyone else that tries this code that there is a hard-coded IP address in the MinaClient class
new InetSocketAddress(“172.108.0.12″, PORT)
that will need to be changed to the appropriate IP for your testing. I used 127.0.0.1 and the client and server began talking together.
[Reply]