我正在评估libuv作为我正在编写的C / c ++服务器的库。协议的长度是前缀的,所以只要我能从流中读取32位整数,我就应该知道我应该分配什么大小的缓冲区。文档说可能会多次调用uv_read_start函数。
UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
由于我使用长度前缀协议,一旦我知道缓冲区的正确大小,我想分配它并重新使用它进行后续读取,直到我收到所有字节。用libuv有一个简单的方法吗?现在看起来uv_alloc_cb函数必须要处理这个问题。我可以将缓冲区与流对象关联,而不是将其放在地图中吗?
由于我使用的是长度前缀协议,我根本不想在堆上分配缓冲区,直到我能读取前4个字节(32位)。我是否可以在堆栈上分配大小为4的缓冲区并让uv_read_cb函数实际执行堆分配? uv_read_cb函数是否作为uv_read_start函数的一部分同步调用?如果它在我知道我还没有附加到我的流的缓冲区时似乎能够在堆栈上分配。
答案 0 :(得分:7)
回答我自己的问题。我在libuv邮件列表上找到了答案:https://groups.google.com/forum/#!topic/libuv/fRNQV_QGgaA
如果链接不可用,请在此处复制详细信息:
将您自己的数据结构附加到句柄:
句柄有一个void* data
字段,可供您使用。您可以
使它指向一个存储长度的辅助结构
和缓冲区。
或者,您可以将uv_tcp_t嵌入另一个结构中 使用container_of查找嵌入结构。这不是一个 标准C宏,但你可以在其中找到它的定义和用法示例 libuv / source树。它的好处是它只是做了一些指针 算术,它将您从另一个指针间接级别。
接收缓冲区的堆栈分配:
不,那是不可能的。正确的思考方式就是这样 你的alloc_cb返回一个libuv有时会填充数据的缓冲区 在将来。压力是“某个时候”,因为没有 保证什么时候会发生;它可能是直接的,也可能是 几秒钟(或几分钟)。