经过了一天的研究之后,把想到的东西写出来,防止自己忘记,因为太乱了...
首先,开始举例:
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中的是一样的。
就是这些,弄了一天,一直在写字节数,自己手动算来算去的,麻烦死了。。