【发布时间】:2017-02-25 23:36:36
【问题描述】:
我尝试通过 TCP 从网络摄像头发送实时视频流。我在发送前用 JPG 压缩图像;效果很好。但是我的接收器插座有问题。不知何故,它只能在接收端获得四分之一的完整图像。
解码收到的字节数组后是这样的:
我还编写了以下代码来接收图像数据(receive 在线程中运行):
private void receive() {
try {
while(running) {
if((available = clientSocket.Receive(buffer, 4, SocketFlags.None)) >= 0) {
int bytesToRead = BitConverter.ToInt32(buffer, 0);
using(MemoryStream ms = new MemoryStream(bytesToRead)) {
using(BinaryWriter bw = new BinaryWriter(ms)) {
while(bytesToRead > 0) {
if((available = clientSocket.Receive(buffer, getRemainingBytes(bytesToRead), SocketFlags.None)) >= 0) {
bw.Write(buffer);
bytesToRead -= available;
}
}
NetworkPacket.deserialize(ms.ToArray());
}
}
}
}
} catch(Exception ex) {
Logger.Log(Level.WARNING, "Could not receive data from TCP server.", ex);
}
}
private int getRemainingBytes(int bytesToRead) {
if(bytesToRead > clientSocket.ReceiveBufferSize) {
return clientSocket.ReceiveBufferSize;
} else {
return bytesToRead;
}
}
您可以猜到,我的消息结构的前 4 个字节 (Int32) 定义了我必须为每个图像读取的数据包长度(它们在 30-40kB 之间)。
如果我使用 clientSocket.Receive(buffer, 4, SocketFlags.None) 仅读取缓冲数据的前 4 个字节,剩下的数据在幕后会发生什么?是否可以在第二次“clientSocket.Receive(...)”调用中读取它们,或者在第二次调用“clientSocket.Receive(...)”时删除第一次调用的剩余字节?
假设每秒大约有 30 个图像到达每个 30-40kB 大小的图像,我该如何改进接收器代码?
【问题讨论】:
-
我想知道鉴于系统的性质,UDP 是否会是更好的选择?如果你必须坚持使用 TCP,使用 async/await 不仅效率更高,而且可以降低丢失数据的风险
-
是的,可以讨论使用像 UDP 这样的无连接协议;但这是我想解决的一个基本问题。好的,我会看看 async/await 并报告回来。