gpt4 book ai didi

c++ - 如何在 TCP/IP 中为消息长度添加前缀

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

我通过 TCP/IP 发送消息,我需要在 char 数组中添加消息长度前缀,然后发送它。我该怎么做?

您还可以提供一个示例,说明如何在另一端提取它。如果可能,请解释一下。

我正在使用 C++ 和 Winsock。

编辑:

string writeBuffer = "Hello";

unsigned __int32 length = htonl(writeBuffer.length());

它没有返回正确的长度,而是一个非常大的数字。

对于接收部分,如果我使用 ntohl(),那么我也会得到一个大数字而不是正确的长度?为什么呢?我收到这样的

bool Server::Receive(unsigned int socketIndex)
{
// Read data from the socket
if (receivingLength)
{
bytesReceived = recv(socketArray[socketIndex - WSA_WAIT_EVENT_0],
((char*)&messageLength) + bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived, 0);

if (bytesReceived == SOCKET_ERROR)
{
return false;
}

if (bytesReceived == MESSAGE_LENGTH_SIZE)
{
// If uncomment the following line,
// I won't get the correct length, but a large number
//messageLength = ntohl(messageLength);
receivingLength = false;
bytesReceived = 0;
bytesLeft = messageLength;
}
}
else
{
if (bytesLeft > BUFFER_SIZE)
{
return false;
}

bytesReceived = recv(socketArray[socketIndex - WSA_WAIT_EVENT_0],
&receiveBuffer[bytesReceived], bytesLeft, 0);

if (bytesReceived == SOCKET_ERROR)
{
return false;
}

if (bytesReceived == messageLength)
{
// we have received full message
messageReceived = true;

receiveBuffer[bytesReceived] = '\0';

// wait for next message
receivingLength = true;
}

bytesLeft -= bytesReceived;
}

return true;
}

最佳答案

在 TCP 流上发送长度字段时,您需要决定两件事:

  1. length应该有多少长度(1字节,2字节,4字节,可变长度)
  2. 我应该使用哪种字节序

我建议使用 4 字节长度和网络字节顺序(即大端)。对于网络字节顺序,宏 htonl 和 ntohl 将在主机( native )字节顺序(在您的情况下为小端字节序)和网络字节顺序之间进行转换。

要发送数据,片段应如下所示:

size_t length = strlen(data);
uint32_t nlength = htonl(length);
send(sock, &nlength, 4, 0);
send(sock, data, length, 0);

在接收端,首先提取长度,然后提取数据:

uint32_t length, nlength;
recv(sock, &nlength, 4, 0);
length = ntohl(nlength);
data = malloc(length+1);
recv(sock, data, length, 0);
data[length] = 0;

这段代码缺少的是错误处理:每个发送和接收调用都可能失败; recvs 收到的数据可能少于预期。但这应该给你一个想法。

编辑:为了处理 recv 返回的数据太少的情况,在循环中运行它,记录到目前为止您已阅读的内容,例如

int length_bytes = 0;
while(length_bytes < 4){
int read = recv(sock, ((char*)&nLength)+length_bytes, 4-length_bytes, 0);
if (read == -1) some_error_occurred_check_errno();
length_bytes += read;
}

关于c++ - 如何在 TCP/IP 中为消息长度添加前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1339270/

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