java中关于MINA (UDP)

本文深入解析MINA网络应用框架,介绍其基于NIO的工作原理,对比BIO,演示MINA的使用流程,包括IoService配置、过滤器链设定、端口监听及IoHandler业务逻辑编写。同时提供时间服务器和服务端、客户端的编写实例,展示如何处理连接、接收消息及响应。

NIO API是在Java 1.4引入的。MINA是基于NIO编写的。首先要了解NIO与BIO的概念以及区别,NIO代表非阻塞IO,BIO代表着阻塞式IO。具体细节请百度。。。

MINA是一个简单但功能齐全的网络应用框架(其实已经被NettyPK掉了,但都是一类型的东西,很多东西相通的,因为我们单位在用MINA所以优先看这个)。

  • MINA的使用流程:

编写自己的IoService,在这里我们创建IoService的子类。随后编写不同的过滤器(例如关于编解码的过滤器),将这些过滤器添加到过滤器链中,设置当前IoService监听的端口(可以是多个),设置处理器也就是业务逻辑编写的地方。

  • MINA说明:

当客户端向这一端口发送消息,IoService会监听这个端口,并经过过滤链进行处理后,传给IoHandler,在这个处理器中有很多函数,这些函数会在不同情况下触发(连接建立时、接收到消息时、连接关闭时、连接超时时等等)。你需要重写你需要的方法,在里面编写你的业务逻辑。

在这里插入图片描述

  • 一个简单的demo:首先是编写一个服务端

  • 首先是IoService的代码:

    package com.mina;

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.charset.Charset;

    import org.apache.mina.core.service.IoAcceptor;
    import org.apache.mina.filter.codec.ProtocolCodecFilter;
    import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
    import org.apache.mina.filter.logging.LoggingFilter;
    import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

    public class MinaTimeServer {

     public static void main(String[] args) throws IOException {
     	//创建IoService的实例
     	IoAcceptor acceptor = new NioSocketAcceptor();
     	//设置过滤链  日志、编解码
     	acceptor.getFilterChain().addLast("logger", new LoggingFilter());
     	acceptor.getFilterChain().addLast("codec",
     			new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
     	//设置处理器 就是业务逻辑处理的地方
     	acceptor.setHandler(new TimeServerHandler());
     	//让其监听某个端口
     	acceptor.bind(new InetSocketAddress(9123));
     }
    

    }

  • 接下来就是编写这个TimeServerHndler类了

    package com.mina;

    import java.util.Date;
    import org.apache.mina.core.service.IoHandlerAdapter;
    import org.apache.mina.core.session.IdleStatus;
    import org.apache.mina.core.session.IoSession;

    public class TimeServerHandler extends IoHandlerAdapter{
    //设置一个变量
    public static int count=0;

     //当捕获到异常时会触发(这里不做任何处理,仅仅打印一下)
     public void execptionCaught(IoSession session,Throwable cause) throws Exception {	
     	cause.printStackTrace();
     }
     //当接收到数据时触发
     public void messageReceived(IoSession session, Object message) {
     	String mes=message.toString();
     //当接受到的数据是quit时或者用户请求大于2次关闭连接
     if(mes.trim().equalsIgnoreCase("quit")||count>2) {
     	System.out.println("正在退出时间服务器");
     	session.write("正在退出时间服务器。。。。");
     	session.close();
     	return;
     }
         //向客户端回复一个当前时间
     	Date date = new Date();
     	session.write(date.toString());
     	System.out.println("message writen:"+mes);
     	count++;
     }
    

    }

这个时间服务器就写完了。可以在cmd窗口县通过telnet命令向这个端口发送数据,来测试一下。
测试服务端

打开cmd窗口,输入命令Telnet localhost 9123

注意:如果显示这个不是内部命令什么的,先检查拼写,没问题后百度怎么开启电脑的teinet。

输入该命令后窗口如下:

这时可以输入任意字符,会发送到该端口,输入quit退出。或者次数到了后也会自动断开连接。

向服务器发送任意字符,服务器会向你回复一个时间戳。

下面我们自己写一个客户端来和服务端连接。
客户端的编写

客户端和服务器端的编写几乎是一样的,将IoService替换一下,服务器时我们用的是NioSocketAcceptor,客户端我们换成NioSocketConnector。这两个都是IoService的实现类。写法差不多直接上代码:

这是IoService的代码:

package com.minaTcpClient;
 
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
 
public class TcpClient {
 
	public static void main(String[] args) {
		//创建IoService实例
		NioSocketConnector connector = new NioSocketConnector();
		//设置过滤链
		connector.getFilterChain().addLast("logger", new LoggingFilter());
		connector.getFilterChain().addLast("codec",
				new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
		//设置处理器
		connector.setHandler(new TcpClientHandler());
		//连接地址
          ConnectFuture connect = connector.connect(new InetSocketAddress("localhost",9123));
	}
}

下面是TcpClientHandler的代码:

package com.minaTcpClient;
 
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
 
public class TcpClientHandler extends IoHandlerAdapter{
    //会话创建时触发
	public void sessionCreated(IoSession session) throws Exception {
        System.out.println("session  Created");
    }
	//会话打开时触发(第一次连接时先触发sessionCreated函数,后触发本函数)
	 public void sessionOpened(IoSession session) throws Exception {
	       session.write("Hello....");
	    }
	 //当接收到消息时触发
	 public void messageReceived(IoSession session, Object message) throws Exception {
		 System.out.println("收到:"+message.toString());
	        session.write("Received :"+message.toString());
	    }
}
  • 关于UDP协议

UDP协议的写法是一样的,MINA在一定程度上屏蔽了两者的差异。

在编写上只需要将IoService的实现类替换一下

服务器端的NioSocketAcceptor替换为NioDatagramAcceptor

客户端的NioSocketConnector替换为NioDatagramConnector

他们都是IoService的实现类。

转载自:https://blog.youkuaiyun.com/qq_32721817/article/details/81383426

  • 补充:

MINA 可以将UDP的无连接、点对点转变成基于连接的通讯方式。即使在客户端无固定IP的情况下服务端也可以和客户端通讯。需要客户端主动向服务端通讯,建立通讯连接,服务端再通过该连接向客户端通讯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值