skynet.netpack四个核心函数详解

发布于:2025-04-08 ⋅ 阅读:(17) ⋅ 点赞:(0)

在这里插入图片描述

在 Skynet 中,netpack 模块提供了四个核心函数,用于处理网络数据包的接收、粘包解析和队列管理。以下是这四个函数的详细解析:


1. netpack.filter(queue, msg, sz)

作用:

  • 粘包处理:将原始网络数据流(msg)分割为完整的消息包,并将未处理完的数据缓存到 queue 中。
  • 队列管理:将分割后的完整消息包存入队列,供后续逐个处理。

参数:

  • queue:用于缓存消息包的队列(通常是一个表)。
  • msg:接收到的原始二进制数据(lightuserdatastring)。
  • sz:数据长度。

返回值:

  • 完整消息包数量:返回本次处理得到的完整消息包数量。

工作原理:

  1. 协议解析:根据预设的协议(如两字节大端长度头)解析 msg
  2. 数据分割:将 msg 按消息头指示的长度分割为多个完整包。
  3. 缓存处理:未组成完整包的数据部分会被保留在 queue 中,等待下次数据到达时继续处理。

示例:

local queue = {}
local msg = socket.read(fd)  -- 读取原始数据
local count = netpack.filter(queue, msg, #msg)

2. netpack.pop(queue)

作用:

  • 取出消息包:从队列 queue 中弹出一个完整的消息包。
  • 遍历队列:通过循环调用 netpack.pop,可逐个处理所有缓存的完整消息包。

参数:

  • queue:通过 netpack.filter 维护的消息队列。

返回值:

  • 消息包信息:返回三个值:fd(连接的套接字描述符)、msg(消息内容)、sz(消息长度)。若队列为空,返回 nil

示例:

while true do
    local fd, msg, sz = netpack.pop(queue)
    if not fd then break end
    -- 处理消息,如解析并分发给业务逻辑
    handle_request(fd, msg, sz)
end

3. netpack.tostring(msg, sz)

作用:

  • 数据转字符串:将二进制数据 msg 转换为可打印的字符串,用于调试或日志记录。
  • 非破坏性操作:不修改原始数据,仅生成其字符串表示。

参数:

  • msg:二进制数据(lightuserdatastring)。
  • sz:数据长度。

返回值:

  • 字符串:数据的十六进制或可打印字符表示。

示例:

local msg_str = netpack.tostring(msg, sz)
print("Received data:", msg_str)

4. netpack.clear(queue)

作用:

  • 清空队列:释放队列 queue 中所有缓存的消息包占用的内存。
  • 资源回收:在连接关闭或需要重置时调用,避免内存泄漏。

参数:

  • queue:通过 netpack.filter 维护的消息队列。

示例:

function on_disconnect(fd)
    netpack.clear(queue)  -- 清理队列
    socket.close(fd)
end

完整使用场景示例

local skynet = require "skynet"
local socket = require "skynet.socket"
local netpack = require "skynet.netpack"

local queue = {}  -- 消息队列

-- 处理客户端连接
socket.start(fd, function(fd, data)
    -- 1. 处理粘包,分割数据
    local count = netpack.filter(queue, data, #data)

    -- 2. 逐个取出完整消息包
    for _ = 1, count do
        local _, msg, sz = netpack.pop(queue)
        if msg then
            -- 3. 转换为字符串记录日志
            local msg_str = netpack.tostring(msg, sz)
            skynet.error("Received:", msg_str)

            -- 4. 处理业务逻辑
            handle_request(fd, msg, sz)
        end
    end
end)

-- 连接关闭时清理队列
socket.on_close(fd, function()
    netpack.clear(queue)
end)

总结

函数 作用 典型场景
netpack.filter 粘包处理与队列填充 接收原始网络数据流时调用
netpack.pop 从队列中取出完整消息包 处理已分割的完整消息包
netpack.tostring 二进制数据转字符串 调试或日志记录
netpack.clear 清空队列并释放内存 连接关闭或重置时调用

通过这四个函数,Skynet 能够高效地处理网络通信中的粘包问题,并提供灵活的数据管理机制,适用于高并发、低延迟的服务器开发场景。