关于mina框架中的request和response中的getlen和offset的理解

在使用mina的时候对于客户端和服务器端的请求和响应部分的长度设定不是很清晰

经过了一天的研究之后,把想到的东西写出来,防止自己忘记,因为太乱了...

首先,开始举例:

public int getLen(Charset charset) {
  int len = 2;
  try {
   //真实数据区
   if (events != null && events.length > 0) {
    for (int i = 0; i < events.length; i++) {
     BattleFieldDto edt = events[i];
     len +=  2 + 4 + 1 + 1 + 1 + 1  +edt.getLen(charset);
    }
   }
  } catch (Exception e) {
   logger.error("错误...", e);
  }
  return len;
 }

 @Override
 public int getDataOffset() {
  int len = 1 + 4 + 2 ;
  if (events != null && events.length > 0) {
   len += events.length * (2 + 4 + 1 + 1 + 1 + 1);
  }
  return len;
 }
}

 这是一段response中的代码片段,首先看getLen中的Len的定义,这里写的是Len = 2,因为在events中的循环的关系,这个2其实是循环的次数的一个short,就是2位,专门存放循环用的;往下来,len += 2 + 4 + 1 + 1 + 1 + 1 +edt.getLen(charset);这里的2 是一个short,4是存放String的offset的int,然后是String的长度为1个byte,1是一个byte,1是一个byte,1是一个byte,后边的edt.getLen(charset);是一个string,由于mina的协议String的存放有点说法,所以就加在了这里,这里应该是直接发包出去的实际的数据形式,也就是说除了报文头和报文长度的有效传输包的长度。

而继续看这个getDataOffset函数:

int len = 1 + 4 + 2 ;这里的1是报文头,4是报文长度,2和getLen里的len定义时的2一个东西,他俩应该是一致的。

接着看:

len += events.length * (2 + 4 + 1 + 1 + 1 + 1);

这里的events就是报文的循环体了,但是注意,这里和刚才的2 + 4 + 1 + 1 + 1 + 1 +edt.getLen(charset);是一样的,为什么呢,就是因为String的特殊存储方式,一个String的存储是由4个字节的偏移量和1个字节的String的长度来构成的,取String的时候首先要getInt()取得4个字节的偏移量,在偏移量的下一个byte也就是get()出1个字节的String的长度,就可以getString(1个字节的长度,charset)取得String了。

说到这里,特殊的就是4 + 1 ,这个代表了一个String,如果events中存在多个String,那么这里将是多个4 + 1,而在getLen中却不会出现4+1,只会出现多个edt.getLen(charset);而已。

接下来就是request的:

	public int getLen(Charset charset) {
		int len = 4 + 1 + 1;
		try {
			if (player_nickname != null && !"".equals(player_nickname)) {
				len += player_nickname.getBytes(charset).length;
			}
		} catch (Exception e) {
			logger.error("错误...", e);
		}
		return len;
	}

	@Override
	public int getDataOffset() {
		int len = 1 + 4 + 4 + 1 + 1;
		return len;
	}

注意看,这里的getLen中的len定义的时候是 4 + 1 + 1,分别是一个int,一个byte,和一个String的长度,长度是一个byte,如果这里边有String的话一定要多出来一个byte来记录这个String的长度,如果有2个String的话要在后边继续添加一个byte,而String要统一放在最后边一起进行相加,还是协议的关系,String类型不能放在基本数据区,只有java的8个原始数据类型才可以放在基本数据区。

然后再看 getDataOffset,这里的len定义的是:1是报文头,4是报文长度,然后后边的4 + 1 + 1就是getLen中的len定义的了,其他的跟response中的是一样的。

就是这些,弄了一天,一直在写字节数,自己手动算来算去的,麻烦死了。。

你可能感兴趣的:(框架,exception,String,Mina,byte,events)