gpt4 book ai didi

c# - 如何正确接收分片的TCP数据?

转载 作者:可可西里 更新时间:2023-11-01 02:57:45 26 4
gpt4 key购买 nike

我尝试通过 TCP 从网络摄像头发送实时视频流。发送前我用JPG压缩了图片;效果很好。但是我的接收器 socket 有问题。它以某种方式只能在接收端获得完整图像的四分之一。

解码我收到的字节数组后看起来像这样:

enter image description here

我已经编写了以下代码来接收图像数据(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,我如何改进接收器代码?

最佳答案

修复

你应该只“写”你收到的字节

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);

关于c# - 如何正确接收分片的TCP数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42462940/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com