mina 框架知识点部分整理

    之前做个一段时间的游戏开发,用到了mina通讯框架,怕久了忘记,这里整理下知识点。第一个就是搞清楚他的核心nio,但是讲这个就必须先搞清楚bio。jdk1.4之前用的是阻塞-BIO,jdk1.4之后引入NIO-非阻塞IO, jdk1.7后引入了 AIO-异步非阻塞IO。BIO相信大家入门时都写过:

     

while(true){
           Socket s = socket.accept();
          //操作s
          //new Thread(s);
          //s.read();
          //s.write();
     }

bio编程时需要一个线程去循环检测是否有新的socket连接进来,连接进来后socket就放入新的线程或者连接池。所以socket个数和线程个数M:N,M>N。bio是面相流的,建立链接,读取,写入都是同步阻塞的。这就意味着对方处理数据较慢或者网络传输数据较慢时,处理这个请求的线程只有阻塞等待。就算用了线程池,也会把线程吃完,后续处理不能正常进行。

nio socket编程

    将通道和对应的事件会一起注册到selector上。事件分四种:服务器接收客户端连接,客户端连接服务器,读事件,写事件。所有的事件都可以共用一个selector,也可以分开。

while(true){
   int n=selector.select();
   if(n>0){
          //取出就绪通道
          //判断事件类型
          //处理对应事件
     }
}

    selector选择器也需要一个线程去轮训是否有就绪的通道。原来程序要读取对方传来的数据时,需要阻塞等待对方的流数据在网卡组装好后,才能读取。就像你要下楼等到快递员给你送快递。而nio是当程序需要读取数据时,只需要将读取事件和通道一起注册到选择器上,选择器一直轮训你关心的数据准备好没有。当数据到达网卡且准备好时,就被轮训出来。 当有就绪通道时,就把通道里面的数据读到缓冲区里面。通道是否就绪,是由操作系统决定的。

mina通讯框架的粘包和断包问题

什么是粘包,断包问题?

TCP是面相字节流的,他的消息是无边界概念的,就好比文章没有标点符号,没有分段,全部粘在一起。那么发送方发送好几个包,接收方当作一个包一次性接收,就叫粘包。而当发送方发送的数据太大时,又不的不拆成几个包分开发送,就叫断包。那怎么解决呢?

     1,常见的就是用特殊分隔符分割。比如\r\n之类的。

     2,还有就是把消息的长度加到消息头部。

//封包
public void encode(IoSession session, Object message,
			ProtocolEncoderOutput out) throws Exception {
		Map retm = (Map) message;
		//map转字节数组
		byte[] bytes = gzipMsg(retm);
		//消息长度
		int  len = bytes.length;
		IoBuffer buf = IoBuffer.allocate(len+4);
		buf.setAutoExpand(true);
		//把长度加消息开头
		writeInt(buf, len);
		buf.put(bytes);
		buf.flip();
		out.write(buf);
	}

//拆包
@Override
	public MessageDecoderResult decodable(IoSession session, IoBuffer buf) {
		return messageComplete(buf) ? MessageDecoderResult.OK
				: MessageDecoderResult.NEED_DATA;
	}

	private boolean messageComplete(IoBuffer in) {
		int remaining = in.remaining();

		log.info("remaining:" + remaining);
		if (remaining < 6)
			return false;
		//读取消息头
		int len = readInt(in);
		//看本次收到的消息完整吗
		if (len > in.remaining())
			return false;
		return true;//不完成就继续接收

	}

	@Override
	public MessageDecoderResult decode(IoSession session, IoBuffer buf,
			ProtocolDecoderOutput out) throws Exception {
		// Try to decode body
		int length = readInt(buf);
		if (length < 6)
			return MessageDecoderResult.NEED_DATA;
		if (length > 128 * 1024)
			return MessageDecoderResult.NOT_OK;

		byte[] message = new byte[length];
		buf.get(message);
		out.write(message);
		message = null;
		return MessageDecoderResult.OK;

	}

未完待续...

时间: 2024-09-17 05:46:02

mina 框架知识点部分整理的相关文章

javanio-有人对mina框架有很深的理解吗?

问题描述 有人对mina框架有很深的理解吗? 有人知道mina的框架吗,如果使用mina框架的话,如何实现多服务.多协议同时运行的问题? 解决方案 我也在研究这个,可以一起讨论

Mina框架IoService通用抽象服务详解

IoService是对通信双方所进行的I/O操作的抽象,那么无论是在服务器端还是在客户端,都要进行I/O的读写操作,它们有一些共性,可以抽象出来.这里,我们主要详细说明IoAccectpr和IoConnector以及所基于的IoService抽象服务,都提供哪些操作和数据结构,都是如何构建的.首先,提供一个IoService服务接口相关的继承层次关系的类图,如图所示: 最终使用的Acceptor和Connector是上面继承层次中最下层的实现类. IoService抽象 实际上,支持I/O操作服

使用Mina框架开发QQ Android 客户端(3) 登陆功能的实现

在博客中有登陆界面的文章http://blog.csdn.net/vestigge/article/details/8124674 就不在重复了,直接看登陆的代码, 用Mina传递字符串上节已经看过了,要实现传递对象,也非常简单,只需要修改一下过滤器: chain.addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory())); 在Android客户端,登陆的Activity中: publ

使用Mina框架开发QQ Android 客户端(2) 客户端与服务端的通信

一个简单的例子,对Mina框架有了大体的了解,在上节的基础上,看看 怎样实现客户端与服务端的通信, 废话不多说了,直接看代码: public class Test { public static void main(String[] args) throws Exception{ SocketConnector connector = new NioSocketConnector(); IoFilter filter = new ProtocolCodecFilter(new TextLineC

java mina框架传输10k左右的字节数组的问题

问题描述 java mina框架传输10k左右的字节数组的问题 我用mina传递一个10k左右的字节数组,格式是自己定位的,里面包含报文长度,文件和校验字节,客户端和服务端都分别设置了readBufferSize为10240,但是客户端发往服务端时,每次只能接受1k多一点,要循环接收9次左右,效率太低了,设置了readBufferSize为10240,目的就是为了 一次接受完毕的,但是要循环接受好多次,请问大神这是为什么啊? 解决方案 一般来说,sendbuf 和 recvbuf代表发送和接收缓

线程-Mina框架死锁检测算法的原理?

问题描述 Mina框架死锁检测算法的原理? 30C private void checkDeadLock() { if (!(this instanceof CloseFuture || this instanceof WriteFuture || this instanceof ReadFuture || this instanceof ConnectFuture)) { return; } StackTraceElement[] stackTrace = Thread.currentThre

客户端发送信息给Mina框架的服务器端

问题描述 客户端发送信息给Mina框架的服务器端 IOS GCDSocket 可以连接mina服务器端,但是IOS发送信息mina服务器已经接收到了数据流,但是触发mina的messageReceived(IoSession session, Object message )方法,望大家解决一下,谢谢!下面贴上控制台打印的代码: 图片说明

【APACHE MINA2.0开发之一】搭建APACHE MINA框架并实现SERVER与CLIENT端的简单消息传递!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/apache-mina/831.html Hibernate系列学习阶段到此结束了,那么紧接着进入Apache Mina的开发学习,很多童鞋在微薄和QQ中疑问Himi为什么突然脱离游戏开发了,嘿嘿,其实可能更多的童鞋已经看出来了,Himi在偏向服务器Server端开发了,Hibernate.MySQL等都是为了Server端Mina开发而做的

MIna框架I/O Filter Chain层设计

I/O Filter Chain层是介于I/O Service层与I/O Handler层之间的一层,从它的命名上可以看出,这个层可以根据实际应用的需要,设置一组IoFilter来对I/O Service层与I/O Handler层之间传输数据进行过滤,任何需要在这两层之间进行处理的逻辑都可以放到IoFilter中.我们看一下IoFilter的抽象层次设计,如图所示: 通过上述类图可见,要实现一个自定义的IoFilter,一般是直接实现IoFilterAdapter类.同时,Mina也给出了几类