成像有一堆协议(protocol)和一些整齐覆盖的 c/cpp 代码 在每一层发送。每个发送函数使用下面的层添加 另一个标题,直到整个消息最终被放入 第 0 层上的连续全局缓冲区:
void SendLayer2(void * payload, unsigned int payload_length)
{
Layer2Header header; /* eat some stack */
const int msg_length = sizeof(header) + payload_length;
char msg[msg_length]; /* and have some more */
memset(msg, 0, sizeof(msg));
header.whatever = 42;
memcpy(&buffer[sizeof(header)], payload, payload_length);
SendLayer1(buffer, msg_length);
}
void SendLayer1(void * payload, unsigned int payload_length)
{
Layer1Header header; /* eat some stack */
const int msg_length = sizeof(header) + payload_length;
char msg[msg_length]; /* and have some more */
memset(msg, 0, sizeof(msg));
header.whatever = 42;
memcpy(&buffer[sizeof(header)], payload, payload_length);
SendLayer0(buffer, msg_length);
}
现在数据被移动到某个全局变量并实际传输:
char globalSendBuffer[MAX_MSG_SIZE];
void SendLayer0(void * payload, unsigned int payload_length)
{
// Some clever locking for the global buffer goes here
memcpy(globalSendBuffer, payload, payload_length);
SendDataViaCopper(globalSendBuffer, payload_length);
}
我想同时减少堆栈使用和 memcpy() 的数量 代码,所以我想是这样的:
void SendLayer2(void * payload, unsigned int payload_length)
{
Layer2Header * header = GetHeader2Pointer();
header->whatever = 42;
void * buffer = GetPayload2Pointer();
memcpy(buffer, payload, payload_length);
...
}
我的想法是在底部设置一些东西,通过连续从 MAX_MSG_SIZE 中减去并让上层代码直接从结束/右侧。
这听起来合理吗?是否有替代的、也许更优雅的方法?
最佳答案
您可能对这篇文章感兴趣:"Network Buffers and Memory Management"艾伦考克斯。基本上,您有缓冲区和几个指向该缓冲区不同有趣部分的指针:协议(protocol) header 、数据……最初,您通过将数据指针设置为 (buffer_start + max_headers_size) 为 header 保留一些空间,并且每一层都有一个指针更接近缓冲区的开始。
我确定 BSD 的 mbufs 在某处一定有类似的描述。
编辑:
David Miller(Linux 网络维护者)有这篇文章 "How SKBs work"
关于c - 通过直接写入下面的发送缓冲区来保存堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3303121/