Переглянути джерело

add: 添加UDP服务器的库及demo

Wendal Chen 2 роки тому
батько
коміт
c61a966c76
2 змінених файлів з 156 додано та 0 видалено
  1. 88 0
      demo/socket/udp_server/main.lua
  2. 68 0
      script/libs/udpsrv.lua

+ 88 - 0
demo/socket/udp_server/main.lua

@@ -0,0 +1,88 @@
+
+-- LuaTools需要PROJECT和VERSION这两个信息
+PROJECT = "udpsrvdemo"
+VERSION = "1.0.0"
+
+-- sys库是标配
+_G.sys = require("sys")
+
+_G.udpsrv = require "udpsrv"
+
+-- Air780E的AT固件默认会为开机键防抖, 导致部分用户刷机很麻烦
+if rtos.bsp() == "EC618" and pm and pm.PWK_MODE then
+    pm.power(pm.PWK_MODE, false)
+end
+
+-- 统一联网函数
+sys.taskInit(function()
+    local device_id = mcu.unique_id():toHex()
+    -----------------------------
+    -- 统一联网函数, 可自行删减
+    ----------------------------
+    if wlan and wlan.connect then
+        -- wifi 联网, ESP32系列均支持
+        local ssid = "uiot"
+        local password = "czcjhp1985cbm"
+        log.info("wifi", ssid, password)
+        -- TODO 改成自动配网
+        -- LED = gpio.setup(12, 0, gpio.PULLUP)
+        wlan.init()
+        wlan.setMode(wlan.STATION) -- 默认也是这个模式,不调用也可以
+        device_id = wlan.getMac():toHex()
+        wlan.connect(ssid, password, 1)
+    elseif mobile then
+        -- Air780E/Air600E系列
+        --mobile.simid(2) -- 自动切换SIM卡
+        -- LED = gpio.setup(27, 0, gpio.PULLUP)
+        device_id = mobile.imei()
+    elseif w5500 then
+        -- w5500 以太网, 当前仅Air105支持
+        w5500.init(spi.HSPI_0, 24000000, pin.PC14, pin.PC01, pin.PC00)
+        w5500.config() --默认是DHCP模式
+        w5500.bind(socket.ETH0)
+        -- LED = gpio.setup(62, 0, gpio.PULLUP)
+    elseif socket then
+        -- 适配的socket库也OK
+        -- 没有其他操作, 单纯给个注释说明
+    else
+        -- 其他不认识的bsp, 循环提示一下吧
+        while 1 do
+            sys.wait(1000)
+            log.info("bsp", "本bsp可能未适配网络层, 请查证")
+        end
+    end
+    -- 默认都等到联网成功
+    sys.waitUntil("IP_READY")
+    sys.publish("net_ready", device_id)
+end)
+
+sys.taskInit(function()
+    sys.waitUntil("net_ready")
+    local mytopic = "my_udpsrv"
+    local srv = udpsrv.create(12345, mytopic)
+    if srv then
+        -- 单播
+        srv:send("I am UP", "192.168.1.16", 777)
+        -- 广播
+        srv:send("I am UP", "255.255.255.255", 777)
+        while 1 do
+            local ret, data = sys.waitUntil(mytopic, 15000)
+            if ret then
+                log.info("udpsrv", "收到数据", data:toHex())
+                -- 按业务处理收到的数据
+            else
+                log.info("udpsrv", "没数据,那广播一条")
+                srv:send("I am UP", "255.255.255.255", 777)
+            end
+        end
+    else
+        log.info("udpsrv", "启动失败")
+    end
+    -- 如果关闭,调用
+    -- srv:close()
+end)
+
+-- 用户代码已结束---------------------------------------------
+-- 结尾总是这一句
+sys.run()
+-- sys.run()之后后面不要加任何语句!!!!!

+ 68 - 0
script/libs/udpsrv.lua

@@ -0,0 +1,68 @@
+--[[
+@module udpsrv
+@summary UDP服务器
+@version 1.0
+@date    2023.7.28
+@author  wendal
+@demo    socket
+@usage
+-- 具体用法请查阅demo
+]]
+
+local sys = require "sys"
+
+local udpsrv = {}
+
+--[[
+创建UDP服务器
+@api udpsrv.create(port, topic)
+@int 端口号, 必填, 必须大于0小于65525
+@string 收取UDP数据的topic
+@return table UDP服务的实体, 若创建失败会返回nil
+]]
+function udpsrv.create(port, topic)
+    local srv = {}
+    -- udpsrv.port = port
+    -- srv.topic = topic
+    srv.rxbuff = zbuff.create(1500)
+    local sc = socket.create(nil, function(sc, event)
+        -- log.info("udpsrv", sc, event)
+        if event == socket.EVENT then
+            local rxbuff = srv.rxbuff
+            local succ, data_len = socket.rx(sc, rxbuff)
+            if succ and data_len and data_len > 0 then
+                local resp = rxbuff:toStr(0, rxbuff:used())
+                rxbuff:del()
+                sys.publish(udpsrv.topic, resp)
+            end
+        end
+    end)
+    if sc == nil then
+        return
+    end
+    srv.sc = sc
+    -- socket.debug(sc, true)
+    socket.config(sc, port, true)
+    if socket.connect(sc, "0.0.0.0", 0) then
+        srv.send = function(self, data, ip, port)
+            if self.sc and data then
+                -- log.info("why?", self.sc, data, ip, port)
+                return socket.tx(self.sc, data, ip or "0.0.0.0", port)
+            end
+        end
+        srv.close = function(self)
+            socket.close(self.sc)
+            -- sys.wait(200)
+            socket.release(self.sc)
+            self.sc = nil
+        end
+        -- log.info("udpsrv", "监听开始")
+        return srv
+    end
+    socket.close(udpsrv.sc)
+    -- sys.wait(200)
+    socket.release(udpsrv.sc)
+    -- log.info("udpsrv", "监听失败")
+end
+
+return udpsrv