LuaSocket server:accept() 超时问题(TCP)

问题

按照 LuaSocket 介绍 中的方法,我成功运行了服务器并在客户端成功连接。但是我注意到服务器脚本会冻结直到 server:accept() 获取到连接。

研究

LuaSocket 参考文献 指定了:

使用 settimeout 方法,否则 accept 可能会阻塞,直到另一个客户端出现。

这甚至在示例代码中都有提到。然而,在 local client = server:accept() 之后调用了 client:settimeout(10),因此脚本在到达此点之前就被阻塞了。

我读到说这可以通过多线程来解决,但这似乎有些夸张。

问题

  1. 如何使服务器脚本停止等待连接并继续运行?
  2. 如何防止 client:receive()(服务器端)和 tcp:receive()(客户端)出现类似问题(或者 client:settimeout(10) 已经解决了这个问题)?

代码

服务器端(来自 LuaSocket 介绍

-- 加载命名空间
local socket = require("socket")
-- 创建 TCP 套接字并将其绑定到本地主机的任何端口
local server = assert(socket.bind("*", 0))
-- 找出 OS 为我们选择的端口
local ip, port = server:getsockname()
-- 打印一条信息,告知端口号
print("请在本地主机上的端口 " .. port .. " 上使用 Telnet")
print("连接后,您有 10 秒钟输入要回显的行")
-- 永久循环等待客户端连接
while 1 do
  -- 等待从任何客户端来的连接
  local client = server:accept()
  -- 确保我们不阻塞等待此客户端的行
  client:settimeout(10)
  -- 接收行
  local line, err = client:receive()
  -- 如果没有错误,则将其发送回客户端
  if not err then client:send(line .. "\n") end
  -- 关闭客户端对象完成任务
  client:close()
end

客户端(参考了 这个答案

local host, port = "127.0.0.1", 100
local socket = require("socket")
local tcp = assert(socket.tcp())

tcp:connect(host, port);
-- 注意下面的换行符
tcp:send("hello world\n");

while true do
    local s, status, partial = tcp:receive()
    print(s or partial)
    if status == "closed" then break end
end
tcp:close()
点赞
用户1442917
用户1442917

你应该在调用 server:accept() 之前使用 server:timeout()

server:settimeout(2)
local client, err = server:accept()
print(client, err)

如果在 2 秒内没有请求进来,这会打印出 nil timeout

2017-02-24 18:34:57