lua 的tcp,udp封装

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

使用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即可


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值