从 TCP 套接字读取 JPEG 字节 (Android)
Read JPEG bytes from TCP socket (Android)
我有一个应用程序可以显示来自移动设备的闭路电视信号。我成功开发了 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 连接获取多个图像。
只查找一些魔法字节来确定数据的结尾是个坏主意。虽然这些魔术字节应该在文件的末尾,但它们也可以出现在数据内部。
更好的方法是在数据前加上长度前缀,或者为每个 jpeg 文件使用单独的 TCP 连接,然后一直读取直到连接结束(即直到您不再获得任何数据)。如果这不可能,您必须进行更高级的解析,请参阅 Detect Eof for JPG images。
我有一个应用程序可以显示来自移动设备的闭路电视信号。我成功开发了 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 连接获取多个图像。
只查找一些魔法字节来确定数据的结尾是个坏主意。虽然这些魔术字节应该在文件的末尾,但它们也可以出现在数据内部。
更好的方法是在数据前加上长度前缀,或者为每个 jpeg 文件使用单独的 TCP 连接,然后一直读取直到连接结束(即直到您不再获得任何数据)。如果这不可能,您必须进行更高级的解析,请参阅 Detect Eof for JPG images。