马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目录
一、UDP协议概述
1、UDP基本概念
2、UDP的主要特点
3、UDP的基本报文格式
二、ESP8266官方UDP库相关函数详解
三、创建UDP服务器的一样平常流程
四、ESP8266官方库 UDP 示例步伐演示
五、ESP8266官方库 UDP 步伐运行阐明
1、将步伐编译并上传到开辟板。
2、运行串口网络数据调试器 对UDP服务器进行测试。
一、UDP协议概述
1、UDP基本概念
UDP(User Datagram Protocol)—— 用户数据报协议,是互联网传输层的一个重要协议。
UDP为应用步伐提供了一种无需创建连接就可以发送封装的 IP 数据包的方法,允许应用步伐在所需的层次上架构本身的协议之外,几乎没有做什么特别的事情。
UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据包传输服务。它不提供报文到达确认、排序、及流量控制等功能。
由于使用UDP协议斲丧资源小,通信服从高,以是通常都会用于音频、视频和寻常数据的传输例如视频聚会会议都使用UDP协议,由于这种环境纵然偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
2、UDP的主要特点
(1)UDP是无连接的协议。即在发送数据前不需要创建连接,发送数据竣事也没有连接开释,因此减少了开销和发送数据前的时延。
(2)UDP使用尽最大努力交付。即不包管可靠交付,因此不需要维护复杂的连接状态表。
(3)UDP是面向数据报的。对于应用层交付的报文,发送方的UDP在添加首部后直接交付给IP层。UDP对应用层交付的报文,既不合并,也不拆分,而是保留这些报文的边界。也就是说,应用层给UDP多长报文,UDP就发多长,一次发送一个报文。
(4)在接收方的UDP,对于IP层交付的UDP用户数据报,在去除UDP首部后也直接交付应用层,不作任何处理,一次交付一个完整的报文。因此,控制报文长度的工作由应用层负责,应用层要选择合适大小的报文。若报文太长,UDP封装后交给IP层,IP层在传输时大概要进行分片处理,减低了IP层的服从。反之,应用层报文太短,服从也低。
(5)UDP没有拥塞控制机制。因此,网络出现的拥塞不会使源主机的发送速率低落。这对某些实时应用很重要,如IP电话,实时视频聚会会议等,要求源主机以恒定的速率发送数据,并且允许在网络拥塞时丢失一部分数据,但不允许数据有太大的时延。
(6)UDP支持一对一,一对多,多对一和多对多的交互通信。
(7)UDP的首部开销小,只有8字节,比TCP的20字节的首部短。
3、UDP的基本报文格式
UDP报头由4部分构成:
源端口号:发送方的端口号。
目的端口号:目的主机的端口号。
UDP长度:UDP报文的长度,单元字节,包括报头和有用载荷。
UDP校验和:包管报文完整性和正确性,出错就抛弃。
二、ESP8266官方UDP库相关函数详解
1. begin(uint16_t port)
功能:初始化 WiFiUDP库和网络设置,启动WiFiUDP套接字,侦听指定的本地端口
参数:port,指定侦听的本地端口号
返回值:1,成功;0,失败,表现没有可用的套接字
- // initialize, start listening on specified port.
- // Returns 1 if successful, 0 if there are no sockets available to use
- uint8_t begin(uint16_t port) override;
复制代码 2. available()
功能:返回当前数据包中,可从缓冲区读取的字节数。这是已经到达的数据。
参数:无
返回值:当前数据包中可用的字节数
注意:仅在调用分析数据包函数WiFiUDP.parsePacket()之后,才能成功调用此函数。
- // Number of bytes remaining in the current packet
- int available() override;
复制代码 3. beginPacket(hostName, port) 或 beginPacket(hostIp, port)
功能:开始构建数据包,准备写入数据,以发送到指定ip和端口的长途主机。
参数:长途主机的IP地址(或域名)和端口号
返回值:假如成功,则返回1;假如提供的IP地址或端口有题目,则返回0。
- // Start building up a packet to send to the remote host specific in ip and port
- // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
- int beginPacket(IPAddress ip, uint16_t port) override;
- // Start building up a packet to send to the remote host specific in host and port
- // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
- int beginPacket(const char *host, uint16_t port) override;
复制代码 4. endPacket()
功能:写入UDP数据后,完成数据找包并发送。
参数:无
返回值:报文发送成功,返回1;如有错误,返回0
- // Finish off this packet and send it
- // Returns 1 if the packet was sent successfully, 0 if there was an error
- int endPacket() override;
复制代码 5. write(byte) 或 write(buffer, size)
功能:前者,将单个字节内容,写入UDP数据包;后者,将缓冲区中指定命目的字节数,写入UDP数据包。
参数:byte,发送的字节;buffer:数据缓冲区指针;size,缓冲区大小。
返回值:写入UDP数据包的字节数。
注意:此函数必须包装在beginPacket()和endPacket()之间。其中,beginPacket()初始化数据包,endPacket()完成数据包的发送。
- // Write a single byte into the packet
- size_t write(uint8_t) override;
- // Write size bytes from buffer into the packet
- size_t write(const uint8_t *buffer, size_t size) override;
复制代码 6. parsePacket ()
功能:开始处理下一个可用的传入数据包
参数:无
返回值:返回数据包的大小(以字节为单元),如无可用的数据包,则返回0
注意:在使用UDP.read()读取缓冲区之前,必须先行调用parsePacket ()。
- // Start processing the next available incoming packet
- // Returns the size of the packet in bytes, or 0 if no packets are available
- int parsePacket() override;
复制代码 7. peek()
功能:从当前数据包中读取并返回下一个字节,但并不向前移动到下一个字节。也就是说,对peek()的连续调用将返回类似的值,与对下一个read()的调用类似。
返回值:下一个字节或字符;假如没有可供读取的字节则返回-1
- // Return the next byte from the current packet without moving on to the next byte
- int peek() override;
复制代码 8. read() 或 read(buffer, len)
功能:前者,从当前数据包中读取一个字节;后者,从当前数据包中读取 len 个字节的数据,并将其存入buffer指定的缓冲区。
参数:buffer,将要生存数据的缓冲区指针;len,要求要读取的字节数。
返回值:前者,读取到的字节数据;后者,读取到的字节数。如无可供读取的字节则返回0
注意:在函数 parsePacket() 实行成功之后,才能调用此函数
- // Read a single byte from the current packet
- int read() override;
- // Read up to len bytes from the current packet and place them into buffer
- // Returns the number of bytes read, or 0 if none are available
- int read(unsigned char* buffer, size_t len) override;
复制代码 9. flush()
功能:等待发送所有传出字符,此调用后输出缓冲区将被清空
- // wait for all outgoing characters to be sent, output buffer is empty after this call
- void flush() override;
复制代码 10. stop()
功能:断开 UDP 连接,开释 UDP 会话期间所使用的资源。
- // Finish with the UDP connection
- void stop() override;
复制代码 11. remotelP()
功能:获取发送当前数据包的长途主机的IP地址
返回值:发送当前数据包的长途主机IP地址(4个字节的IPAddress结构)
注意:必须在WiFiUDP.parsePacket()之后,才能调用此函数
- // Return the IP address of the host who sent the current incoming packet
- IPAddress remoteIP() override;
复制代码 12. remotePort()
功能:获取长途连接主机的端口号
返回值:发送当前数据包的长途主机的端口号
注意:必须在WiFiUDP.parsePacket()之后,才能调用此函数
- // Return the port of the host who sent the current incoming packet
- uint16_t remotePort() override;
复制代码 三、创建UDP服务器的一样平常流程
1、将ESP8266模组或开辟板设置在station工作模式:WiFi.mode(WIFI_STA)。
2、将ESP8266模组或开辟板接入到WIFI 网络:WiFi.begin(SSID,PSSD)。
3、实例化 WiFiUDP对象,开始在指定侦听端口号创建UDP连接,启动自动侦听。
4、等待输入的UDP包,处理收到的数据,并回复客户端请求的信息。
四、ESP8266官方库 UDP 示例步伐演示
启动 ArduinoIDE,从菜单栏依次点选【文件】——【示例】——【ESP8266WiFi】——【UDP】,在IDE窗口主界面打开官方 UDP 示例步伐。
将步伐编译\上传到NodeMCU-ESP8266开辟板。

- /*
- UDPSendReceive.pde:
- This sketch receives UDP message strings, prints them to the serial port
- and sends an "acknowledge" string back to the sender
- A Processing sketch is included at the end of file that can be used to send
- and received messages for testing with a computer.
- created 21 Aug 2010
- by Michael Margolis
- This code is in the public domain.
- adapted from Ethernet library examples
- */
- #include <ESP8266WiFi.h>
- #include <WiFiUdp.h>
- #ifndef STASSID
- #define STASSID "xcb940" //将SSID更改成可用的名称
- #define STAPSK "87589940abc" //更改成可用的密码
- #endif
- unsigned int localPort = 8888; // local port to listen on
- // buffers for receiving and sending data
- char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // buffer to hold incoming packet,
- char ReplyBuffer[] = "acknowledged\r\n"; // a string to send back
- WiFiUDP Udp;
- void setup() {
- Serial.begin(115200);
- WiFi.mode(WIFI_STA);
- WiFi.begin(STASSID, STAPSK);
- while (WiFi.status() != WL_CONNECTED) {
- Serial.print('.');
- delay(500);
- }
- Serial.print("Connected! IP address: ");
- Serial.println(WiFi.localIP());
- Serial.printf("UDP server on port %d\n", localPort);
- Udp.begin(localPort);
- }
- void loop() {
- // if there's data available, read a packet
- int packetSize = Udp.parsePacket();
- if (packetSize) {
- Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort(), Udp.destinationIP().toString().c_str(), Udp.localPort(), ESP.getFreeHeap());
- // read the packet into packetBufffer
- int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
- packetBuffer[n] = 0;
- Serial.println("Contents:");
- Serial.println(packetBuffer);
- // send a reply, to the IP address and port that sent us the packet we received
- Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
- Udp.write(ReplyBuffer);
- Udp.endPacket();
- }
- }
复制代码 五、ESP8266官方库 UDP 步伐运行阐明
1、将步伐编译并上传到开辟板。
如在串口监视器可以看到如下信息,阐明步伐已成功运行。
信息提示:(1)开辟板成功连接到本地WiFi,获取到IP地址为:192.168.0.103。
(2)创建UDP服务器成功,并在8888端口启动侦听。
2、运行串口网络数据调试器 对UDP服务器进行测试。
(1)调试工具:SSCOM V5.13.1 百度网盘点击下载, 提取码:b89u。
(2)运行调试工具,按照开辟板串口输出信息中的UDP服务器IP地址和端口号,设置调试工具窗口左下角的长途主机IP地址和端口号,本地IP地址和端口号由软件自动填充。
(3)点击调试工具窗口左下角【连接】按钮,在右下角空白窗口输入待发送的信息,再点击【发送】按钮,就可以向UDP服务器发送信息了。
(4)假如信息发送成功,开辟板串口监视器和调试工具上方的信息窗口,就可以看到有关信息了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |