我想從我的Android應用程序中的TCP/IP數據包中提取確認編號。我將原始數據以字節形式存儲爲ByteBuffer
。讀取TCP確認編號
作爲一個例子,讓我們看看下面的TCP/IP分組:(這是字節的原始TCP數據)
140 174 20 102 249 178 241 231 **238 84 109 14** 128 24 1 91 240 54 0 0 1 1 8 10 0 43 86 97 209 144 51 108 0 0 35
粗體字節表示確認號,但是當我嘗試將其轉換到int
或long
,我得到一個負數。這就是我最初在那裏a
,b
,c
試過了,d
是代表應答號的4個字節:
this.ackNumber = ((a & 0xFF) << 24) + ((b & 0xFF) << 16) + ((c & 0xFF) << 8) + (d & 0xFF);
看到那之後,沒有工作,我試圖做一步一步來像這樣:
byte a = packet.get(); // -18
byte b = packet.get(); // 84
byte c = packet.get(); // 109
byte d = packet.get(); // 14
Log.e(TAG, "A: " + a + " B: " + b + " C: " + c + " D: " + d);
int ia = a & 0xFF; // 238
int ib = b & 0xFF; // 84
int ic = c & 0xFF; // 109
int id = d & 0xFF; // 14
Log.e(TAG, "IA: " + ia + " IB: " + ib + " IC: " + ic + " ID: " + id);
ia = ia << 24; // -301989888
ib = ib << 16; // 5505024
ic = ic << 8; // 27904
id = id << 0; // 14
Log.e(TAG, "LIA: " + ia + " LIB: " + ib + " LIC: " + ic + " LID: " + id);
long la = (long)ia & 0x00000000FF000000; // -301989888
long lb = ib & 0x00FF0000; // 5505024
long lc = ic & 0x0000FF00; // 27904
long ld = id & 0x000000FF; // 14
Log.e(TAG, "ALIA: " + la + " ALIB: " + lb + " ALIC: " + lc + " ALID: " + ld);
此代碼仍返回不正確的數字。我究竟做錯了什麼?
編輯:
我設法由十六進制這樣之後增加的L簡單地得到正確的數字:
long la = (long)ia & 0x00000000FF000000L;
合併他們這樣兩種工作方式:
Log.e(TAG, "Ack: " + (la + lb + lc + ld) + " Ack: " + (la | lb | lc | ld));
沒有理由爲什麼TCP序列號不能爲負數。這是一個。 – EJP
序列號不能小於零。根據這個問題的答案http://stackoverflow.com/a/2672750/4893507當他們達到最大值時,他們重置爲0. – TychoTheTaco
最大值是2^32-1,而不是2^31-1。 TCP序列號[佔據未簽名的32位空間](https://tools.ietf.org/html/rfc793#page-24)。這個以0x80000000開頭,所以*就Java'int'而言*是否定的。 – EJP