前面的文章讲过,如何使用 socket 建立 tcp 监听:
#监听指定地址:ip:port
socket_id = socket.listen("ip:port")
#当监听到连接时,自定义函数:accept 会被触发
socket.start(socket_id, accept)
function accept(socket_id, addr)
skynet.error(addr .. " accepted")
end
#启动socket监听,然后从socket_id读取数据
socket.start(socket_id)
下面将测试如何使用 socket 主动建立连接。
一、服务端
local skynet = require "skynet"
local socket = require "skynet.socket"
function echo(cID, addr)
socket.start(cID)--启动socket监听
while true do
local str = socket.readline(cID)
if str then
skynet.fork(function()
skynet.error("recv " ..str)
skynet.sleep(math.random(1, 5) * 100)
socket.write(cID, string.upper(str) .. "\n")
end)
else
socket.close(cID)
skynet.error(addr .. " disconnect")
return
end
end
end
function accept(cID, addr)
skynet.error(addr .. " accepted")
skynet.fork(echo, cID, addr)
end
--服务入口
skynet.start(function()
local addr = "0.0.0.0:8001"
skynet.error("listen " .. addr)
local lID = socket.listen(addr)
assert(lID)
socket.start(lID, accept)
end)
二、客户端
local skynet = require "skynet"
local socket = require "skynet.socket"
function client(id)
local i = 0
while(i < 3) do
skynet.error("send data"..i)
socket.write(id, "data"..i.."\n")
local str = socket.readline(id)
if str then
skynet.error("recv " .. str)
else
skynet.error("disconnect")
end
i = i + 1
end
socket.close(id) --不主动关闭也行,服务退出的时候,会自动将套接字关闭
skynet.exit()
end
skynet.start(function()
local addr = "127.0.0.1:8001"
skynet.error("connect ".. addr)
local id = socket.open(addr)
assert(id)
--启动读协程
skynet.fork(client, id)
end)
可见,客户端 tcp 连接服务端的方式:
socket_id = socket.open(“ip:port”)
此外,socket 读写数据的方式:
str = socket.readline(socket_id)
socket.readline(socket_id, sep):从 socket_id 上读一行数据,sep:行分割符,默认为 “\n”,读到的字符串是不包含这个分割符。
socket.write(socket_id, data_str)
关闭 socket:
socket.close(socket_id)
三、测试结果
客户端:
服务端: