【问题标题】:Reading 4 bytes from InputStreamReader从 InputStreamReader 读取 4 个字节
【发布时间】: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不应该负责完整性检查等等吗?

标签: java byte checksum


【解决方案1】:

InputStreamReader 将读取基于字符的数据。您必须编写自定义 InputStream 并从中读取 x 个字节。

【讨论】:

    猜你喜欢
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 2011-01-26
    • 2015-10-25
    • 1970-01-01
    • 2013-01-07
    • 2017-05-28
    相关资源
    最近更新 更多