我正在尝试从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
以粗体显示的字节代表确认号,但当我尝试将其转换为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));
答案 0 :(得分:0)
如果您尝试将屏蔽和移位的字节合并到int
或long
,则应该使用逻辑OR运算符|
,而不是逻辑AND &
此外,使用int
的版本将产生负数,因为int
是用Java签名的,而高阶字节是&gt; 127因此将其最高有效位设置为1,这使得整数int为负二进制补码。