LWIP提供了三种的可以被应用程序直接调用的接口API:
(1) 低水平的,基于内核/回调函数的API(后面称 RAW API) 适用于数据量不大,没有os的MCU
(2) 高水平的,连续的API(后面称LwIP API) 这种方式最常用,需要os支持,适用于传输数据量大的场合
(3) BSD风格的套接字API(后面称BSD socket) 目前还不太稳定
本文介绍的是处于传输层的udp和tcp。两者的区别和各自使用的场合这里就不再赘叙
TCP/IP网络四层模型
(1).udp简介
端口号表示发送和接收进程, UDP 协议使用端口号为不同的应用保留各自的数据传输通,UDP 和 TCP 协议都是采用端口号对同一时刻内多项应用同时发送和接收数据,而数据接收方则通过目标端口接收数据。有的网络应用只能使用预先为其预留或注册的静态端口;而另外一协议使用报头中的校验和来保证数据的安全 。
在LWIP中有关处理的函数关系如下:
(2)udp整个通信过程如下图:
(3)其实通讯过程很简单,下面看一下代码
① 接收函数就是遍历整个pbuf链表,将pbuf的数据存储区域payload里面的数据memcpy到数组里
1 //UDP回调函数 2 void udp_demo_recv(void *arg,struct udp_pcb *upcb,struct pbuf *p, struct ip4_addr *addr,u16_t port) 3 { 4 u32 data_len = 0; 5 struct pbuf *q; 6 if(p!=NULL) //接收到不为空的数据时 7 { 8 memset(udp_demo_recvbuf,0,UDP_DEMO_RX_BUFSIZE); //数据接收缓冲区清零 9 for(q=p;q!=NULL;q=q->next) //遍历完整个pbuf链表 10 { 11 //判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于 12 //的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 13 if(q->len > (UDP_DEMO_RX_BUFSIZE-data_len)) memcpy(udp_demo_recvbuf+data_len,q->payload,(UDP_DEMO_RX_BUFSIZE-data_len));//拷贝数据 14 else memcpy(udp_demo_recvbuf+data_len,q->payload,q->len); 15 data_len += q->len; 16 if(data_len > UDP_DEMO_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出 17 } 18 upcb->remote_ip=*addr; //记录远程主机的IP地址 19 upcb->remote_port=port; //记录远程主机的端口号 20 udp_demo_flag|=1<<6; //标记接收到数据了 21 pbuf_free(p);//释放内存 22 } 23 else 24 { 25 debug("connect has been break !!!!\r\n"); 26 } 27 }