如果已经移植好LWIP,就可以开始使用RAW API,如果上操作系统,还能做NETCONN呢,不过操作系统我还没搞上.所以,就只好用一些RAW API.对于UDP来说,主要函数就那么几个:
- udp_new 创建一个udp块.
- udp_bind 绑定IP,端口.
- udp_recv 接收数据.
- udp_connect 连接UDP.
- udp_send UDP发送.
- udp_disconnect 断开UDP.
- pbuf_free 释放pbuf内存.
- pbuf_alloc 申请pbuf内存.
UDP没有什么容错,类似于自己裸发串口,只有简单的校验位.从上次的Web Server的应用上来改.先创建一个,接收回传.
void udp_echoserver_init(void) { struct udp_pcb *upcb; err_t err; /* Create a new UDP control block */ upcb = udp_new(); if (upcb) { /* Bind the upcb to the UDP_PORT port */ /* Using IP_ADDR_ANY allow the upcb to be used by any local interface */ err = udp_bind(upcb, IP_ADDR_ANY, 17); if(err == ERR_OK) { /* Set a receive callback for the upcb */ udp_recv(upcb, udp_echoserver_receive_callback, NULL); } else { udp_remove(upcb); } } }
udp_echoserver_receive_callback就是收到数据后的callback值.callback里面就是如此:
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { /* Connect to the remote client */ udp_connect(upcb, addr, 17); /* Tell the client that we have accepted it */ udp_send(upcb, p); /* free the UDP connection, so we can accept new clients */ udp_disconnect(upcb); /* Free the p buffer */ pbuf_free(p); }
其中回调里面,arg就是参数,upcb就是这个UDP的PCB块,pbuf就是这个缓冲区,是个环形链表,然后是IP,端口.下面直接调用udp_send发送数据,最后会被自动调用udp_send_to,但是后面目标IP和端口,都是自动填写的,这样,就是把数据发回去.
如果要发送自己的数据,就是填写pbuf块.比如准备数据tcp_demo_sendbuf[5],并且填充,那么可以使得回传函数如下:
uint8_t tcp_demo_sendbuf[5] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { struct pbuf *ptr; ptr = pbuf_alloc(PBUF_TRANSPORT,strlen((const char*)tcp_demo_sendbuf),PBUF_POOL); ptr->payload=(void*)tcp_demo_sendbuf; /* Connect to the remote client */ udp_connect(upcb, addr, 17); /* Tell the client that we have accepted it */ udp_send(upcb, ptr); //udp_send(upcb, p); /* free the UDP connection, so we can accept new clients */ udp_disconnect(upcb); /* Free the p buffer */ pbuf_free(p); }
执行结果就是,只要我给发数据,就会有UDP数据来,如图:
我的电脑IP配置如下:
程序依旧提供下载:
大神你好,有个问题想请教你,你上面列举的方法我试了,可以将数组里的5个字节发送出去,但是如果里面有0x00的话就不行了,0x00,包括0x00之后的数据都发送不出来,请问这是什么原因呢?
@杨硕 申请pbuf时候考虑好最终大小,就可以正常发,在LWIP 2.1 / ESP32 上试了一下,可以的.
@杨硕 我认为可能是strlen引起的,0x00的字符是’\0’,表示字符串结束