UDP(User Datagram Protocol用户数据报协议)是一种无连接、不可靠的协议。UDP协议没有流控制,没有应答确认机制,不能解决丢包、重发、错序问题。它只是简单地实现从一端主机到另一端主机的数据传输功能,数据通过IP层发送,在网络中传输,到达目标主机的顺序是无法预知的,因此需要应用程序对这些数据进行排序处理。在发送端,UDP只是把上层应用的数据封装到UDP报文中;在差错检测方面,仅仅是对数据进行了简单的校验,然后将其封装到IP数据报中发送出去。在接收端,无论是否收到数据,都不会产生一个应答返回送给源主机。如果接收到数据校验错误,接收端丢弃该UDP报文,也不会告诉源主机,这样数据是无法保障其准确性的。但是在如今的网络环境下,UDP协议传输出现错误的概率很小,并且它的实时性是非常好,常用于实时视频的传输,比如直播、网络电话等,即使是出现了数据丢失的情况,导致视频卡帧,也不会产生大的影响。UDP被广泛应用于与对传输速度有要求,并且可以容忍出现差错的数据传输中。
对于UDP通信来说,可以没有服务器,服务器只是一种规定。主动发送的一方为客户端,被动接受的一方为服务器(下图为通信过程,程序也是按照这个步骤进行设计)。
实验使用MB-039开发板,在工程中使用LwIP+FreeRTOS,实验展示如何实现UDP数据收发,实验使用到的硬件如下:
如图是MB-039(完整原理图可以通过MM32官网下载)的ETH部分接口电路。
各个信号引脚对应如下:
实验用到的API前面几节已经进行了讲解,我们直接创建UDP工程:
static void udpecho_thread(void* arg)
{
struct netconn* conn;
struct netbuf* buf;
char buffer[4096];
err_t err;
LWIP_UNUSED_ARG(arg);
conn = netconn_new(NETCONN_UDP); // (1)
netconn_bind(conn, IP_ADDR_ANY, LOCAL_PORT); // (2)
while (1) {
err = netconn_recv(conn, &buf); // (3)
if (err == ERR_OK) {
if(netbuf_copy(buf, buffer, sizeof(buffer)) != buf->p->tot_len) { // (4)
LWIP_DEBUGF(LWIP_DBG_ON, ("copy failed\n"));
}
else {
buffer[buf->p->tot_len] = '\0';
err = netconn_send(conn, buf); // (5)
if(err != ERR_OK) {
LWIP_DEBUGF(LWIP_DBG_ON, ("netconn_send failed: %d\n", (int)err));
}
else {
LWIP_DEBUGF(LWIP_DBG_ON, ("got %s\n", buffer));
}
}
netbuf_delete(buf);
}
}
}
(1)创建一个UDP类型的连接结构
(2)绑定IP地址与端口
(3)接收客户端发送的数据(值得指出的是UDP可以一对一,也可以一对多以广播的形式发送)
(4)拷贝出接收的数据
(5)将数据发送给目标主机
到这里已经完成了工程的创建,看一下PC的IP地址,设备需要处于同一网段,以方便测试。打开命令行窗口输入:ipconfig
PC的地址为:192.168.105.34,在sys\\_arch.h文件中对DEST\\_IP\\_ADDR0 、DEST\\_IP\\_ADDR1、DEST\\_IP\\_ADDR2、DEST\\_IP\\_ADDR3进行修改,DEST\\_PORT 随意修改。
#define LOCAL_PORT 2021
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 105
#define IP_ADDR3 35
将程序下载入开发板中,使用NetAssist进行如下设置:
(1)协议设置,选择UDP
(2)本机主机地址(即PC地址)
(3)端口号
(4)设置远程主机地址(即设备地址)
点击打开,在进行这一步前可以则Ping一下开发板地址,可以正常Ping通则检查端口号;如果无法Ping通则需要对工程进行检查。任意输入字符进行发送。
可以发现对接收到的数据进行了正确的转发,我们也可以使用Wireshark进行监视抓取整个过程,选择IP过滤:ip.addr==192.168.105.35。
通过上图表明实验成功。实验程序请登录我们的官网(https://www.mindmotion.com.cn/products/mm32mcu/mm32f/mm32f\\_mainstream/mm32f3270/)下载MM32F3270 SDK,工程路径如下:~\MM32F3270\\_Lib\\_Samples\\_V0.90\Demo\\_app\Ethernet\\_Demo\ETH\\_RTOS\Freertos\\_UDP。
我们下节的题目为《基于MM32F3270以太网Client的使用》。