终于是意识到了不写技术博客以及在学完某一样东西而不去练习加以巩固的坏处了!
这些天在开发山寨QQ,所以想用JAVA里面的mina框架,可是自己压根就没怎么练习用过而且也没做什么笔记,于是开始在Google上大肆搜查,终于算是弄得差不多了,所以得写篇博客,免得以后再找……
一.mina框架简介
Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中。
二.Mina的通信模式
由于我是使用的是对象的传送;所以这里只列对象传送
二.如何使用
1.下载mina压缩包,大家可以在http://mina.apache.org下载mina;现在最新的版本是2.0
2.将里面的jar包导入工程;
3.做完了这两步还不能用,如果我们写好程序启动之后会报以下错误:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60) at org.apache.mina.core.service.SimpleIoProcessorPool.<clinit>(SimpleIoProcessorPool.java:81) at org.apache.mina.core.polling.AbstractPollingIoAcceptor.<init>(AbstractPollingIoAcceptor.java:104) at org.apache.mina.transport.socket.nio.NioSocketAcceptor.<init>(NioSocketAcceptor.java:66) at minaserver.MinaServer.main(MinaServer.java:19) Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) ... 5 more |
很明显是找不到org/slf4j/impl/StaticLoggerBinder 这个类,那么就需要我们再引入一个jar包,所以还需另外下载slf4j-nop-1.5.2.jar引入到工程中才行。
4.当一切工作做好了之后就可以写我们的mina服务器和客户端了
服务器端JAVA源码:
类MinaServer:
import java.net.InetSocketAddress; import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; 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 :张立冬 */ public class MinaServer { public static void main(String[] args) throws Exception{ //创建一个非阻塞的Server端Socket,用NIO SocketAcceptor acceptor = new NioSocketAcceptor(); //创建接收数据的过滤器 DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); //设定这个过滤器将以对象为单位读取数据 ProtocolCodecFilter filter= new ProtocolCodecFilter(new ObjectSerializationCodecFactory()); chain.addLast("objectFilter",filter); //设定服务器端的消息处理器:一个SamplMinaServerHandler对象, acceptor.setHandler(new ServerIOListener()); // 服务器端绑定的端口 int bindPort=9988; //绑定端口,启动服务器 acceptor.bind(new InetSocketAddress(bindPort)); System.out.println("Mina Server is Listing on:= " + bindPort); } } |
类ServerIOListener:
import java.util.ArrayList; import java.util.List; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; /** * 基于Mina框架的通信 服务器端的通信事件监听器 * 1.完成了通信消息的处理逻辑 * @author:张立冬 */ public class ServerIOListener extends IoHandlerAdapter{ //保存与客户端的会话队列对象 private List<IoSession> sessions=new ArrayList(); public void sessionCreated(IoSession session) throws Exception { System.out.println("连结己创建!"); } public void sessionOpened(IoSession session) throws Exception { //将新会话对象加入队列 sessions.add(session); System.out.println("连结己打开!:"); this.SendMsg(session); } public void sessionClosed(IoSession session) throws Exception { System.out.println("连结己关闭!:"); } public void SendMsg(IoSession session) throws Exception{ // User user=new User(); // user.setUserID(4); // user.setUserName("服务器"); // session.write(user); } // 发送消息给服务器 public void messageSent(IoSession session,Object message) throws Exception { System.out.println("服务器端发过去的是:"+message.toString()); } public void messageReceived(IoSession session, Object message) throws Exception { // String msg=message.toString()+"\r\n"; // if(msg.equals("bye")){ // //从队列中找出session,然后close掉即可! // } // // //要发给其它所有用户去 // for(IoSession otherSession:sessions){ // if(session.getId()!=otherSession.getId()){ // otherSession.write(msg); // } // } // // User user=(User)message; // // System.out.println("收到消息: "+user.toString()); } } |
客户端JAVA源码:
类MinaClient:
import java.net.InetSocketAddress; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; 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.serialization.ObjectSerializationCodecFactory; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.transport.socket.nio.NioSocketConnector; public class MinaClient { private static final Log log = LogFactory.getLog(MinaClient.class); /** * @param args */ public static void main(String[] args) { //实际应用中,这里可以生成一个线程来监听 // Create TCP/IP connector. NioSocketConnector connector = new NioSocketConnector(); // 创建接收数据的过滤器 DefaultIoFilterChainBuilder chain = connector.getFilterChain(); //设定这个过滤器将以对象为单位读取数据 ProtocolCodecFilter filter= new ProtocolCodecFilter(new ObjectSerializationCodecFactory()); chain.addLast("objectFilter",filter); ClientHandler hand=new ClientHandler(); //设定服务器端的消息处理器:一个SamplMinaServerHandler对象, connector.setHandler(hand); //连结到服务器: try { ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 9988)); cf.awaitUninterruptibly(); cf.getSession().getCloseFuture().awaitUninterruptibly(); connector.broadcast("ddfdf"); } catch(Exception e) { connector.dispose(); log.error("未能连接到服务器"); } } } .类ClientHandler import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; public class ClientHandler extends IoHandlerAdapter throws IOException{ // 当一个客端端连结进入时 private static final Log log = LogFactory .getLog(ClientHandler.class); public void sessionOpened(IoSession session) throws Exception { log.info("server : " + session.getRemoteAddress()); // try { // this.SendMsg(session); // } catch (Exception e) { // e.printStackTrace(); // } } // 当一个客户端关闭时 public void sessionClosed(IoSession session) { log.info("one server Disconnect !"); } // 当服务器端发送的消息到达时: public void messageReceived(IoSession session, Object message) throws Exception { User user = (User) message; System.out.println("接收到服务器发过来的用户对象是:"+user.toString()); } // 发送消息给服务器 public void messageSent(IoSession session,Object message) throws Exception { System.out.println("客户端发过去的是:"+message.toString()); } // 发送消息异常 public void exceptionCaught(IoSession session, Throwable cause) { session.close(); } public void SendMsg(IoSession session) throws Exception{ User user=new User(); user.setUserID(1); user.setUserName("张立冬"); session.write(user); } // //sessiong空闲 // public void sessionIdle( IoSession session, IdleStatus status ) // { // } // 创建 session public void sessionCreated(IoSession session) { } }
|