0Pricing
Lua Academy · 课时

使用 luasocket 实现非阻塞 I/O

以非阻塞模式使用 luasocket,并将其集成到协程调度器中。

使用 luasocket 实现非阻塞 I/O 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。

什么是 Lua 套接字库

Lua 套接字库是一个提供 TCP/UDP 套接字、超文本传输协议、FTP 和 SMTP 客户端的 Lua 库。默认情况下它会阻塞;启用非阻塞模式后即可进行异步输入/输出。

安装 Lua 套接字库

通过 LuaRocks 安装:luarocks install luasocket。在脚本中导入它。

local socket = require("socket")
local tcp = socket.tcp()

创建 TCP 套接字

创建 TCP 客户端套接字并连接到服务器。

local tcp = socket.tcp()
tcp:connect("example.com", 80)
tcp:send("GET / HTTP/1.0\r\nHost: example.com\r\n\r\n")
local response = tcp:receive("*a")
tcp:close()
print(response:sub(1, 200))

非阻塞模式

使用 tcp:settimeout(0) 将套接字设置为非阻塞模式。如果没有数据就绪,读取和写入会立即返回超时错误。

tcp:settimeout(0)  -- non-blocking
local data, err = tcp:receive(1024)
if err == "timeout" then
  -- no data yet, try again later
elseif data then
  print("Got:", data)
end

协程集成

将非阻塞套接字与协程结合:数据未就绪时执行 yield,选择器指示就绪后恢复协程。

local function readAsync(sock)
  while true do
    local data, err = sock:receive(1024)
    if data then return data end
    if err ~= "timeout" then error(err) end
    coroutine.yield()  -- let other tasks run
  end
end

socket.select

socket.select(readSet, writeSet, timeout) 会返回已准备好进行输入/输出的套接字集合,这是完整事件循环的基础。

local readable, writable = socket.select({sock1, sock2}, nil, 0.1)
for _, s in ipairs(readable) do
  local data = s:receive(1024)
  -- handle data
end

超文本传输协议客户端

Lua 套接字库包含一个高级超文本传输协议模块,可用于发送简单请求。

local http = require("socket.http")
local body, code = http.request("http://example.com")
print(code, #body)

UDP 套接字

UDP 是无连接的。请使用 socket.udp() 进行基于数据报的通信。

local udp = socket.udp()
udp:setsockname("*", 0)
udp:sendto("hello", "127.0.0.1", 9999)
local data = udp:receive()
udp:close()

超时

使用 :settimeout(seconds) 设置超时。超时值为 0 表示非阻塞;正数允许部分阻塞;nil 表示无限期阻塞。

错误处理模式

Lua 套接字库的函数在失败时会返回 nil 和错误字符串。请始终检查第二个返回值。

local ok, err = tcp:connect("host", 80)
if not ok then
  error("Connection failed: " .. tostring(err))
end

OpenResty 替代方案

对于 LuaJIT 中的生产级非阻塞输入/输出,OpenResty 的协作套接字功能更强大、性能也更好。请将 Lua 套接字库用于独立脚本和简单工具。

非阻塞问题

tcp:settimeout(0) 会做什么?

回顾:非阻塞输入/输出

使用 settimeout(0) 创建非阻塞套接字,并使用 socket.select 实现输入/输出多路复用。将它与协程结合:超时时执行 yield,数据就绪时恢复协程。对于高性能异步输入/输出,请优先使用 OpenResty 或 libuv 绑定库。

常见问题解答

「使用 luasocket 实现非阻塞 I/O」课时是免费的吗?

是的 — 「使用 luasocket 实现非阻塞 I/O」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。

「使用 luasocket 实现非阻塞 I/O」这节课中我会学到什么?

以非阻塞模式使用 luasocket,并将其集成到协程调度器中。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Lua Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「使用 luasocket 实现非阻塞 I/O」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Lua Academy 课中编写并运行代码吗?

能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 构建简单事件循环
  2. 使用协程实现 Async/Await
  3. 类似 Promise 的模式
  4. 使用 luasocket 实现非阻塞 I/O
← 返回 Lua Academy