所以,我正在学习套接字编程,并且我正在尝试用 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()
我建议使用多线程库,例如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