lua服务器无法处理多个客户端

问题描述 投票:0回答:1

所以,我正在学习套接字编程,并且我正在尝试用 lua 制作一个简单的 tcp 聊天室服务器。

它可以很好地连接到单个客户端,但是当另一个客户端尝试加入服务器时,它会等到另一个客户端退出然后再加入

服务器.lua

require('socket')
server = assert(socket.bind('localhost', 69420))

clients = {}
--data = {} --use later

function broadcast(message)
        if message then
            for _, client in pairs(clients) do
                    client:send(message .. '\n')
            end
    end
end


function handle(client)
    while 1 do
        local buff, err = client:receive()
        if err then
            print(err)
            client:send("error occurred = ".. err)
            client:close()
            break
        else
            print(buff)
            broadcast(buff)
        end
    end
end

function recieve()
    while 1 do
        server:settimeout(0.01) -- tried adding this, still didn't worked
        local client = server:accept()
        if client then
            table.insert(clients, client)

            print("a new client entered")
            broadcast("a new client has joined us\n")

            coroutine.wrap(handle)(client) --this was supposed to handle the clients
        end
    end
end

print("localhost server listening on port 69420... nice")
recieve()

另外,我正在使用这个客户端脚本:

客户端.lua

-- simple script just to check for server errors 
require('socket')
client = socket.tcp()

client:connect("localhost", 69420)
client:send("hello\n")

while 1 do 
    local s, status, partial = client:receive()
    print(s or partial)
    if status == "closed" then
      break
    end
end

client:close()
sockets tcp lua tcpserver
1个回答
0
投票

我建议使用多线程库,例如Lanes。如果您只想使用LuaSocket,则需要按照以下顺序(伪代码):

while 1 do
    server:accept()
    ...
    for i,client in ipairs(clients) do
        client:receive()
        ...
        client:send()
        ...
    end
end

您可以使用

socket.select
过滤掉已经收到数据的客户端,从而避免每次都循环遍历所有客户端:

local recvt, sendt, err = socket.select(clients, clients, 0.01)
if not err then
    if recvt then
        -- Calling receive on clients in this table will immediately return.
        for k,c in ipairs(recvt) do
            local line, err = c:receive()
        end
    end
    if sendt then
        -- Same as recvt
        for k,c in ipairs(sendt) do
        end
    end
end
© www.soinside.com 2019 - 2024. All rights reserved.