如何在TCPIP协议中精确添加消息长度前缀以实现高效通信?

2026-04-16 17:404阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1043个文字,预计阅读时间需要5分钟。

如何在TCP/IP协议中精确添加消息长度前缀以实现高效通信?

我正在通过TCP/IP发送消息,需要在char数组中为消息长度添加前缀,然后再发送。我应该怎么做?另外,请提供一个如何在另一端提取它的例子。

做法:

1.首先,确定消息的长度。

2.创建一个char数组,长度为消息长度加上前缀的长度(通常为2个字节,用于表示16位长度)。

3.将消息长度转换为字节形式,并填充到char数组的前两个字节。

4.将消息内容追加到char数组中。

5.发送这个包含前缀的消息。

例子:

发送端代码示例(C语言):

c#include #include

int main() { const char *message=Hello, world!; int messageLength=strlen(message); char messageWithLength[2 + messageLength];

// 将消息长度转换为字节形式并填充到前两个字节 messageWithLength[0]=(messageLength >> 8) & 0xFF; messageWithLength[1]=messageLength & 0xFF;

// 将消息内容追加到char数组中 memcpy(messageWithLength + 2, message, messageLength);

// 发送messageWithLength数组 // 发送函数根据实际情况实现,这里仅为示例 sendData(messageWithLength, 2 + messageLength);

return 0;}

void sendData(char *data, int size) { // 实现发送数据的函数}

接收端代码示例(C语言):c#include #include

int main() { char buffer[1024]; int bytesRead;

// 接收数据 bytesRead=recvData(buffer, sizeof(buffer));

if (bytesRead > 0) { // 提取消息长度 int messageLength=(buffer[0] <<8) | buffer[1];

// 提取消息内容 char *message=buffer + 2; printf(Received message: %s\n, message); }

return 0;}

如何在TCP/IP协议中精确添加消息长度前缀以实现高效通信?

int recvData(char *buffer, int bufferSize) { // 实现接收数据的函数 // 这里仅为示例,返回实际接收的字节数 return bufferSize; // 假设接收了整个缓冲区}

解释:- 在发送端,首先计算消息长度,然后将长度转换为字节形式,并填充到char数组的前两个字节。接着,将消息内容复制到这个数组中,最后发送这个数组。- 在接收端,首先接收数据到buffer中,然后从buffer的前两个字节中提取消息长度,最后根据这个长度提取消息内容。

我正在通过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字节,2字节,4字节,可变长度)
>我应该使用什么字节序

我建议使用4个字节的长度和网络字节顺序(即big-endian).对于网络字节顺序,宏htonl和ntohl将在主机(本机)字节顺序(在您的情况下为little-endian)和网络字节顺序之间进行转换.

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

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

标签:前缀

本文共计1043个文字,预计阅读时间需要5分钟。

如何在TCP/IP协议中精确添加消息长度前缀以实现高效通信?

我正在通过TCP/IP发送消息,需要在char数组中为消息长度添加前缀,然后再发送。我应该怎么做?另外,请提供一个如何在另一端提取它的例子。

做法:

1.首先,确定消息的长度。

2.创建一个char数组,长度为消息长度加上前缀的长度(通常为2个字节,用于表示16位长度)。

3.将消息长度转换为字节形式,并填充到char数组的前两个字节。

4.将消息内容追加到char数组中。

5.发送这个包含前缀的消息。

例子:

发送端代码示例(C语言):

c#include #include

int main() { const char *message=Hello, world!; int messageLength=strlen(message); char messageWithLength[2 + messageLength];

// 将消息长度转换为字节形式并填充到前两个字节 messageWithLength[0]=(messageLength >> 8) & 0xFF; messageWithLength[1]=messageLength & 0xFF;

// 将消息内容追加到char数组中 memcpy(messageWithLength + 2, message, messageLength);

// 发送messageWithLength数组 // 发送函数根据实际情况实现,这里仅为示例 sendData(messageWithLength, 2 + messageLength);

return 0;}

void sendData(char *data, int size) { // 实现发送数据的函数}

接收端代码示例(C语言):c#include #include

int main() { char buffer[1024]; int bytesRead;

// 接收数据 bytesRead=recvData(buffer, sizeof(buffer));

if (bytesRead > 0) { // 提取消息长度 int messageLength=(buffer[0] <<8) | buffer[1];

// 提取消息内容 char *message=buffer + 2; printf(Received message: %s\n, message); }

return 0;}

如何在TCP/IP协议中精确添加消息长度前缀以实现高效通信?

int recvData(char *buffer, int bufferSize) { // 实现接收数据的函数 // 这里仅为示例,返回实际接收的字节数 return bufferSize; // 假设接收了整个缓冲区}

解释:- 在发送端,首先计算消息长度,然后将长度转换为字节形式,并填充到char数组的前两个字节。接着,将消息内容复制到这个数组中,最后发送这个数组。- 在接收端,首先接收数据到buffer中,然后从buffer的前两个字节中提取消息长度,最后根据这个长度提取消息内容。

我正在通过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字节,2字节,4字节,可变长度)
>我应该使用什么字节序

我建议使用4个字节的长度和网络字节顺序(即big-endian).对于网络字节顺序,宏htonl和ntohl将在主机(本机)字节顺序(在您的情况下为little-endian)和网络字节顺序之间进行转换.

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

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

标签:前缀