MINA使用之UDP篇

 

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源代码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值