【问题标题】:How to wait for more data in libuv?如何在 libuv 中等待更多数据?
【发布时间】:2016-07-24 17:16:34
【问题描述】:

我正在测试服务器的 libuv。

问题是数据将部分到达,我需要等待更多数据。 (这种情况还没有发生,但根据我的经验,我认为它指日可待)

但是这个 libuv 依赖于事件库,以及下一个 after_read() 函数 不保证下一个数据包是剩余的。

我想知道你是如何工作的。 谢谢。


添加以获取更多信息。 我关心的分包情况。

  • 假设客户端 A、客户端 B、服务器 S。

    1. A 向服务器发送 100 个字节。
    2. B 向服务器发送 100 个字节。
    3. S 接收 A 的前 50 个字节。 (在读取回调中)
    4. S 收到 B 的 100 个字节。 (在读取回调中)
    5. S 接收 A 的剩余 50 个字节。 (在读取回调中)

在第 3 步之后,我预计 A 的其余 50 个字节到达,但与我的预期不同,B 的 100 个字节到达。我的目标是将步骤 3(50 字节)+ 步骤 5(50 字节)合并为 A 的全部数据。

【问题讨论】:

    标签: libuv


    【解决方案1】:

    在libuv中你不等待数据,你通过调用uv_read_start请求读取数据,然后当有数据读取时会调用读取回调。如果您的应用程序需要读取完整的数据包,您通常希望使用状态机来了解您所处的状态,并一直缓冲数据直到获得完整的数据包。

    【讨论】:

    • 感谢您的评论,saghul。我知道 uv_read_start 和回调函数的基本特性。但我担心拆分数据包。我在我的帖子中添加了更多解释。我需要管理所有的数据包还是有什么好的方法来处理数据包的顺序和分片?
    • 我认为没有状态机和一些缓冲就无法处理这个问题。对于每个连接,您缓冲 1 个数据包,并在完成之前避免处理。如果您使用 UDP,则需要源地址和数据包缓冲区之间的映射,从而使事情复杂化。 libuv 没有内置工具可以帮助您,因为这是非常特定于应用程序的。
    • 是的。我也认为它是特定于应用程序的,但我担心我的无知而问。此时我正在考虑为每个客户端分配特定大小的缓冲区。谢谢你的建议。
    • 如果你的数据包大小是固定的,那么你可以在 on_alloc 中为整个数据包分配空间,然后在后续调用中传递一个指向剩余缓冲区的指针,直到数据包完成。
    • 我的数据包是动态的,但在第一个字节有一个数据包标记,在下一个字节有一个长度。这样我就可以事先找到整个长度。
    【解决方案2】:

    要处理这个问题,只需使用您需要的任何连接特定信息创建您自己的派生 tcp 类型。

    typedef struct
    {
      uv_tcp_t base;
      int idx;
    } my_tcp_t;
    

    然后 malloc 你的结构并转换它

    my_tcp_t *client = (my_tcp_t*) malloc(sizeof(my_tcp_t));
    client->idx = 2;
    uv_tcp_init(loop, (uv_tcp_t*)client);
    

    idx 变量在读回调中通过强制转换 (my_tcp_t*) 可用。

    【讨论】:

    • 自我上次回复以来已经过去了很多时间。下次我在 libuv 上工作时,我会考虑你的。也许回到那个项目,看起来我实现的和你的类似。谢谢。
    猜你喜欢
    • 2018-05-15
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    相关资源
    最近更新 更多