我在使用(TCP)套接字传输数据时遇到了一些小问题。以下是我的工作背景:
我正在将数据从A端发送到B端。发送的数据长度可以变化,最大长度为1096字节。
然而,当我这样做时:我意识到A正在发送小块数据...大约80-90字节左右。经过几次发送后,B将它们组合在一起,使接收字节数为1096。这显然会破坏数据并导致混乱。为了解决这个问题,我将我的数据分成两部分:头和数据。
在A方面:
在B端,我首先接收头部并确定要接收的载荷大小,然后接收其余的载荷。
我正在将数据从A端发送到B端。发送的数据长度可以变化,最大长度为1096字节。
A) send(clientFd, buffer, size, NULL)
在B端,由于我不知道期望的大小是多少,所以我总是尝试接收1096字节:
B) int receivedBytes = receive(fd, msgBuff, 1096, NULL)
然而,当我这样做时:我意识到A正在发送小块数据...大约80-90字节左右。经过几次发送后,B将它们组合在一起,使接收字节数为1096。这显然会破坏数据并导致混乱。为了解决这个问题,我将我的数据分成两部分:头和数据。
struct IpcMsg
{
long msgType;
int devId;
uint32_t senderId;
uint16_t size;
uint8_t value[IPC_VALUES_SIZE];
};
在A方面:
A) send(clientFd, buffer, size, NULL)
在B端,我首先接收头部并确定要接收的载荷大小,然后接收其余的载荷。
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);
}
因此,对于每个有有效负载的发送,我最终会调用两次接收。这对我有用,但我想知道有没有更好的做法?
recv
以接收所有数据。 - Some programmer duderecv
进行多次调用,但在现代计算机上,多个send
/recv
调用的性能惩罚是可以忽略不计的(而TCP可能会将两个连续的send
调用的数据放入单个数据包中)。 - Some programmer dudesend
调用不会引入任何网络“延迟”,因为这两个调用的数据将作为一个单独的数据包发送(如果数据量小于MTU)。而且,如果数据被作为一个单独的数据包发送,无论你进行多少次recv
调用,它仍然会从单个数据包中读取。 - Some programmer dude