提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
使用lua封装tcp和udp的内部接口,可以实现tcp客户端的短线重连和服务端多个连接。
一、tcp封装代码
local socket = require("socket")
Timeout = 0.01
-- 定义一个工厂函数
-- HsTimer class
HsTcp = { serialname = nil, serverserialname = nil, Send = nil, Receive = nil, Close = nil, addr = nil, port = nil }
function HsTcp:new(ipaddr, ipport, type)
if type == "tcpclient" then
local client = socket.tcp()
client:settimeout(Timeout)
local success, err = client:connect(ipaddr, ipport)
if success then
print("连接成功:" .. success.." ip:"..ipaddr.." port:"..ipport)
client:settimeout(0)
else
print("连接失败:" .. err.." ip:"..ipaddr.." port:"..ipport)
client:close()
client = nil
end
local tcp =
{
serialname = client,
addr = ipaddr,
port = ipport,
Send = nil,
Receive = nil,
Close = nil,
}
tcp.Send = function(data)
if tcp.serialname ~= nil then
local bytes, err = tcp.serialname:send(data)
if bytes == nil and (err == "closed" or err =="timeout") then
print("发送数据失败:" .. err)
tcp.serialname = nil
tcp.serialname = HsTcp:new(tcp.addr, tcp.port, "tcpclient").serialname
end
else
print("重连ing")
tcp.serialname = nil
tcp.serialname = HsTcp:new(tcp.addr, tcp.port, "tcpclient").serialname
end
end
tcp.Receive = function(num)
if num == nil then
return nil
end
if tcp.serialname ~= nil then
local response, err, partial = tcp.serialname:receive(num)
if response and err == nil then
--print("response收到服务器响应:" .. response)
return response,tostring(tcp.serialname:getpeername())
else
if #partial ~= 0 and err == "timeout" then
--print("partial收到服务器响应:" .. partial)
return partial,tostring(tcp.serialname:getpeername())
else
if err == "timeout" then
print("接收服务器信息超时:"..tostring(tcp.serialname:getpeername()))
return nil
else
tcp.serialname:close()
tcp.serialname = nil
tcp.serialname = HsTcp:new(tcp.addr, tcp.port, "tcpclient").serialname
end
end
end
else
print("重连ing")
tcp.serialname = nil
tcp.serialname = HsTcp:new(tcp.addr, tcp.port, "tcpclient").serialname
end
end
tcp.Close = function()
if tcp.serialname then
if tcp.serialname == nil then
print("close".." ip:"..tcp.addr.." port:"..tcp.port.." success")
else
print("close".." ip:"..tcp.addr.." port:"..tcp.port.." Failed")
end
end
end
return tcp
else
if type == "tcpserver" then
local host = ipaddr or '127.0.0.1'
local port = ipport
local server = socket.bind(host, port)
if not server then
print("Failed to bind server to host:port".." ip:"..host.." port:"..port)
Servertype = "bind err"
Bindtype= 0
else
print("success to bind server to host:port".." ip:"..host.." port:"..port)
Bindtype = 1
server:settimeout(0.01)
end
local tcp =
{
serialname = {},
serverserialname = server,
addr = ipaddr,
port = ipport,
Send = nil,
Receive = nil,
Close = nil,
count = 1,
type = Bindtype,
redata = Servertype
}
tcp.Send = function(data)
if tcp.type == nil then
return nil
else
for i = 1, tcp.count do
if tcp.serialname[i] == nil then
tcp.serialname[i] = tcp.serverserialname:accept()
if tcp.serialname[i] then
tcp.serialname[i]:settimeout(0)
tcp.count = tcp.count + 1
print('access success')
else
tcp.serialname[i] = nil
--print('accept err')
end
end
if tcp.serialname[i] ~= nil then
local bytes, err = tcp.serialname[i]:send(data)
if not bytes and err == "timeout" then
print("发送数据失败:" .. err)
tcp.serialname[i]:close()
tcp.serialname[i] = nil
end
end
end
end
end
tcp.Receive = function(num)
if tcp.type == nil then
return nil
else
for i = 1, tcp.count do
if tcp.serialname[i] == nil then
tcp.serialname[i] = tcp.serverserialname:accept()
if tcp.serialname[i] then
tcp.count = tcp.count + 1
tcp.serialname[i]:settimeout(0)
print('access success')
else
tcp.serialname[i] = nil
--print('accept err')
end
end
if num == nil then
return nil
end
if tcp.serialname[i] ~= nil then
local response, err, partial = tcp.serialname[i]:receive(num)
if response and err == nil then
--print("response收到客户端响应:" .. response)
return response,tostring(tcp.serialname[i]:getpeername())
else
if #partial ~= 0 and err == "timeout" then
--print("partial收到客户端响应:" .. partial)
return partial,tostring(tcp.serialname[i]:getpeername())
else
if err == "timeout" then
print("接收客户端信息超时:"..tostring(tcp.serialname[i]:getpeername()))
else
tcp.serialname[i]:close()
tcp.serialname[i] = nil
end
end
end
end
end
end
end
tcp.Close = function()
for i = 1, tcp.count do
if tcp.serialname[i] then
print("close"..i)
tcp.serialname[i]:shutdown("both")
tcp.serialname[i]:close()
tcp.serialname[i]=nil
end
end
if tcp.serverserialname then
if tcp.serverserialname:close() == nil then
print("server".." ip:"..tcp.addr.." port:"..tcp.port.." Failed")
else
print("server".." ip:"..tcp.addr.." port:"..tcp.port.." success")
end
end
end
return tcp
end
end
return nil
end
如何使用
tcpdevice = HsTcp:new(device_tcp.ip, device_tcp.port,"tcpserver" or "tcpclient")
tcpdevice.Send("xxxx")
二、udp封装代码
local socket = require("socket")
HsUdp = { serialname = nil, Send = nil, Receive = nil, Close = nil, addr = nil, port = nil }
function HsUdp:new(ipaddr, ipport, type)
if type == "udpclient" then
local client = socket.udp()
client:settimeout(0)
local success, err = client:setpeername(ipaddr, ipport)
if success then
print("连接成功:" .. success)
else
print("连接失败:" .. err)
client:close()
client = nil
end
local udp =
{
serialname = client,
Send = nil,
Receive = nil,
Close = nil,
addr = ipaddr,
port = ipport
}
udp.Send = function(t)
if udp.serialname ~= nil then
udp.serialname:send(t)
end
end
udp.Receive = function(num)
if udp.serialname ~= nil then
local response, addr = udp.serialname:receive()
if response then
--print("收到服务器响应:" .. response..tostring(udp.serialname:getpeername()))
return response,tostring(udp.serialname:getpeername())
end
return nil
end
return nil
end
udp.Close = function()
udp.serialname:close()
end
return udp
else
if type == "udpserver" then
local server = socket.udp()
local host = ipaddr or '127.0.0.1'
local port = ipport
server:setsockname(host, port)
server:settimeout(0)
local udp =
{
serialname = server,
Send = nil,
Receive = nil,
Close = nil,
addr = nil,
port = nil
}
udp.Send = function(t)
if udp.serialname ~= nil and udp.addr ~= nil and udp.port ~= nil then
local sendcli = udp.serialname:sendto(t, udp.addr, udp.port)
if (sendcli) then
print('sendcli ok')
else
print('sendcli error')
end
end
end
udp.Receive = function(num)
if udp.serialname ~= nil then
local revbuff, receip, receport = udp.serialname:receivefrom()
if revbuff then
udp.addr = receip
udp.port = receport
--print('revbuff:' .. revbuff .. ', receip:' .. udp.addr .. ', receport:' .. udp.port)
return revbuff,udp.addr
end
end
return nil
end
udp.Close = function()
udp.serialname:close()
end
return udp
end
end
return nil
end
使用方法与tcp类似前缀改为udp即可