5

我正在评估 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 函数的一部分同步调用?如果是这样,当我知道我的流还没有附加缓冲区时,我应该能够在堆栈上进行分配。

4

1 回答 1

9

回答我自己的问题。我在这里的 libuv 邮件列表中找到了答案:https ://groups.google.com/forum/#!topic/libuv/fRNQV_QGgaA

如果链接不可用,请在此处复制详细信息:

将您自己的数据结构附加到句柄:

句柄有一个void* data您可以使用的字段。你可以让它指向一个存储长度和缓冲区的辅助结构。

或者,您可以将 uv_tcp_t 嵌入到另一个结构中,然后使用 container_of 查找嵌入结构。它不是标准的 C 宏,但您可以在 libuv/ 源代码树中找到它的定义和使用示例。它的好处是它只是做一些指针运算,它使你免于另一个级别的指针间接。

接收缓冲区的堆栈分配:

不,那是不可能的。正确的思考方式是你的 alloc_cb 返回一个缓冲区,libuv 将在未来的某个时间填充数据。压力在于“某个时候”,因为无法保证何时会发生;它可能是即时的,也可能是几秒钟(或几分钟)之后。

于 2013-10-07T16:47:15.220 回答