我有一个非常奇怪的情况。我将我的Java软件与设备连接起来,我们称之为“黑盒子”(因为我无法查看它或在其中留下痕迹)。我正在寻址特定端口(5550)并在套接字上将命令作为字节序列发送。结果,我从同一插座上的Black Box得到答案。 我的命令和回复都以预定义的方式(根据API)加上前缀并具有XOR校验和。
当我从Windows运行代码时,一切都很好:命令1获取其答复1,命令2获取其答复2。
当我从Android运行代码时(实际上是我的目标 - Windows开始追踪错误)它获得了STRANGE:命令1获得其答复1但命令2没有。当我使用Command 2(非法更改前缀,违反校验和)时,Black Box会按预期做出反应(带有错误回复)。但是,如果从Android发出正确的Command 2,则回复完全错误:错误的前缀和缺少的校验和。
在尝试分析错误时,我尝试了WireShark,这表明在网络接口上,Black Box正在发送RIGHT Reply 2,但是从套接字用Java评估这个回复,这是错误的。如果Command / Reply 1 ???
一切正常,怎么会这样呢?奇怪的是,预期数据的部分存在:
预期:ff fe e4 04 00 11 00 f1
收到: fd fd fd 04 00 11 00 //字节8丢失
我附加简约代码来强制解决问题。什么可以伪造我收到的字节? Java中是否存在Java的“原始”访问权限,可以揭示问题?
我很困惑,所以任何帮助都会受到赞赏:
String address = "192.168.1.10";
int port = 5550;
Socket socket;
OutputStream out;
BufferedReader in;
try {
socket = new Socket(address, port);
out = socket.getOutputStream();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// This is "Command 1" which is receiving the right reply
// byte[] allesAn = new byte[] {(byte)0xff, (byte)0xfe, (byte)0x21, (byte)0x81, (byte)0xa0};
// out.write(allesAn);
// This is "Command 2" which will not receive a right reply
byte[] getLokInfo3 = new byte[] {(byte)0xff, (byte)0xfe, (byte)0xe3, (byte)0, (byte)0, (byte)3, (byte)0xe0};
out.write(getLokInfo3);
out.flush();
while (true) {
String received = "";
final int BufSize = 1000;
char[] buffer = new char[BufSize];
int charsRead = 0;
charsRead = in.read(buffer, 0, BufSize);
// Convert to hex presentation
for (int i=0; i < charsRead; i++) {
byte b = (byte)buffer[i];
received += hexByte((b + 256) % 256) + " ";
}
String result = charsRead + ">" + received + "<";
Log.e("X", "Read: " + result);
}
} catch (Exception e) {
Log.e("X", e.getMessage() + "");
}
与
private static String hexByte(int value) {
String s = Integer.toHexString(value);
return s.length() % 2 == 0 ? s : "0" + s;
}
这是wireshark所说的,显示了预期的8个字节: