我尝试通过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,我怎样才能改进接收器代码?
答案 0 :(得分:3)
<强> FIX 强>
您应该只“写”您收到的字节
将bw.Write(buffer)
更改为
bw.Write(buffer, 0, available);
<强>加速比强>
您可以直接将网络数据读入缓冲区,而不是在多个缓冲区之间移动接收到的数据。
int bytesToRead = BitConverter.ToInt32(buffer, 0);
int offset = 0;
byte[] frame = new byte[bytesToRead];
while (bytesToRead > 0)
{
var n = clientSocket.Receive(frame, offset, bytesToRead);
offset += n;
bytesToRead -= n;
}
NetworkPacket.deserialize(frame);