MINA框架开发入门--简单易用的基于TCP/IP通信的JAVA框架

简单介绍

MINA是apache下的一个开源项目,是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。

mina下载

下载地址:http://mina.apache.org/downloads-mina.html

image.png

下载最新版本zip包后解压。

image.png

解压后的文件路径,lib文件夹是其依赖的jar,dist文件夹里是mina核心的jar。

现在我们主要需要两个,一个核心jar的mina-core-2.0.19.jar,一个日志jar的slf4j-api-1.7.25.jar。


创建一个简单的java工程mina-project

完成的工程如下

image.png


mina服务端消息处理器

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());
	}
}


此时就可以启动服务端。

image.png


使用命令行测试服务端消息接收情况

打开cmd,输入 telnet localhost 9999 回车,如下图

image.png  image.png

输入:hello

服务端就会接收到消息:

image.png

并处理后返回给客户端。客户端不继续处理,直接打印:

image.png

测试完成服务端可以正常通信。


写客户端

然后我们也可以自己写客户端,具体代码如下:

客户端的消息处理器

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();
	}
}


同样启动客户端

image.png

服务端此时也可以看到客户端打开的消息

image.png


可以接着在客户端输入一句话,比如:hello,mina ,然后回车,如下图

image.png

服务端收到消息,加了个 return,返回给了客户端,如下

image.png

客户端收到消息“return:hello,mina”。


到此,客户端与服务器端就可以正常通信交互了

评论

*
*