udp_server_main.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. --[[
  2. @module udp_server_main
  3. @summary udp server 主应用功能模块
  4. @version 1.0
  5. @date 2025.11.15
  6. @author 王世豪
  7. @usage
  8. 本文件为udp server 主应用功能模块,核心业务逻辑为:
  9. 1、创建一个udp server,监听指定端口;
  10. 2、处理通信异常,出现异常后,重新初始化UDP服务以恢复正常数据接收;
  11. 3、调用udp_server_receiver和udp_server_sender中的外部接口,进行数据收发处理;
  12. 本文件没有对外接口,直接在main.lua中require "udp_server_main"就可以加载运行;
  13. ]]
  14. local udpsrv = require "udpsrv"
  15. -- 加载UDP服务器数据接收功能模块
  16. local udp_server_receiver = require "udp_server_receiver"
  17. -- 加载UDP服务器数据发送功能模块
  18. local udp_server_sender = require "udp_server_sender"
  19. -- 服务器监听端口
  20. local SERVER_PORT = 50003
  21. -- 服务器主题(用于接收消息)
  22. SERVER_TOPIC = "udp_server"
  23. -- udp server socket的任务处理函数
  24. local function udp_server_main_task_func()
  25. local udp_server
  26. local ret, data, remote_ip, remote_port
  27. while true do
  28. -- 如果当前时间点设置的网卡还没有连接成功,一直在这里循环等待
  29. while not socket.adapter(socket.dft()) do
  30. log.warn("udp_client_main_task_func", "wait IP_READY", socket.dft())
  31. -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
  32. -- 或者等待1秒超时退出阻塞等待状态;
  33. -- 注意:此处的1000毫秒超时不要修改的更长;
  34. -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
  35. -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
  36. -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
  37. sys.waitUntil("IP_READY", 1000)
  38. end
  39. -- 检测到了IP_READY消息
  40. log.info("udp_server_main_task_func", "recv IP_READY", socket.dft())
  41. -- 创建UDP服务器对象
  42. -- 注意:udpsrv.create有3个参数,最后一个参数是网络适配器编号
  43. udp_server = udpsrv.create(SERVER_PORT, SERVER_TOPIC, socket.dft())
  44. if not udp_server then
  45. log.error("udp_server_main_task_func", "udpsrv.create error")
  46. goto EXCEPTION_PROC
  47. end
  48. log.info("udp_server_main_task_func", "UDP server started on port", SERVER_PORT)
  49. -- 发送一条广播消息,通知端口号为50000的客户端,UDP服务器已启动
  50. udp_server:send("UDP Server is UP", "255.255.255.255", 50000)
  51. -- 数据收发以及网络连接异常事件总处理逻辑
  52. while true do
  53. -- 数据发送处理
  54. if not udp_server_sender.proc(udp_server) then
  55. log.error("udp_server_main_task_func", "udp_server_sender.proc error")
  56. end
  57. -- 等待接收数据事件
  58. ret, data, remote_ip, remote_port = sys.waitUntil(SERVER_TOPIC, 15000)
  59. if ret then
  60. -- 判断是否是发送就绪事件(通过 data 内容或 remote_ip 是否为 nil)
  61. if data == "SEND_READY" and remote_ip == nil then
  62. -- 这是发送就绪事件,无需处理接收数据,直接继续循环以发送数据
  63. log.info("udp_server_main_task_func", "send ready event received")
  64. -- 网络异常事件
  65. elseif data == "SOCKET_CLOSED" then
  66. goto EXCEPTION_PROC
  67. else
  68. -- 真实接收到的数据
  69. if not udp_server_receiver.proc(data, remote_ip, remote_port) then
  70. log.error("udp_server_main_task_func", "udp_server_receiver.proc error")
  71. end
  72. end
  73. else
  74. -- 超时,发送一条心跳广播
  75. log.info("udp_server_main_task_func", "No data received, sending broadcast heartbeat")
  76. udp_server:send("UDP Server Heartbeat", "255.255.255.255", 50000)
  77. end
  78. end
  79. ::EXCEPTION_PROC::
  80. -- 数据发送应用模块对来不及发送的数据做清空和通知失败处理
  81. udp_server_sender.exception_proc()
  82. -- 关闭UDP服务器
  83. if udp_server then
  84. udp_server:close()
  85. udp_server = nil
  86. end
  87. -- 5秒后跳转到循环体开始位置,重建udp server
  88. sys.wait(5000)
  89. end
  90. end
  91. --创建并且启动一个task
  92. --运行这个task的主函数udp_server_main_task_func
  93. sys.taskInit(udp_server_main_task_func)