日期:2014-05-17  浏览次数:20954 次

基于Apache Mina实现的TCP长连接和短连接实例

1、前言

Apache MINA是Apache组织的一个优秀的项目。MINA是Multipurpose Infrastructure for NetworkApplications的缩写。它是一个网络应用程序框架,用来帮助用户非常方便地开发高性能和高可靠性的网络应用程序。在本文中介绍了如何通过Apache Mina2.0来实现TCP协议长连接和短连接应用。

2、系统介绍

2.1系统框架

整个系统由两个服务端程序和两个客户端程序组成。分别实现TCP长连接和短连接通信。

系统业务逻辑是一个客户端与服务端建立长连接,一个客户端与服务端建立短连接。数据从短连接客户端经过服务端发送到长连接客户端,并从长连接客户端接收响应数据。当收到响应数据后断开连接。

系统架构图如下:

2.2处理流程

系统处理流程如下:

1)???????启动服务端程序,监听8001和8002端口。

2)???????长连接客户端向服务端8002端口建立连接,服务端将连接对象保存到共享内存中。由于采用长连接方式,连接对象是唯一的。

3)???????短连接客户端向服务端8001端口建立连接。建立连接后创建一个连接对象。

4)???????短连接客户端连接成功后发送数据。服务端接收到数据后从共享内存中得到长连接方式的连接对象,使用此对象向长连接客户端发送数据。发送前将短连接对象设为长连接对象的属性值。

5)???????长连接客户端接收到数据后返回响应数据。服务端从长连接对象的属性中取得短连接对象,通过此对象将响应数据发送给短连接客户端。

6)???????短连接客户端收到响应数据后,关闭连接。

3、服务端程序

3.1长连接服务端

服务启动

public class?MinaLongConnServer {

private static final int?PORT?= 8002;

?

????public void?start()throws?IOException{

?????? IoAcceptor acceptor =?new?NioSocketAcceptor();

?

?????? acceptor.getFilterChain().addLast("logger",?new?LoggingFilter());

?????? acceptor.getFilterChain().addLast("codec",?newProtocolCodecFilter(newTextLineCodecFactory(Charset.forName("UTF-8"))));

?

?????? acceptor.setHandler(new?MinaLongConnServerHandler());

?????? acceptor.getSessionConfig().setReadBufferSize(2048);

?????? acceptor.bind(new?InetSocketAddress(PORT));

?????? System.out.println("Listeningon port " +?PORT);

??? }

}

消息处理

public class?MinaLongConnServerHandler?extends?IoHandlerAdapter {

????private final?Logger logger = (Logger) LoggerFactory.getLogger(getClass());

?

??? @Override

????public void?sessionOpened(IoSession session) {

?????? InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();

?????? String clientIp = remoteAddress.getAddress().getHostAddress();

?????? logger.info("LongConnect Server opened Session ID ="+String.valueOf(session.getId()));

?????? logger.info("接收来自客户端 :" + clientIp + "的连接.");

?????? Initialization init = Initialization.getInstance();

?????? HashMap<String, IoSession> clientMap =init.getClientMap();

?????? clientMap.put(clientIp, session);

??? }

?

??? @Override

????public void?messageReceived(IoSession session, Object message) {

?????? logger.info("Messagereceived in the long connect server..");

?????? String expression = message.toString();

?????? logger.info("Message is:" + expression);

?????? IoSession shortConnSession =(IoSession) session.getAttribute("shortConnSession");

?????? logger.info("ShortConnect Server Session ID ="+String.valueOf(shortConnSession.getId()));

?????? shortConnSession.write(expression);

??? }

?

??? @Override

????public void?sessionIdle(IoSession session, IdleStatus status) {

?????? logger.info("Disconnectingthe idle.");

?????? // disconnect an idle client

?????? session.close(true);

??? }

?

??? @Override

????public void?exceptionCaught(