使用Arduino开发ESP32(04):UDP通讯使用说明

您所在的位置:网站首页 udp监听是什么 使用Arduino开发ESP32(04):UDP通讯使用说明

使用Arduino开发ESP32(04):UDP通讯使用说明

2024-07-12 21:34| 来源: 网络整理| 查看: 265

文章目录 目的常规UDP使用示例常用方法说明 异步UDP使用示例常用方法说明 总结

目的

UDP是网络应用中常用的功能,可以算是最简单的功能了,学会使用UDP就可以开发很多网络应用了。

常规UDP 使用示例

UDP使用比较简单,直接使用下面代码进行测试:

#include #include //引用以使用UDP const char *ssid = "********"; const char *password = "********"; WiFiUDP Udp; //创建UDP对象 unsigned int localUdpPort = 2333; //本地端口号 void setup() { Serial.begin(115200); Serial.println(); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (!WiFi.isConnected()) { delay(500); Serial.print("."); } Serial.println("Connected"); Serial.print("IP Address:"); Serial.println(WiFi.localIP()); Udp.begin(localUdpPort); //启用UDP监听以接收数据 } void loop() { int packetSize = Udp.parsePacket(); //获取当前队首数据包长度 if (packetSize) //如果有数据可用 { char buf[packetSize]; Udp.read(buf, packetSize); //读取当前包数据 Serial.println(); Serial.print("Received: "); Serial.println(buf); Serial.print("From IP: "); Serial.println(Udp.remoteIP()); Serial.print("From Port: "); Serial.println(Udp.remotePort()); Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //准备发送数据 Udp.print("Received: "); //复制数据到发送缓存 Udp.write((const uint8_t*)buf, packetSize); //复制数据到发送缓存 Udp.endPacket(); //发送数据 } }

在这里插入图片描述

常用方法说明 uint8_t begin(uint16_t p) uint8_t begin(IPAddress a, uint16_t p) 启动监听某个端口,或者来自某地址发送给某端口的数据;void stop() 停止监听,释放资源;int beginPacket() 准备发送数据包(仅在运行parsePacket()方法且返回值大于0时可用);int beginPacket(IPAddress ip, uint16_t port) 准备发送数据包,参数分别为目标IP和目标端口号;size_t write(uint8_t) size_t write(const uint8_t *buffer, size_t size) 复制数据到发送缓存(同一数据包发送缓存最大1460字节);int endPacket() 发送数据;int parsePacket() 获取接收数据信息,如果有数据包可用,则返回队首数据包长度,否则返回0;int read() 读取首字节数据(仅在运行parsePacket()方法且返回值大于0时可用);int read(unsigned char* buffer, size_t len) int read(char* buffer, size_t len) 读取数据(仅在运行parsePacket()方法且返回值大于0时可用);int peek() 读取首字节数据,但并不从接收缓存中删除它(仅在运行parsePacket()方法且返回值大于0时可用);void flush() 清空当前接收缓存(仅在运行parsePacket()方法且返回值大于0时可用);IPAddress remoteIP() 返回远端地址(仅在运行parsePacket()方法且返回值大于0时可用);uint16_t remotePort() 返回远端端口号(仅在运行parsePacket()方法且返回值大于0时可用); 异步UDP

异步UDP理论上可以提供比一般UDP更加优异的性能。

使用示例

可以使用下面的代码进行测试:

#include #include //引用以使用异步UDP const char *ssid = "********"; const char *password = "********"; AsyncUDP udp; //创建UDP对象 unsigned int localUdpPort = 2333; //本地端口号 unsigned int broadcastPort = localUdpPort; const char *broadcastData = "broadcast data"; // const uint8_t broadcastData[] = {"broadcast data"}; void onPacketCallBack(AsyncUDPPacket packet) { Serial.print("UDP数据包来源类型: "); Serial.println(packet.isBroadcast() ? "广播数据" : (packet.isMulticast() ? "组播" : "单播")); Serial.print("远端地址及端口号: "); Serial.print(packet.remoteIP()); Serial.print(":"); Serial.println(packet.remotePort()); Serial.print("目标地址及端口号: "); Serial.print(packet.localIP()); Serial.print(":"); Serial.println(packet.localPort()); Serial.print("数据长度: "); Serial.println(packet.length()); Serial.print("数据内容: "); Serial.write(packet.data(), packet.length()); Serial.println(); packet.print("reply data"); broadcastPort = packet.remotePort(); } void setup() { Serial.begin(115200); Serial.println(); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (!WiFi.isConnected()) { delay(500); Serial.print("."); } Serial.println("Connected"); Serial.print("IP Address:"); Serial.println(WiFi.localIP()); while (!udp.listen(localUdpPort)) //等待udp监听设置成功 { } udp.onPacket(onPacketCallBack); //注册收到数据包事件 } void loop() { delay(5000); udp.broadcastTo(broadcastData, broadcastPort); //可以使用该方法广播信息 // IPAddress broadcastAddr((~(uint32_t)WiFi.subnetMask())|((uint32_t)WiFi.localIP())); //计算广播地址 // udp.writeTo(broadcastData, sizeof(broadcastData), broadcastAddr, localUdpPort); //广播数据 }

在这里插入图片描述 异步UDP在收到数据时会触发事件,比起需要在loop()中查询获取数据响应要快很多。

常用方法说明

AsyncUDP类:

void onPacket(AuPacketHandlerFunctionWithArg cb, void * arg=NULL) void onPacket(AuPacketHandlerFunction cb) 注册事件,绑定回调函数;bool listen(const IPAddress addr, uint16_t port) bool listen(uint16_t port) bool listen(const IPv6Address addr, uint16_t port) bool listen(uint16_t port) 开启监听;bool listenMulticast(const ip_addr_t *addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) bool listenMulticast(const IPAddress addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) bool listenMulticast(const IPv6Address addr, uint16_t port, uint8_t ttl=1, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) 开启多播监听;bool connect(const ip_addr_t *addr, uint16_t port) bool connect(const IPAddress addr, uint16_t port) bool connect(const IPv6Address addr, uint16_t port) 作为客户端连接到服务器(连接成功后可以直接使用write、send方法,而不用writeTo、sendTo);void close() 关闭UDP;size_t writeTo(const uint8_t *data, size_t len, const ip_addr_t *addr, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t writeTo(const uint8_t *data, size_t len, const IPAddress addr, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t writeTo(const uint8_t *data, size_t len, const IPv6Address addr, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t write(const uint8_t *data, size_t len) size_t write(uint8_t data) 发送数据;size_t broadcastTo(uint8_t *data, size_t len, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t broadcastTo(const char * data, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t broadcast(uint8_t *data, size_t len) size_t broadcast(const char * data) 广播数据;size_t sendTo(AsyncUDPMessage &message, const ip_addr_t *addr, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t sendTo(AsyncUDPMessage &message, const IPAddress addr, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t sendTo(AsyncUDPMessage &message, const IPv6Address addr, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t send(AsyncUDPMessage &message) 发送数据;size_t broadcastTo(AsyncUDPMessage &message, uint16_t port, tcpip_adapter_if_t tcpip_if=TCPIP_ADAPTER_IF_MAX) size_t broadcast(AsyncUDPMessage &message) 广播数据;

AsyncUDPPacket类:

AsyncUDPPacket(AsyncUDP *udp, pbuf *pb, const ip_addr_t *addr, uint16_t port, struct netif * netif) 构造函数;uint8_t * data() 返回数据指针;size_t length() 返回数据长度;bool isBroadcast() 查询是否为广播数据;bool isMulticast() 查询是否为组播地址;IPAddress localIP() 返回目标(本地)IP;uint16_t localPort() 返回目标(本地)端口号;IPAddress remoteIP() 返回远端IP;uint16_t remotePort() 返回远端端口号;size_t read(uint8_t *data, size_t len) 读取数据;int read() 读取首字节数据;int peek() 读取首字节数据,但并不从接收缓存中删除它;void flush() 清空当前接收缓存;size_t write(const uint8_t *data, size_t len) size_t write(uint8_t data) 向远端发数据;

AsyncUDPMessage类:

AsyncUDPMessage(size_t size=CONFIG_TCP_MSS) 构造函数(这东西相当于一个缓存,把要发送的数据放到这里,然后通过相应方法发送);size_t write(const uint8_t *data, size_t len) size_t write(uint8_t data) 将数据写到AsyncUDPMessage对象;size_t space() 返回AsyncUDPMessage对象剩余可用空间;uint8_t * data() 返回AsyncUDPMessage对象中数据首指针;size_t length() 返回AsyncUDPMessage对象当前已用长度;void flush() 清空当前AsyncUDPMessage对象中的数据; 总结

UDP的使用基本上就上面那些了,UDP中还有组播的功能上面没有介绍,可以参考官方例程和源码。 更多内容参考如下: https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi https://github.com/espressif/arduino-esp32/tree/master/libraries/AsyncUDP



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3