MINA是apache下的一个开源项目,是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。
下载地址:http://mina.apache.org/downloads-mina.html
下载最新版本zip包后解压。
解压后的文件路径,lib文件夹是其依赖的jar,dist文件夹里是mina核心的jar。
现在我们主要需要两个,一个核心jar的mina-core-2.0.19.jar,一个日志jar的slf4j-api-1.7.25.jar。
完成的工程如下
package com.mina; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; /** * 服务器端的消息处理器 * 重写最基本的三个父类方法 * @author tgf * */ public class ServerHandler extends IoHandlerAdapter{ /** * 服务端的消息接收 */ @Override public void messageReceived(IoSession session, Object message) throws Exception { super.messageReceived(session, message); String msg = (String) message; System.out.println("服务端的接收到消息:" + msg); // 收到消息后,处理并返回给客户端 msg = "return:" + msg; session.write(msg); } /** * 一次会话的客户端连接关闭 */ @Override public void sessionClosed(IoSession session) throws Exception { super.sessionClosed(session); System.out.println("会话客户端关闭:" + session.getRemoteAddress()); } /** * 一次会话的客户端连接打开 */ @Override public void sessionOpened(IoSession session) throws Exception { super.sessionOpened(session); System.out.println("会话客户端打开:" + session.getRemoteAddress()); } }
package com.mina; import java.io.IOException; import java.net.InetSocketAddress; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.SocketAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; /** * mina 服务端 * @author tgf * */ public class MinaServer { public static void main(String[] args) { // 创建一个非阻塞的server端socket连接,并使用NIO SocketAcceptor acceptor = new NioSocketAcceptor(); // 设置接收的消息类型的过滤器 DefaultIoFilterChainBuilder filterChain = acceptor.getFilterChain(); // 定义一个文本类型的过滤器 filterChain.addLast("codecFilter", new ProtocolCodecFilter(new TextLineCodecFactory())); // 设置服务器端的消息处理器 acceptor.setHandler(new ServerHandler()); // 绑定端口 acceptor.setDefaultLocalAddress(new InetSocketAddress(9999)); try { // 启动 acceptor.bind(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("mina 服务端启动,监听端口:" + acceptor.getDefaultLocalAddress().getPort()); } }
此时就可以启动服务端。
打开cmd,输入 telnet localhost 9999 回车,如下图
输入:hello
服务端就会接收到消息:
并处理后返回给客户端。客户端不继续处理,直接打印:
测试完成服务端可以正常通信。
然后我们也可以自己写客户端,具体代码如下:
客户端的消息处理器
package com.mina; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; /** * mina客户端消息处理器 * 同样的重写父类方法 * @author tgf * */ public class ClientHandler extends IoHandlerAdapter{ /** * 客户端的消息接收 */ @Override public void messageReceived(IoSession session, Object message) throws Exception { super.messageReceived(session, message); String msg = (String) message; // 收到消息后,直接打印 System.out.println("客户端的接收到消息:" + msg); } /** * 客户端的连接关闭 */ @Override public void sessionClosed(IoSession session) throws Exception { super.sessionClosed(session); System.out.println("客户端的连接关闭"); } /** * 客户端的连接打开 */ @Override public void sessionOpened(IoSession session) throws Exception { super.sessionOpened(session); System.out.println("客户端的连接打开"); } }
客户端连接:
package com.mina; import java.net.InetSocketAddress; import java.util.Scanner; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.SocketConnector; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class MinaClient { public static void main(String[] args) { // 客户端用connector 创建连接 SocketConnector connector = new NioSocketConnector(); // 设置接收的消息类型的过滤器 DefaultIoFilterChainBuilder filterChain = connector.getFilterChain(); // 定义一个文本类型的过滤器(与服务器端一致) filterChain.addLast("codecFilter", new ProtocolCodecFilter(new TextLineCodecFactory())); // 设置客户端的消息处理器 connector.setHandler(new ClientHandler()); // 连接超时时间 connector.setConnectTimeoutMillis(10000); // 连接到服务器 ConnectFuture cf = connector.connect(new InetSocketAddress(9999)); // 等待连接(长连接) cf.awaitUninterruptibly(); Scanner input = new Scanner(System.in); while (true) { System.out.println("请输入:"); String msg = input.nextLine();//此句会阻塞 cf.getSession().write(msg); } // 等待服务器连接关闭,客户端结束长连接 //cf.getSession().getCloseFuture().awaitUninterruptibly(); // 直接关闭连接 //connector.dispose(); } }
同样启动客户端
服务端此时也可以看到客户端打开的消息
可以接着在客户端输入一句话,比如:hello,mina ,然后回车,如下图
服务端收到消息,加了个 return,返回给了客户端,如下
客户端收到消息“return:hello,mina”。
到此,客户端与服务器端就可以正常通信交互了
评论