读取TCP确认号码

时间:2016-07-08 05:56:35

标签: java android tcp packet

我正在尝试从Android应用中的TCP / IP数据包中提取确认号。我将原始数据以字节存储为ByteBuffer

举个例子,让我们看看下面的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

以粗体显示的字节代表确认号,但当我尝试将其转换为intlong时,我会得到一个负数。这是我最初尝试的abcd是表示确认号码的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));

1 个答案:

答案 0 :(得分:0)

如果您尝试将屏蔽和移位的字节合并到intlong,则应该使用逻辑OR运算符|,而不是逻辑AND &

此外,使用int的版本将产生负数,因为int是用Java签名的,而高阶字节是&gt; 127因此将其最高有效位设置为1,这使得整数int为负二进制补码。