新闻  |   论坛  |   博客  |   在线研讨会
Arduino ESP8266 UDP通讯
Linux嵌入式 | 2023-01-03 13:26:12    阅读:1835   发布文章

1、 UDP协议

UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。

由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。

但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。UDP传输数据被限制在64K以内。

2、UDP通信Station下的通信步骤

ESP8266WiFi.h如果我们使用ESP8266的Wi-Fi,需要使用。WiFiUdp.h是专门用于UDP编程的。有了适当的库,我们需要创建一个WiFiUDP对象。然后,我们应该指定一个端口以侦听传入的数据包。最后,我们需要为传入数据包设置一个缓冲区并定义一个回复消息。

3、相关函数

1. WiFiUDP .begin(port);

· 初始化WiFi UDP库和网络设置。启动WiFiUDP套接字,侦听本地端口

· port:要侦听的本地端口(int)

· 1:成功

· 0:没有可用的套接字

2. WiFiUDP .available()

· 获取可用于从缓冲区读取的字节数(字符)。这是已经到达的数据。

仅在之后才能成功调用此函数。

available()从Stream实用程序类继承。

· 无参数

· 返回值

当前数据包中可用的字节数

0:如果尚未调用 parsePacket

3. WiFiUDP.beginPacket(hostName, port);

WiFiUDP.beginPacket(hostIp, port);

· 启动连接以将UDP数据写入远程连接

· hostName:远程主机的地址。它接受字符串或IPAddresshostIp:远程连接的IP地址(4个字节)port:远程连接的端口(整数)

· 返回值

1:如果成功

0:如果提供的IP地址或端口有问题

4.WiFiUDP.endPacket();

· 在将UDP数据写入远程连接后调用。它完成数据打包并发送。

· 返回值

1:报文发送成功

0:如果有错误

5. WiFiUDP.write(byte);WiFiUDP.write(buffer, size);

· 将UDP数据写入远程连接。必须包装在beginPacket()和endPacket()之间。beginPacket()初始化数据包,直到调用endPacket()才发送数据包。

· 参数

byte: 发送的字节buffer: 发送的数组size: 缓冲区大小

· 返回值:

· 单字节进入数据包

· 缓冲区返回数据包的字节大小

6. WiFiUDP .parsePacket()

· 它开始处理下一个可用的传入数据包,检查UDP数据包的存在,并报告大小。在使用UDP.read()读取缓冲区之前,必须调用parsePacket()。

· 返回值

数据包的大小(以字节为单位)

0:如果没有数据包可用

7. WiFiUDP .peek()

· 从文件中读取一个字节,而无需前进到下一个字节。也就是说,对peek()的连续调用将返回相同的值,与对下一个read()的调用相同。

· 返回值

下一个字节或字符

-1:如果没有可用

8. WiFiUDP.read();WiFiUDP.read(buffer, len);

· 从指定的缓冲区读取UDP数据。如果没有给出参数,它将返回缓冲区中的下一个字符。仅在之后才能成功调用此函数。

· 参数

buffer:用于保存传入数据包的缓冲区(char *)len:缓冲区的最大大小(int)

· 返回值

缓冲区中的字符(字符)

size:缓冲区的大小

-1:如果没有可用的缓冲区

9.WiFiUDP.flush()

丢弃已写入客户端但尚未读取的所有字节。

10. WiFiUDP.stop()

· 与服务器断开连接。释放UDP会话期间正在使用的所有资源。

11. WiFiUDP.remoteIP();

· 获取远程连接的IP地址。必须在之后调用此函数。

· 返回值

4个字节:发送当前传入数据包的主机的IP地址

12.WiFIUDP.remotePort()

· 获取远程UDP连接的端口。必须在之后调用此函数。

· 返回值

返回当前传入数据包的主机的端口

程序流程:

1、设置ESP8266工作在station模式(WiFi.mode(WIFI_STA));

2、将ESP8266接入到WIFI网络中WiFi.begin(SSID,PSSD);

3、实例化WiFiUDP对象指定端口,建立UDP连接,连接后自动开始侦听传入的数据包。

WiFiUDP Udp; Udp.begin(localUdpPort);

4、等待输入的UDP包处理收到的数据并回复。

Udp.parsePacket();

Udp.read(incomingPacket, 255);

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());

Udp.write(replyPacket);

Udp.endPacket();

例程:

#include <ESP8266WiFi.h>

#include <WiFiUdp.h>

const char* ssid = "********";

const char* password = "********";

WiFiUDP Udp;

unsigned int localUdpPort = 4210; // local port to listen on

char incomingPacket[255]; // buffer for incoming packets

char replyPacket[] = "Hi there! Got the message :-)"; // a reply string to send back

void setup()

{

Serial.begin(115200);

Serial.println();

Serial.printf("Connecting to %s ", ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED)

{

delay(500);

Serial.print(".");

}

Serial.println(" connected");

Udp.begin(localUdpPort);

Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);

}

void loop()

{

int packetSize = Udp.parsePacket();

if (packetSize)

{

// receive incoming UDP packets

Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());

int len = Udp.read(incomingPacket, 255);

if (len > 0)

{

incomingPacket[len] = 0;

}

Serial.printf("UDP packet contents: %s\n", incomingPacket);

// send back a reply, to the IP address and port we got the packet from

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());

Udp.write(replyPacket);

Udp.endPacket();

}

}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
工科男,多年嵌入式工作者,每日分享工作中常遇到的一些“坑”
推荐文章
最近访客