MINA是什么?
MINA是JAVA非阻塞通讯模式框架(http://hi.baidu.com/yhzhw2121/blog/item/61506c420efb7a189313c619.html这里有详细说明非阻塞和阻塞通讯的区别),由APACHE组织开发。目前此类开源框架有很多各有利弊本人之所以选择MINA的主要原因是因为他出自APACHE之手。
本文主要介绍的MINA版本是2.0M6可以在http://mina.apache.org/index.html这里下载最新版本的MINA。
网上关于MINA的资料很少,UDP方式的就更少,下面是我几天学习中简单总结的DEMO以后会继续完善,希望能给初学者提供一些帮助,更希望大侠给指点,先谢过··
程序主要分为SERVER端和CLINET端
SERVER由MINA实现,CLINET端由JAVA的普通UDP链接(MINA也可以实现CLINET端)
SERVER端代又分为两部分,一部分为监听端,另一部分为处理端(MINA用到的其他JAR包有slf4j-jdk,slf4j-api)
监听端代码:
public class MemoryMonitorTest {
private static final long serialVersionUID = 1L;
public static final int PORT = 8080;
public MemoryMonitorTest() throws IOException {
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();//创建一个UDP的接收器
acceptor.setHandler(new YourHandler());//设置接收器的处理程序
Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池
acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
DatagramSessionConfig dcfg = acceptor.getSessionConfig();//建立连接的配置文件
dcfg.setReadBufferSize(4096);//设置接收最大字节默认2048
dcfg.setReceiveBufferSize(1024);//设置输入缓冲区的大小
dcfg.setSendBufferSize(1024);//设置输出缓冲区的大小
dcfg.setReuseAddress(true);//设置每一个非主监听连接的端口可以重用
acceptor.bind(new InetSocketAddress(PORT));//绑定端口
}
public static void main(String[] args) throws IOException {
new MemoryMonitorTest();
}
server建立连接后,server端--》filter--》handler
处理端代码:
public class YourHandler extends IoHandlerAdapter {
//messageSent是Server响应给Clinet成功后触发的事件
@Override
public void messageSent(IoSession session, Object message) throws Exception {
if (message instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) message;
byte[] bb = buffer.array();
for (int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
}
}
}
//抛出异常触发的事件
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
cause.printStackTrace();
session.close(true);
}
//Server接收到UDP请求触发的事件
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println("messageReceived");
if (message instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) message;
// byte[] bb = buffer.array();
// for(int i=0;i<bb.length;i++) {
// System.out.print((char)bb[i]);
// }
IoBuffer buffer1 = IoBuffer.wrap("11".getBytes());//返回信息给Clinet端
session.write(buffer1);
//声明这里message必须为IoBuffer类型
}
}
//连接关闭触发的事件
@Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
//建立连接触发的事件
@Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
SocketAddress remoteAddress = session.getRemoteAddress();
System.out.println(remoteAddress);
}
//会话空闲
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
//打开连接触发的事件,它与sessionCreated的区别在于,一个连接地址(A)第一次请求Server会建立一个Session默认超时时间为1分钟,此时若未达到超时时间这个连接地址(A)再一次向Server发送请求即是sessionOpened(连接地址(A)第一次向Server发送请求或者连接超时后向Server发送请求时会同时触发sessionCreated和sessionOpened两个事件)
@Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session Opened...");
SocketAddress remoteAddress = session.getRemoteAddress();
System.out.println(remoteAddress);
}
Client端代码:Client端代码不做解释
public void send(String host, int port) {
try {
InetAddress ia = InetAddress.getByName(host);
DatagramSocket socket = new DatagramSocket(9999);
socket.connect(ia, port);
byte[] buffer = new byte[1024];
buffer = ("22")
.getBytes();
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
System.out.println(dp.getLength());
DatagramPacket dp1 = new DatagramPacket(new byte[22312], 22312);
socket.send(dp);
socket.receive(dp1);
byte[] bb = dp1.getData();
for (int i = 0; i < dp1.getLength(); i++) {
System.out.print((char) bb[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
注意:UDP为无连接协议,因此Clinet向Server发送请求得到响应后会立即断开,Server端中的Session一定要设置超时系统默认为一分钟,如果需要保持连接可以让Client设置心跳(Clinet心跳时间<=Server端Session超时时间)
参考资料:
http://blog.csdn.net/junhuo/archive/2008/10/20/3106260.aspx http://amozon.javaeye.com/blog/326169
http://mina.apache.org/udp-tutorial.html
http://topic.csdn.net/u/20080910/12/9538228d-0b18-40f3-96b8-c2221ac9f9cc.html
以及MINA包中的练习和MINA源代码。