3

我需要一些使用套接字“选择”功能的帮助。

我的服务器代码是这样的:

while true do
    for _,server in pairs(servers) do
        local client = server:accept()

        client:settimeout(5)

        local line, err = client:receive()
        if not err then
            client:send(line .. "_SERVER_SIDE\n")
        else
            client:Send("___ERRORPC"..err)
        end

        client:close()
    end
end

但现在我想使用 select 函数而不是像这样创建一个永远循环。

阅读:http ://w3.impa.br/~diego/software/luasocket/socket.html

我知道我可以使用类似的东西:

socket.select(servers, nil, 5)

但我不知道如何在上面的代码中使用它。谁能帮我?

我将不得不在一段时间内使用这个真实的声明?

读取操作(第一个参数)意味着我只能接受/接收]?而秒参数意味着我只能发送?

4

3 回答 3

3

根据文档, select 接收一个或两个套接字数组并返回一个可以安全地读取而不会阻塞的套接字数组和一个可以安全地写入而不会阻塞的套接字数组和一个可以安全地写入的套接字数组没有阻塞。重要的一点是,第一个数组用于要调用 accept 的服务器套接字和要调用 receive 的客户端套接字。

秒参数只是选择的超时。这与您可以进行多少次操作无关。

您必须在代码中更改的基本内容是,当接收调用因超时而失败时,您应该将该套接字添加到您传递给选择的套接字数组中。这样,您可以让 select 告诉您该套接字何时再次变为活动状态。

于 2013-04-15T06:36:14.407 回答
2

来自文档select:“在调用 accept 之前使用接收参数中的服务器套接字调用 select 并不能保证 accept 将立即返回。使用 settimeout 方法或 accept 可能会永远阻塞。” 这意味着您需要在通话settimeout之前使用accept,但假设您有一个可以在servers表中使用的打开连接列表,您可以通过select以下方式使用:

local canread = socket.select(servers, nil, 1)
for _,client in ipairs(canread) do
  local line, err = client:receive()
  if not err then
      client:send(line .. "_SERVER_SIDE\n")
  else
      client:send("___ERRORPC"..err)
  end
end

socket.select最多会阻塞 1 秒,但如果您提供的列表中有一个可以读取的套接字,则会更快返回。如果您使用socket.select(servers, nil, 0);您可以无限期阻止 如果您在等待输入时需要做一些其他工作,那么阻塞一小段时间很有用。

更新为使用ipairs,而不是pairs返回表在数字和套接字本身上都键入了键,因此如果可以从中读取一个套接字,则返回的数组看起来像{[1] = sock, [sock] = 1}.

于 2013-04-15T19:13:25.370 回答
0

单个演示

local server = socket.bind("*",7777)
local client_tab = {}

while true do
    -- socket.select first param is a table of connected socket,
    -- you want a connected socket,you need to call accept()
    -- if you do not want to block,you should call settimeout(seconds)
    local recvt = socket.select(client_tab, nil, 1)
    server:settimeout(1)
    local client = server:accept()
    if client then
        client_tab[#client_tab+1] = client 
    end
    if #recvt > 0 then
        -- read clients in recvt
    end
end
于 2019-07-17T04:25:41.460 回答