IoAccepter 相当于网络应用程序中的服务器端
IoConnector 相当于客户端
IoSession 当前客户端到服务器端的一个连接实例
IoHandler 业务处理逻辑
IoFilter 过滤器用于悬接通讯层接口与业务层接口
服务器端:MinaServer.java
public class MinaServer {
private static final int SERVER_PORT = 9990;
public static void main(String[] args) throws Throwable{
//服务端入口
IoAcceptor acceptor = new SocketAcceptor();
SocketAcceptorConfig cfg = new SocketAcceptorConfig();
cfg.setReuseAddress(true);
//设定这个过滤器将以对象为单位读取数据
cfg.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
//添加日志过滤器
cfg.getFilterChain().addLast("logger", new LoggingFilter());
//接收访问的连接和到IoHandler触发事件
acceptor.bind(new InetSocketAddress(SERVER_PORT),new ServerHandler(), cfg);
System.out.println("The server Listening on port " + SERVER_PORT);
}
}
服务器端业务处理类:
public class ServerHandler extends IoHandlerAdapter
{
/**
* 有新连接时触发
*/
public void sessionOpened(IoSession session) {
System.out.println("sessionOpened");
}
/**
* 收到来自客户端的消息
*/
public void messageReceived(IoSession session, Object message) {
System.out.println("server messageReceived!");
CityMessage cm = (CityMessage)message;
System.out.println(cm.getCode()+":"+cm.getName());
//将消息发向客户端
session.write(cm);
}
/**
* 当有异常发生时触发
*/
public void exceptionCaught(IoSession session, Throwable cause) {
session.close();
}
/**
* 连接被关闭时触发
*/
public void sessionClosed(IoSession ssn) throws Exception {
System.out.println("session closed from " + ssn.getRemoteAddress());
}
}
要发送的消息对象:
public class CityMessage implements Serializable{
private int code;
private String name;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
客户端:
public class MinaClient {
private static final String HOSTNAME = "localhost";
private static final int PORT = 9990;
public static void main( String[] args ) throws Throwable{
//Connector为客户端入口
SocketConnector connector = new SocketConnector();
SocketConnectorConfig cfg = new SocketConnectorConfig();
//设定这个过滤器将以对象为单位读取数据
cfg.getFilterChain().addLast("codec",
new ProtocolCodecFilter( new ObjectSerializationCodecFactory() ) );
//添加日志过滤器
cfg.getFilterChain().addLast( "logger", new LoggingFilter() );
//向远程服务器发起连接,触发事件到IoHandler
connector.connect(new InetSocketAddress( HOSTNAME, PORT ),
new ClientHandler(), cfg );
}
}
客户端业务处理类:
public class ClientHandler extends IoHandlerAdapter {
public ClientHandler() {
super();
}
/**
* 有新连接时触发
*/
public void sessionOpened(IoSession session) {
// 创建一个cityMessage发送
CityMessage cm = new CityMessage();
cm.setCode(547600);
cm.setName("凤山");
session.write(cm);
}
/**
* 收到来自客户端的消息
*/
public void messageReceived(IoSession session, Object message) {
System.out.println("client messageReceived!");
CityMessage cm = (CityMessage)message;
System.out.println(cm.getCode()+":"+cm.getName());
}
/**
* 当有异常发生时触发
*/
public void exceptionCaught(IoSession session, Throwable cause) {
session.close();
}
/**
* 连接被关闭时触发
*/
public void sessionClosed(IoSession ssn) throws Exception {
System.out.println("session closed from " + ssn.getRemoteAddress());
}
}
开发一个Mina应用,简单的说,就是创建连结,设定过滤规则,编写自己的消息处理器这三步!
过滤器:
ObjectSerializationCodecFactory:设定这个过滤器将以对象为单位读取数据。
TextLineCodecFactory:设定这个过滤器将一行一行(/r/n)的读取数据
注意:(摘抄自网上) 由apache mina建立的socket不管是采用TCP或是UDP,在Filter不添加codec选项的情况下,由IoHandlerAdapter派生的处理handler 类中public void messageReceived(IoSession session, Object message){}函数里的message对象是IoBuffer的实例,如下:
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
if (! (message instanceof IoBuffer)) {
return;
}
IoBuffer rb = (IoBuffer) message;
callback.messageReceived(java.nio.ByteBuffer.wrap(rb.array(), 0, rb.buf().limit()));
}
如果你使用mina建立一个socket添加了如下:
IoFilter CODEC_FILTER = new ProtocolCodecFilter(
new TextLineCodecFactory());
connector(acceptor).getFilterChain().addLast("codec", CODEC_FILTER);
如果发送数据的socket不是同样的设置或者不是利用mina建立的socket则发送数据的时候需要在数据末尾添加‘\n’,以表示字符串结束。
文章来源:
http://java999.blog.51cto.com/259217/148287