MINA 入门介绍
?
? ? Mina处于中间层,它不关心底层网络数据如何传输,只负责接收底层数据,过滤并转换为Java对象提供给我们的应用程序,然后把应用程序响应值过滤并转换为底层识别的字节,提供给底层传输;
------总之:Mina是底层数据传输和用户应用程序交互的接口!
?
?
这个流程图不仅很直观的看出了Mina的工作流程,也涵盖了Mina的三个核心接口:IoService接口,IoFilter接口和IoHandler接口:
第一步. 创建服务对象(客户端或服务端) ?---IoService接口实现
第二步. 数据过滤(编码解码等) ? ? ? ? ?---IOFilter接口实现
第三步. 业务处理 ? ? ? ? ? ? ? ? ? ? ? ?---IoHandler接口实现
? ?
Mina的精髓是IOFilter,它可以进行日志记录,信息过滤,编码解码等操作,把数据接收发送从业务层独立出来。
创建服务对象,则是把NIO繁琐的部分进行封装,提供简洁的接口。
业务处理是我们最关心的部分,跟普通的应用程序没任何分别。
?
package web.sample;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;//负责处理连接上来的客户机,即消息处理器public class MinaServerHandler extends IoHandlerAdapter{ //客户端发送的消息到达时 @Override public void messageReceived(IoSession session, Object message) throws Exception { // TODO Auto-generated method stub String s = (String)message; System.out.println("来自客户端的消息:"+s); session.write(s); } //一个客户端关闭时 @Override public void sessionClosed(IoSession session) throws Exception { // TODO Auto-generated method stub System.out.println("one Client Disconnect"); } //一个客户端接入时 @Override public void sessionCreated(IoSession session) throws Exception { // TODO Auto-generated method stub System.out.println("one Client Connection"); } }
?
package web.sample;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;public class StartServer {public static void main(String[] args) {// 创建一个非阻塞的serever端socket,用NioSocketAcceptor acceptor = new NioSocketAcceptor();// 创建接收数据的过滤器DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();// 设定这个过滤器规则(将一行一行读取数据)chain.addLast("myChin", new ProtocolCodecFilter(new TextLineCodecFactory()));// 设定服务器端的消息处理器:一个MinaServerHandler对象acceptor.setHandler(new MinaServerHandler());// 服务器端绑定的端口int bindPort = 10000;// 绑定端口,启动服务器try {acceptor.bind(new InetSocketAddress(bindPort));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("Mina server is listing on:=" + bindPort);}}
?
1、使用telnet命令来和服务器进行连接,并发送消息,如图所示:
2、使用程序和服务器连接
package web.sample;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.Socket;import java.util.logging.Logger;/* * 使用Socket创建客户端请求 */public class EchoClient01 {// private Logger logger = Logger.getLogger(EchoClient01.class);private String HOST = "localhost";private int PORT = 10000;private Socket socket;public EchoClient01() throws IOException {socket = new Socket(HOST, PORT);}public void talk() throws IOException {try {// 获得服务端响应信息的输入流InputStream socketIn = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(socketIn));// 给服务端发送信息的输出流OutputStream socketOut = socket.getOutputStream();PrintWriter pw = new PrintWriter(socketOut, true);BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));String msg = null;while ((msg = localReader.readLine()) != null) {pw.println(msg);// logger.info(br.readLine());if (msg.equals("bye"))break;}} catch (IOException e) {e.printStackTrace();} finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public static void main(String args[]) throws IOException {new EchoClient01().talk();}}
?
备注:public PrintWriter(OutputStream out,boolean autoFlush),通过现有的 OutputStream 创建新的 PrintWriter。此便捷构造方法创建必要的中间 OutputStreamWriter,后者使用默认字符编码将字符转换为字节。
?
如果只是创建使用这个PrintWriter(OutputStream out)构造方法,则服务器端是收到接收的信息的。
?