【发布时间】:2015-04-01 17:07:35
【问题描述】:
我遇到了问题。我正在使用 Java 开发一个简单的多线程 TCP 服务器,我目前遇到了这个问题:
客户端可以给我一个输入字符串,比如
[IDENTIFIER] 文本\r\n
没关系,我已经完成了。每个输入查询都需要以 \r\n 结束,除了一种情况。
这种情况是客户端将图像作为二进制数据发送。此消息具有以下结构:
PHOTO[空格][数据长度][空格][数据][BIG ENDIAN中4字节校验和]
关键是要么返回一个
202 好的\r\n
校验和匹配数据中的位总和时的消息,或者...
302 错误校验和\r\n
...否则。但是,我在读取 4 个字节时遇到了一些严重的问题。 输入源是 InputStreamReader 的一个实例,获取自:
in = new InputStreamReader(this.clientSocket.getInputStream());
和函数 InputStreamReader.read() 返回刚刚读取的 char 的 int。现在,我尝试了
correctChecksumBytes = new byte[4];
for( int i = 0 ; i < 4 ; ++i ) {
correctChecksumBytes[i] = (byte) in.read();
}
if (correctChecksumBytes == null) {
throw new BadSyntax();
}
bb = ByteBuffer.wrap(correctChecksumBytes);
bb.order(ByteOrder.BIG_ENDIAN);
fourByteCheck = bb.getInt();
但是,我现在明白,转换从 in.read() 返回的 int 是错误的,因为结果相差很大。我被引导相信 ByteBuffer 的使用是正确的,我只是不知道如何用正确的值填充字节数组。
我也尝试将 InputSreamReader 转换为字节数组,但我发现这不是一个有效的方法,因为一条消息......
PHOTO[space][length of data][space][data][4 bytes of checksum in BIG ENDIAN][IDENTIFIER] text\r\n
...有效,需要解释为 2 条消息。
我做了一些测试,发现我成功地读取了所有数据并计算了有效的校验和,因此输入中接下来的 4 个字节是校验和的 4 个字节,我还没有设法读取。
另外,这是一个有效的 PHOTO 消息示例
照片 8 ABCDEFGH\x00\x00\x02\x24
所以我想问一下,如何读取这 4 个字节并将它们转换为 int 以与计算的校验和进行比较?
非常感谢
【问题讨论】:
-
你有一个
InputStreamReader。那是一个阅读器——你不是从阅读器那里读取bytes,而是阅读text。在我看来,您应该重新考虑一下您的协议,以便更清楚地将二进制数据与文本数据分开。例如,通常每个“消息”都有一个标题,其中包含一些二进制数据,然后是正文……您会将正文读取为字节数组,但如果正文本身是文本,您将构造一个阅读器在它上面(例如,通过 InputStreamReader 包装 ByteArrayInputStream)。 -
TCP不应该负责完整性检查等等吗?