在《网络通信:通过UDP发送数据》一文中,我们对在Rainbow总进行UDP通信有了初步认识,今天我们将分析一下UDP接收数据,并实现一个Echo服务器的功能:客户端通过UDP发送过来的数据,服务器原封不动地回传过去。
其实,做UDP接收也同样简单,在进行网络初始化,设置了UDP监听端口后,只需要调用UDP.parsePacket(),如果返回值大于零,表明有数据发送过来,可以进行接收操作,如:使用UDP.read()可以从UDP接收到的数据包中读取一个字节的数据,UDP.readString()可以读取接收到的字符串,当然还有更多丰富的读写操作方法。实际上UDP是Stream的子类,Stream中所有对流进行操作的函数都可以使用。对c++比较熟悉的人可以参考Stream.cpp、Stream.h中的定义和实现。
在软件包的“Projects\UDP-Echo”文件夹包含了本文的完整工程,可以直接编译、烧写和调试。这个程序主要展示如何实现UDP-Echo服务器,看看main.cpp的代码:
#include "WProgram.h"
#include "Ethernet.h"
#include "EthernetUDP.h"
//网络模块的MAC地址
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
//网络模块的IP地址
IPAddress ip(192, 168, 1, 15);
//定义UDP对象
EthernetUDP UDP;
void setup()
{
//初始化Rainbow
boardInit();
//初始化默认串口
Serial.begin();
Serial.println("UDP-Echo start...");
//对网络进行初始化
Ethernet.begin(mac, ip);
//UDP监听端口
UDP.begin(6000);
}
void loop()
{
//判断是否接收到UDP数据包
if(UDP.parsePacket() > 0)
{
//打印出对方的ip和端口
Serial.print("from:");
Serial.print(UDP.remoteIP());
Serial.print(":");
Serial.println(UDP.remotePort());
//向对方将数据发送回去
UDP.beginPacket();
int c = UDP.read();
while(c > 0)
{
UDP.write(c);
c = UDP.read();
}
//换行
UDP.println();
UDP.endPacket();
}
}
int main()
{
setup();
while(1) loop();
}
上面的程序非常简单,首先通过UDP.parsePacket()的返回值判断又可以发送给服务器的UDP数据包,如果有数据包,就将对方的ip和端口通过串口输出,然后通过UDP.read()接收UDP数据,并将所有的数据通过UDP.write()写入到要发送的UDP数据包中,并发送给对方。
上面的程序编译无误后,将程序烧写到Rainbow中,然后在电脑上运行串口调试工具并和Rainbow连接成功,启动UDP监听,可以在串口调试工具中看到输出的日志,通过UDP向Rainbow发送“Hello,world!”,在调试工具中立刻会接收到我们开始发送的信息: