Network

网络系统,包括监听、连接、收发数据等;只支持lua。 可以使用地址*代替0.0.0.0和本机ip,linux服务端不能直接解析机器名。 全部展开

监听展开

  • + listenNet = _listen('ip或域名:port 或 @name', onListen, onClose)

    启动监听网络连接,地址为ip或域名,端口为port。
    监听到连接时回调函数。
    监听到的连接关闭时回调函数,包括服务端主动关闭,发现连接重置,等待数据时超时等情况。
    在linux系统,还可以监听共享名字,以@开头如@game001,用来接收共享网络对象。
    返回的对象可以调用方法,返回的对象应保持引用,被垃圾回收时关闭监听,监听关闭不回调。
    此函数只在没有其他函数执行时回调,不与任何函数重入。

  • + onListen(net, listenNet, ip, port, myip, myport, share)

    监听到连接时回调,net为连接的网络对象,listenNet为正在监听连接的网络对象。
    ip port为连接对端的ip整数和端口数,myip myport为连接本端的ip整数和端口数。
    share为共享net时的数据,并非每次回调都创建新的share,如果需要长期引用数据,可以通过 share:tostr()转换成字符串或share:tobytes()转换成独立的字节数据。
    net对象可以调用{receive}、{send}、{close}等方法,对象应保持引用,被垃圾回收时自动关闭,并回调{onClose}。
    此函数只在没有其他函数执行时回调,不与任何函数重入。

连接展开

  • + net = _connect('ip或域名:port', onConnect, onClose, timeout)

    连接网络,地址为ip或域名,端口为port,timeout为超时秒数1~86400,注意域名解析会阻塞程序。
    连接成功时回调{onConnect}函数。
    连接失败或超时回调{onClose}函数,notconn参数为true。
    连接成功后再关闭时回调{onClose}函数,包括主动关闭,发现连接重置,等待数据超时等情况。
    返回的对象可以调用{receive}、{send}、{close}等方法,对象应保持引用,被垃圾回收时自动关闭,并回调{onClose}。
    此函数只在没有其他函数执行时回调,不与任何函数重入。

  • + onConnect(net, ip, port, myip, myport)

    连接成功时回调,net为连接的网络对象。
    ip port为连接对端的ip整数和端口数,myip myport为连接本端的ip整数和端口数。
    net对象可以调用{receive}、{send}、{close}等方法,对象应保持引用,被垃圾回收时自动关闭,并回调{onClose}。
    此函数只在没有其他函数执行时回调,不与任何函数重入。

收发数据展开

  • + data = net:receiving(length, timeoutSeconds)

    阻塞接收数据。
    当对应的{receive}应该回调{onReceive}时,receiving返回data,参见{onReceive}。
    如果超时或发现连接关闭,回调{onClose},然后从receiving抛出错误。

  • + data, separator = net:receiving(separator1, ..., length, timeoutSeconds)

    阻塞接收数据。
    当对应的{receive}应该回调{onReceive}时,receiving返回data和separator,参见{onReceive}。
    如果超时或发现连接关闭,回调{onClose},然后从receiving抛出错误。

  • + net:receive(length, onReceive, timeoutSeconds)

    接收数据,length为需要接收的字节数,onReceive为接收到数据的回调。
    当接收到长度足够的数据时,回调{onReceive}。
    timeout为等待数据超时秒数1~86400,包括数据长度不足的情况,超时将自动关闭连接,并回调{onClose}。
    网络对象接收的数据暂存在缓冲里,调用receive时处理数据,不会立即回调{onReceive}。
    回调{onReceive}时要调用另一个receive来处理后续数据。

  • + net:receive(separator1, separator2, ..., length, onReceive, timeoutSeconds)

    接收数据,separator1等为分割数据的字符串,length为最多等待分割的数据字节数,onReceive为接收到数据的回调。
    当接收到的数据超出长度之前,包含某个分割字符串,回调{onReceive},含sepreate参数。
    当接收到的数据长度足够,但不包含任何一个分割字符串,回调{onReceive},不含separate参数。
    timeout为等待数据的超时秒数1~86400,包括数据长度不足且不包含分割字符串的情况,超时将自动关闭连接,并回调{onClose}。
    网络对象接收的数据暂存在缓冲里,调用receive时处理数据,不会立即回调{onReceive}。
    回调{onReceive}时要调用另一个receive来处理后续数据。

  • + onReceive(net, data, separator)

    接收到数据时回调,net为网络对象,data为接收到的数据,#data为字节数。
    对于使用分割字符串来接收的{receive},separator为实际收到的分割字符串,从to+1开始即为此字符串,separator为nil表示未收到分割字符串,数据已达到长度限制。
    每次回调的data可能是同一个引用而内容不同,如果需要在回调之后继续处理原data内容,建议通过data:tostr()拷贝成字符串或data:tobytes()拷贝成另一个字节串,以避免内容变化。
    此函数只在没有其他函数执行时回调,不与任何函数重入。

  • + sent = net:send(data, from, to, partial)

    发送数据,data为字符串或编码函数_encode返回的数据。
    from和to为数据被发送的起始和结束字节,省略时则发送整个数据。
    如果发现连接被重置,则关闭连接,并立即回调{onClose},返回-1。
    partial参数false或nil时,如果发送队列未满,则无返回值,如果发送队列已满,则关闭连接,并立即回调{onClose},返回实际进入发送队列的字节数。
    partial参数非false非nil时,返回实际进入发送队列的字节数,即使发送队列已满,也不关闭连接。

其它展开

  • + ipnumber... = _hostips('ip或域名'[, timeout])

    解析域名,依据网络情况可能阻塞较长时间,可设置timeout时间,单位秒。
    返回域名解析的32位整数ip,可能返回多个。解析失败则抛出错误。
    可以使用地址*获得非127开头的本机ip,linux服务端不能直接解析机器名。

    local res, ret = pcall( _hostips, 'xx.com' )
    if not res then
        print( '连接错误' )
    else
        print( string.format('%08x',ip) )
    end
  • + net:close()

    关闭连接,立即回调{onClose},对于监听端口,不回调{onClose}。

  • + net:closed( )

    返回net连接是否处于关闭状态。

  • + net:connecting( )

    返回当前net连接是否处于正在连接的状态。

  • + net:nagle( bool on )

    打开或关闭net连接的延迟发送。 延迟发送会减少流量,合并内容减少包头,立即发送对于小数据包头明显增加。系统默认打开。

  • + net:share(name, data, from, to)

    共享网络对象,只支持linux
    name为共享名,如game001,不含开头的@,data为字符串或编码函数_encode返回的数据。
    from和to为数据被发送的起始和结束字节,省略时则发送整个数据。
    接收共享的进程需要_listen相同的名字。
    共享之后两个网络对象读取和发送可能并发,必须非常严谨地设计数据协议,如果不是必须共享则建议一方net:close()。

  • + net:state( )

    返回当前net连接的状态。
    0 空闲 2 接收数据 13 连接中 14 监听中 15 共享 16 关闭

  • + onClose(net, timeout, notconn, err)

    连接关闭回调,net为被关闭的网络连接对象,关闭监听时不回调。
    timeout为true表示接收数据超时或连接超时,notconn为true表示连接失败。err为可能的错误信息,仅供参考。
    可能在其他函数执行时回调此函数。
    没有发送也没有接收操作的网络连接对象,可能不检测连接是否断开。

服务端代码示例展开

    function netSend(net, data)
        local send = net and net.send
        if send then
            send(net, string.from32b(#data))
            send(net, data)
        end
    end
    local onHead, onBody, onIndex
    function onHead(net, data)
        local len = string.to32b(data, 1, true)
        if len <= 0 or len > 4096 then
            net:close()
            error'invalid net data'
        end
        net:receive(len, onBody, 10)
    end
    function onBody(net, data)
        net:receive(4, onHead, 300)
        print(data:tostr())
        netSend(net, data)
    end
    local nets = {}
    local function onListen(net, lisn, ip, port, myip, myport)
        print('accept', net)
        net:receive(4, onHead, 60)
        net.ip = ip
        net.port = port
        nets[net] = true
    end
    local function onClose(net, ...)
        print('close', net, ...)
        nets[net] = nil
    end
    _G.listening = _listen('*:1234', onListen, onClose)

客户端代码示例展开

    function netSend(net, data)
        local send = net and net.send
        if send then
            send(net, string.from32b(#data))
            send(net, data)
        end
    end
    local function connectServer(to, onInit, onConnect, reconnect)
        local onHead, onBody
        function onHead(net, data)
            local len = string.to32b(data, 1, true)
            if len <= 0 or len > 1024*1024 then
                net:close()
                error'invalid net data'
            end
            net:receive(len, onBody, 86400)
        end
        function onBody(net, data)
            net:receive(4, onHead, 86400)
            print(data:tostr())
        end
        print('connecting', to)
        onInit(_connect(to, function (net)
            print('connect', to)
            net:receive(4, onHead, 86400)
            onConnect(net)
        end, function (net, timeout, notconn, ...)
            if notconn then
                print('connect failed', to, timeout, notconn, ...)
                if reconnect then
                    _enqueue(os.now(0)+1000000, nil, connectServer, to, onInit, onConnect, reconnect)
                end
            else
                print('close', to, timeout, notconn, ...)
            end
        end, 10))
    end
    connectServer('0.0.0.0:1234', function (net)
        _G.server = net
    end, function (net)
        print'connected'
        netSend(net, 'hello')
    end, true)
问题反馈(登录才可以发表哦!)