sockets - Lua 套接字 - 异步事件

标签 sockets lua

在当前的 lua 套接字实现中,我看到我们必须安装一个定期回调的计时器,以便我们检查非阻塞 API 以查看我们是否收到任何内容。

这一切都很好,但是在 UDP 情况下,如果发送者有很多信息正在发送,我们是否有丢失数据的风险。假设另一台设备通过 UDP 发送 2MB 照片,我们每 100 毫秒检查一次套接字接收。在 2MBps 时,在我们的调用查询底层 TCP 堆栈之前,底层系统必须存储 200Kbits。

当我们在特定套接字上接收到数据而不是我们现在必须做的轮询时,有没有办法让事件触发?

最佳答案

有多种方法可以处理此问题;你会选择哪一个取决于你想做多少工作。*

但首先,您应该(对自己)澄清您是在处理 UDP 还是 TCP; UDP 套接字没有“底层 TCP 堆栈”。此外,UDP 是用于发送整个数据(如文本或照片)的错误协议(protocol);它是一个不可靠的协议(protocol),因此不能保证您接收到每个数据包,除非您使用托管套接字库(例如 ENet )。

Lua51/LuaJIT + LuaSocket

轮询是唯一的方法。

  • 阻止:调用socket.select没有时间参数并等待套接字可读。
  • 非阻塞:调用socket.select超时参数为 0 , 并使用 sock:settimeout(0)在您正在读取的套接字上。

  • 然后简单地重复调用这些。
    我建议使用 coroutine scheduler对于非阻塞版本,允许程序的其他部分继续执行而不会造成太多延迟。

    Lua51/LuaJIT + LuaSocket + Lua Lanes (受到推崇的)

    与上述方法相同,但套接字存在于使用 Lua Lanes 制作的另一个 channel 中(另一个线程中的轻量级 Lua 状态) (latest source)。这使您可以立即从套接字读取数据并进入缓冲区。然后,您使用 linda将数据发送到主线程进行处理。

    这可能是您问题的最佳解决方案。

    我做了一个简单的例子,可用 here .它依赖于 Lua Lanes 3.4.0 ( GitHub repo ) 和修补的 LuaSocket 2.0.2 ( source , patch , blog post re' patch )

    结果是有希望的,但如果你从中派生出我的示例代码,你肯定应该重构它。

    LuaJIT + 操作系统特定的套接字

    如果你有点自虐,你可以尝试从头实现一个套接字库。 LuaJITFFI library使这从纯 Lua 成为可能。 Lua Lanes 对此也很有用。

    对于 Windows,我建议查看 William Adam's blog .他在 LuaJIT 和 Windows 开发方面有过一些非常有趣的冒险经历。至于 Linux 和其他,请查看 C 教程或 LuaSocket 的源代码,并将它们转换为 LuaJIT FFI 操作。

    (如果 API 需要,LuaJIT 支持 callbacks;但是,与从 Lua 轮询到 C 相比,存在显着的性能成本。)

    LuaJIT + ENet

    ENet是一个很棒的图书馆。它提供了 TCP 和 UDP 之间的完美组合:需要时可靠,否则不可靠。它还抽象了操作系统特定的细节,就像 LuaSocket 一样。你可以使用 Lua API 来绑定(bind)它,或者直接通过 LuaJIT 的 FFI 访问它(推荐)。

    * 双关语无意。

    关于sockets - Lua 套接字 - 异步事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12889361/

    相关文章:

    sockets - 如何在套接字编程中让系统为我选择端口号?

    java - 将 Java 客户端与 Python 服务器连接

    lua - 将数据位置信息添加到 latex 输出

    java - 将Java函数绑定(bind)到Lua的方法?

    lua - Lua 中 math.random() 和 math.randomseed() 的区别

    python - 如何解决 Alpine docker 容器内 Flask 应用程序的 Gunicorn exec 引发的 'OSError: libc not found'

    sockets - node.js 套接字异常读取 ETIMEDOUT - 如何正确捕获它?写超时怎么办?

    c - Lua 垃圾回收 : Will reassigned userdata have its __gc meta event triggered?

    lua - 在嵌套的 Lua 函数中,upvalues 是如何计算的?

    javascript - 如何在 casper.js 中捕获和测试 socket.io 事件