gpt4 book ai didi

c++ - 通过 TCP 套接字接收可变大小的数据

转载 作者:可可西里 更新时间:2023-11-01 18:35:43 28 4
gpt4 key购买 nike

我在通过 (TCP) 套接字传输数据时遇到了一个小问题。我在做什么的小背景:

我正在从 A 端向 B 端发送数据。发送的数据可以是可变长度的,假设最大大小为 1096 字节。

A) send(clientFd, buffer, size, NULL)

在 B 上,因为我不知道期望的大小,所以我总是尝试接收 1096 字节:

B) int receivedBytes = receive(fd, msgBuff, 1096, NULL)

但是,当我这样做时:我意识到 A 正在发送小块数据……比如大约 80-90 字节。在几次突发发送后,B 将它们组合在一起,接收到的字节数为 1096。这显然损坏了数据,并且一团糟。

为了解决这个问题,我将数据分为两部分: header 和数据。

struct IpcMsg
{
long msgType;
int devId;
uint32_t senderId;
uint16_t size;
uint8_t value[IPC_VALUES_SIZE];
};

一侧:

A) send(clientFd, buffer, size, NULL)

在 B 上,我首先接收 header 并确定要接收的有效载荷的大小:然后接收其余的有效载荷。

B) int receivedBytes = receive(fd, msgBuff, sizeof(IpcMsg) - sizeof( ((IpcMsg*)0)->value ), 0);
int sizeToPoll = ((IpcMsg*)buffer)->size;
printf("Size to poll: %d\n", sizeToPoll);

if (sizeToPoll != 0)
{
bytesRead = recv(clientFd, buffer + receivedBytes, sizeToPoll, 0);
}

因此,对于每个具有有效负载的发送,我最终都会调用两次接收。这对我有用,但我想知道是否有更好的方法?

最佳答案

您的想法是正确的,即发送一个 header ,其中包含有关以下数据的基本信息,然后是数据本身。然而,这并不总是有效:

int receivedBytes = receive(fd, msgBuff, sizeof(IpcMsg) - sizeof( ((IpcMsg*)0)->value ), 0);
int sizeToPoll = ((IpcMsg*)buffer)->size;

原因是 TCP 可以根据它自己对应用于所谓的拥塞控制策略的底层网络条件的评估,自由地将您的 header 分段并发送到它认为合适的 block 中。在 LAN 上,您几乎总是会在一个数据包中获得 header ,但通过互联网在全局范围内尝试使用它,您一次获得的字节数可能会少得多。

答案是不直接调用 TCP 的“接收”(通常是 recv),而是将其抽象为一个小的实用函数,该函数采用您真正必须接收的大小和一个缓冲区来放入它。进入循环接收和附加数据包,直到所有数据都到达或发生错误。

如果您需要异步并同时为多个客户端提供服务,则适用相同的主体,但您需要调查“选择”调用,以便在数据到达时通知您。

关于c++ - 通过 TCP 套接字接收可变大小的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25803444/

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