關於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中的是一樣的。

就是這些,弄了一天,一直在寫字節數,自己手動算來算去的,麻煩死了。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章