跳转至

3 dhcpsrv-DHCP服务器

作者:魏健强 | 最后修改:2026-03-11

一、概述

dhcpsrv 扩展库,dhcp 服务器端,为 wifi AP 和以太网 LAN 网卡提供 dhcp 功能,为连接的设备自动分配 ip

二、核心示例

1、核心示例是指:使用本扩展库文件提供的 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、 完整的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/netdrv;

-- 创建一个dhcp服务器, 最简介的版本
dhcpsrv.create({adapter=socket.LWIP_AP})
-- 详细的版本
-- 创建一个dhcp服务器
local dhcpsrv_opts = {
    adapter=socket.LWIP_AP, -- 监听哪个网卡, 必须填写
    mark = {255, 255, 255, 0}, -- 网络掩码, 默认 255.255.255.0
    gw = {192, 168, 4, 1}, -- 网关, 默认自动获取网卡IP,如果获取失败则使用 192.168.4.1
    ip_start = 100, -- ip起始地址, 默认100
    ip_end = 200, -- ip结束地址, 默认200
    ack_cb = function(ip, mac) end, -- ack回调, 有客户端连接上来时触发, ip和mac地址会传进来
}
local mydhcpsrv = dhcpsrv.create(dhcpsrv_opts)

local function get_client()
    while true do
        sys.wait(10000)
        -- 这里可以打印一下当前的客户端列表
        for ip, client in pairs(mydhcpsrv.clients) do
            log.info("client", ip, client.mac:toHex(), client.tm, client.stat)
        end
    end
end

-- 以下是一个打印客户端列表的例子, 非必选, 仅供参考
-- clients是一个table, 包含MAC和IP的对应关系, 注意, IP只记录了最后一段数字, 非完整IP
-- 注意, clients是动态变化的过程, mydhcpsrv对象的其他属性切勿修改, 仅提供clients的只读功能
sys.taskInit(get_client)

-- 自动分配网段功能说明:
-- 如果不指定gw参数,系统会自动获取网卡IP作为网关地址
-- 这样可以确保DHCP分配的IP与网卡IP在同一网段

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

合宙LuatOS内核固件中定义的核心库常量,和此扩展库功能有关,所以也会放到本文描述。

关于网络适配器类型的常量:

注意:目前除 8101 系列产品默认网络适配器为 socket.LWIP_STA,其他主流模组默认网络适配器为 socket.LWIP_GP。

socket.LWIP_GP

常量含义:4G网卡
         LWIP是指:传输层和网络层使用的是LuatOS内核固件中的LwIP协议栈
         GP是GPRS的缩写GPRS是2G网络时代的分组数据网络,此处用来代指移动蜂窝数据网络,例如4G网络
数据类型:number
示例代码:socket.localIP(socket.LWIP_GP)

socket.LWIP_STA

常量含义:WiFi设备模式网卡
         LWIP是指:传输层和网络层使用的是LuatOS内核固件中的LwIP协议栈
         STA是STATION的缩写,表示WiFi设备模式,需要连接WiFi热点才能上网
数据类型:number
示例代码:socket.localIP(socket.LWIP_STA)

socket.LWIP_AP

常量含义:WiFi热点模式网卡
         LWIP是指:传输层和网络层使用的是LuatOS内核固件中的LwIP协议栈
         AP是Access Ponit的缩写,意思是WiFi热点,供其他WiFi设备接入上网
数据类型:number
示例代码:socket.localIP(socket.LWIP_AP)

socket.LWIP_ETH

常量含义:使用LwIP协议栈的以太网卡
         LWIP是指:传输层和网络层使用的是LuatOS内核固件中的LwIP协议栈
         ETH是Ethernet的缩写,意思是以太网;
数据类型:number
示例代码:socket.localIP(socket.LWIP_ETH)

socket.ETH0

常量含义:使用硬件协议栈的以太网卡;
         ETH是Ethernet的缩写,意思是以太网,ETH0表示编号为0的硬件协议栈以太网卡
数据类型:number
示例代码:socket.localIP(socket.ETH0)

socket.USB

常量含义:USB接口的以太网卡
         常见的USB以太网卡又可以分为 USB RNDIS以太网卡  USB ECM以太网卡两种
数据类型:number
示例代码:socket.localIP(socket.USB)

socket.LWIP_USER0

常量含义:使用LWIP协议栈的自定义网卡0
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER0)

socket.LWIP_USER1

常量含义:使用LWIP协议栈的自定义网卡1
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER1)

socket.LWIP_USER2

常量含义:使用LWIP协议栈的自定义网卡2
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER2)

socket.LWIP_USER3

常量含义:使用LWIP协议栈的自定义网卡3
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER3)

socket.LWIP_USER4

常量含义:使用LWIP协议栈的自定义网卡4
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER4)

socket.LWIP_USER5

常量含义:使用LWIP协议栈的自定义网卡5
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER5)

socket.LWIP_USER6

常量含义:使用LWIP协议栈的自定义网卡6
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER6)

socket.LWIP_USER7

常量含义:使用LWIP协议栈的自定义网卡7
数据类型:number
示例代码:socket.localIP(socket.LWIP_USER7)

四、函数详解

4.1 dhcpsrv.create(opts)

功能

创建一个 dhcp 服务器;

注意事项

无;

参数

opts

参数含义:dhcp参数设置;
{
参数含义:网络适配器;
数据类型:number;
取值范围:参考第三节常量详解;
是否必选:必选;
注意事项:无;
参数示例: socket.LWIP_AP
参数名称: opts.adapter

参数含义:网络掩码;
数据类型:table;
取值范围:暂无;
是否必选:可选,默认{255, 255, 255, 0};
注意事项:无;
参数示例: {255, 255, 255, 0}
参数名称: opts.mark

参数含义:网关;
数据类型:table;
取值范围:暂无;
是否必选:可选,默认自动获取网卡IP,如果获取失败则使用 {192, 168, 4, 1};
注意事项:无;
参数示例: {192, 168, 4, 1}
参数名称: opts.gw

参数含义:分配的网段内的起始ip;
数据类型:number;
取值范围:2-255,不能使用网关的IP,不能超过ip_end;
是否必选:可选.默认100;
注意事项:无;
参数示例: 100
参数名称: opts.ip_start

参数含义:分配的网段内的结束ip;
数据类型:number;
取值范围:ip_start 至 255;
是否必选:可选,默认200;
注意事项:无;
参数示例: 200
参数名称: opts.ip_end

参数含义:客户端连接模块时的回调函数;
function(ip, mac)
log.info("ack_cb", "new client", ip, mac)
end
回调函数接收以下两个参数:
参数含义:ip;
数据类型:string;
取值范围:无;
是否必选:必选;
参数示例:"192.168.4.100";
ip,

参数含义:mac;
数据类型:string;
取值范围:无;
是否必选:必选;
参数示例:"2E4EDBB1A054";
mac

数据类型:function;
取值范围:暂无;
是否必选:可选;
注意事项:ack回调, 有客户端连接上来时触发, ip和mac地址会传进来;
参数示例:
参数名称: opts.ack_cb
}

数据类型:table;
取值范围:暂无;
是否必选:可选;
注意事项:无;
参数示例:dhcpsrv.create({adapter=socket.LWIP_AP})

返回值

local mydhcpsrv = dhcpsrv.create(ops)

for ip, client in pairs(mydhcpsrv.clients) do

log.info("client", ip, client.mac:toHex(), client.tm, client.stat)

end

mydhcpsrv

含义说明:客户端列表;
        {
         clients = 
         {
             -- 含义说明:ip的最后一段数字;
             -- 数据类型:number;
             -- 取值范围:2-255;
             -- 注意事项:非完整ip;
             -- 返回示例:100;
             ip = 
            {
               -- 含义说明:mac地址;
               -- 数据类型:string;
               -- 取值范围:无;
               -- 注意事项:返回原始mac地址,打印时建议使用client.mac:toHex()转换成HEX字符串;
               -- 返回示例:0x2E4EDBB1A054;
               mac = 0x2E4EDBB1A054,
               -- 含义说明:客户端连接的时间。设备开机到连接时的运行秒数;
               -- 数据类型:number;
               -- 取值范围:无;
               -- 注意事项:会动态变化,出现重连时会更新数据;
               -- 返回示例:6;
               tm = 6,
               -- 含义说明:客户端状态;
               -- 数据类型:number;
               -- 取值范围:1/3 1:已分配ip但未确认 3:已分配ip且已确认;
               -- 注意事项:无;
               -- 返回示例:1;
               stat = 1
            }
          }
        }
数据类型:table
取值范围:无;
注意事项:-- clients是一个table, 包含MAC和IP的对应关系, 注意, IP只记录了最后一段数字, 非完整IP
         -- 注意, clients是动态变化的过程, mydhcpsrv对象的其他属性切勿修改, 仅提供clients的只读功能;
返回示例:{ 100 = {mac = 0x2E4EDBB1A054 , tm = 6  stat = 1}};

示例

-- 创建一个dhcp服务器, 最简单的版本
dhcpsrv.create({adapter=socket.LWIP_AP})
-- 详细的版本
-- 创建一个dhcp服务器
local dhcpsrv_opts = {
    adapter=socket.LWIP_AP, -- 监听哪个网卡, 必须填写
    mark = {255, 255, 255, 0}, -- 网络掩码, 默认 255.255.255.0
    gw = {192, 168, 4, 1}, -- 网关, 默认自动获取网卡IP,如果获取失败则使用 192.168.4.1
    ip_start = 100, -- ip起始地址, 默认100
    ip_end = 200, -- ip结束地址, 默认200
    ack_cb = function(ip, mac)
                 log.info("ack_cb", "new client", ip, mac)
             end -- ack回调, 有客户端连接上来时触发, ip和mac地址会传进来
}
local mydhcpsrv = dhcpsrv.create(dhcpsrv_opts)

-- 以下是一个打印客户端列表的例子, 非必选, 仅供参考
-- clients是一个table, 包含MAC和IP的对应关系, 注意, IP只记录了最后一段数字, 非完整IP
-- 注意, clients是动态变化的过程, mydhcpsrv对象的其他属性切勿修改, 仅提供clients的只读功能
local function get_client()
    while true do
        sys.wait(10000)
        -- 这里可以打印一下当前的客户端列表
        for ip, client in pairs(mydhcpsrv.clients) do
            log.info("client", ip, client.mac:toHex(), client.tm, client.stat)
        end
    end
end

-- 以下是一个打印客户端列表的例子, 非必选, 仅供参考
-- clients是一个table, 包含MAC和IP的对应关系, 注意, IP只记录了最后一段数字, 非完整IP
-- 注意, clients是动态变化的过程, mydhcpsrv对象的其他属性切勿修改, 仅提供clients的只读功能
sys.taskInit(get_client)

-- 自动分配网段功能说明:
-- 如果不指定gw参数,系统会自动获取网卡IP作为网关地址
-- 这样可以确保DHCP分配的IP与网卡IP在同一网段

五、产品支持说明

支持 LuatOS 开发的所有产品都支持 dhcpsrv 扩展库;