从TCP套接字读取JPEG字节(Android)

时间:2015-01-21 07:04:02

标签: java android sockets tcp bitmap

我有一个应用程序,可以显示来自手机的CCTV Feed。我成功开发了iOS应用程序,现在我的客户希望我移植到Android。移植很好,直到我陷入这部分代码。

这部分代码,我必须连接到TCP套接字服务器。连接后,我不必向服务器发送任何东西,相反,服务器将向我发送JPEG图像。因此,在连接之后,我必须继续阅读,直到我收到JPEG结束标记(0xFF,0xD9),然后关闭连接。

我打算做的是

Socket s = new Socket("Server IP Addreess", SERVER_PORT);
DataInputStream dis = new DataInputStream(socket.getInputStream());

ArrayList<Byte> bytes = new ArrayList<Byte>();
boolean err = false;

while (true) {
    byte b = dis.readByte();

    if (b == -1) {
        err = true;
        break;
    }        

    bytes.add(b);

    if ((bytes.get(bytes.size() - 1) == (byte) 0xFF) &&
        (bytes.get(bytes.size() - 2) == (byte) 0xD9)) {
        break;
    }
}

socket.close();

if (!err) {
    // create bitmap from byte array and show in ImageView
}

但我不确定这是否正确。我想到的另一个解决方案是

Socket s = new Socket("Server IP Addreess", SERVER_PORT);
BitmapFactory.decodeStream(s.getInputSteam());

但是,当服务器发送0xFF,0xD9时,我也不知道如何关闭套接字。或者BitmapFactory会检测到该标记并为我关闭套接字连接吗?

欢迎任何建议。谢谢!

P.S。当我提供iOS应用程序时,我没有测试环境。因此,我必须开发然后交付给他们进行测试(通过使用应用程序)。然后,如果它不起作用,他们会告诉我纠正它,但我无法访问LogCat或其他有用的信息。这就像在黑暗的房间里缝一个按钮一样,我无法打开灯。

:|

修改

有关此服务器的更多信息

  • 服务器不会发送文件长度,因此,每个文件的字节数是未知的。
  • 我必须检测0xFF,0xD9表示文件结束。
  • 问题是,我必须从我这边终止套接字连接,服务器不会这样做。
  • 我无法改变服务器的工作方式,也就是客户购买的硬件。

另外,我为每个TCP连接获取一个图像,我没有为单个TCP连接获取多个图像。

1 个答案:

答案 0 :(得分:2)

仅查找一些魔术字节来确定数据的结尾是一个坏主意。虽然这些神奇的字节应该在文件的末尾,但它们也可以在数据内部发生。

最好是使用长度为数据添加前缀,或者为每个jpeg文件使用单独的TCP连接,然后只读取直到连接结束(直到您不再获取任何数据)。如果无法做到这一点,则必须进行更高级的解析,请参阅Detect Eof for JPG images