参考文章:​​http://blog.chinabyte.com/a/534099.html​

传递对象的原因:个人理解:符合面向对象,服务器接收客户端消息,需要解析,处理,应答,如果传的是对象,可以把解析,处理,应答写在对象里,这么做,扩展性更好.


客户端

1 MinaClient.java

package com.nafio.client;  import java.net.InetSocketAddress; 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.transport.socket.nio.NioSocketConnector;  /**  * @author nafio 2012-08-20  * mina传递对象客户端  */ public class MinaClient {          //使用单例模式  private static MinaClient minaClient = null;  //创建 TCP/IP connector  NioSocketConnector connector = new NioSocketConnector();  //创建接收数据的过滤器  DefaultIoFilterChainBuilder chain = connector.getFilterChain();    //使用单例  //相关的IoHandlerAdapter继承类都采用了单实例模式  //在整个通信过程中做到对象session等实例的单一防止发生“所托非人”的现象//这个不是很理解?  public static MinaClient getInstances() {       if (null == minaClient) {                    minaClient = new MinaClient();       }               return minaClient;      }          private MinaClient() {   //设定这个过滤器将按对象读取数据   chain.addLast("myChin", new ProtocolCodecFilter(         new ObjectSerializationCodecFactory()));              connector.setHandler(ClientHandler.getInstances(connector));//by nafio用于彻底关闭客户端连接   //设定连接超时   connector.setConnectTimeout(30);   //连接服务器   ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",        8888));             }      public static void main(String args[]) {       MinaClient.getInstances();          }     }

2 ClientHandler.java

package com.nafio.client;  import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import org.apache.mina.transport.socket.nio.NioSocketConnector;  import com.nafio.obj.TransferObj;  /**  * @author nafio 2012-08-20  * mina传递对象客户端  */ public class ClientHandler extends IoHandlerAdapter {      private static ClientHandler minaClientHandler = null;   NioSocketConnector connector;//by nafio用于彻底关闭客户端连接  public static ClientHandler getInstances(NioSocketConnector con) {       if (null == minaClientHandler) {    minaClientHandler = new ClientHandler(con);   }   return minaClientHandler;  }          private ClientHandler(NioSocketConnector con) {   connector=con;  }           public void sessionOpened(IoSession session) throws Exception {   //session.write("来自客户端:与服务端会话打开");          System.out.println("客户端:打开了与服务端的会话");   sendMsg(session);  }   //会话结束后触发  public void sessionClosed(IoSession session) {   System.out.println("客户端:与服务端会话结束");  }  //接到返回信息后触发  public void messageReceived(IoSession session, Object message)throws Exception {   System.out.println("客户端:接收到服务端返回信息");  }   //连接创建时触发  public void sessionCreated(IoSession session) throws Exception {   super.sessionCreated(session);   System.out.println("客户端:与服务端连接创建");  }  //连接空闲是触发  public void sessionIdle(IoSession session, IdleStatus status)  throws Exception {   super.sessionIdle(session, status);   System.out.println("客户端:连接空闲");  }  //发送信息后触发  public void messageSent(IoSession arg0, Object arg1) throws Exception {   //System.out.println("客户端:已向服务器发送-->"+(String)arg1);   System.out.println("客户端:发送对象完毕");   arg0.close();//这里实际不能彻底关闭mina2.0需要connector.dispose()才能彻底关闭      connector.dispose();//不需要关闭去掉这两句就ok   System.out.println("客户端:强行关闭连接");  }      /**   * 传送信息   * @param session   * @throws Exception   */  public void sendMsg(IoSession session) throws Exception{   TransferObj transferObj=new TransferObj();   transferObj.setDate("nafio_date");   session.write(transferObj);  }   public void exceptionCaught(IoSession session, Throwable cause)  throws Exception {   super.exceptionCaught(session, cause);  } }

3 TransferObj.java

package com.nafio.obj;  public class TransferObj implements java.io.Serializable{  private String date;          public String getDate() {       return date;         }      public void setDate(String date) {    this.date = date;      }                     }


服务端

1 MinaServer.java

package com.nafio.server;  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.serialization.ObjectSerializationCodecFactory; import org.apache.mina.transport.socket.SocketAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  public class MinaServer {      private static MinaServer minaServer = null;  //创建一个非阻塞的Server端Socket  private SocketAcceptor acceptor = new NioSocketAcceptor();  //创建接收数据的过滤器  private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();          private int bindPort = 8888;    //单例  public static MinaServer getInstances() {       if (null == minaServer) {                   minaServer = new MinaServer();       }               return minaServer;      }          private MinaServer() {               //设定这个过滤器将按对象读取数据   chain.addLast("myChin", new ProtocolCodecFilter(         new ObjectSerializationCodecFactory()));    //设定服务器端的消息处理器:一个MinaServerHandler对象,   acceptor.setHandler(ServerHandler.getInstances());         try {    //绑定端口,启动服务器    acceptor.bind(new InetSocketAddress(bindPort));       } catch (IOException e) {                    e.printStackTrace();       }    System.out.println("服务端:监听端口--->" + bindPort);  }      public static void main(String[] args) throws Exception {       MinaServer.getInstances();          }     }


2 ServerHandler.java

package com.nafio.server;  import org.apache.mina.core.filterchain.IoFilterAdapter; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession;  import com.nafio.obj.TransferObj; //下面两种写法应该等同,不确定? //public class ServerHandler extends IoHandlerAdapter {   public class ServerHandler extends IoFilterAdapter implements IoHandler {      private static ServerHandler samplMinaServerHandler = null;          public static ServerHandler getInstances() {   if (null == samplMinaServerHandler) {        samplMinaServerHandler = new ServerHandler();   }       return samplMinaServerHandler;          }      private ServerHandler() {      }      public void sessionOpened(IoSession session) throws Exception {   }      public void sessionClosed(IoSession session) {   }      public void messageReceived(IoSession session, Object message)throws Exception {         if (message instanceof TransferObj) {    TransferObj obj = (TransferObj) message;        System.out.println("服务端:收到客户端数据--->"+obj.getDate());    }           }      public void exceptionCaught(IoSession arg0, Throwable arg1)throws Exception {          }          public void messageSent(IoSession arg0, Object arg1) throws Exception {         }      public void sessionCreated(IoSession arg0) throws Exception {     }          public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {      }     }

3 TransferObj.java(跟客户端相同,因为客户端和服务端要分开,所以这个类两个工程中都放一个)



彻底关闭mina客户端连接的方法

session.close();

java默认不赞成使用这个方法

这个方法使用后客户端实际还没彻底关闭

mina2.0彻底关闭用connector.dispose();


关于socket长短连接

通常的短连接操作步骤是:

连接→数据传输→关闭连接;

而长连接通常就是:

连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接;

这就要求长连接在没有数据通信时,定时发送数据包(心跳),以维持连接状态,短连接在没有数据传输时直接关闭就行了

所以mina默认应该就是长连接所以默认不关闭.