当前位置: 首页 > news >正文

STM32 裸机 LWIP RAW接口 TCP客户端和服务端,以及UDP收发实现

RAW接口

RAW/Callback API 是 LwIP 的一大特色, 在没有操作系统支持的裸机环境中,只能使用这种 API 进行开发;此文章基于野火LWIP教程记录使用方法;使用CubeMX生成LWIP项目,1分钟就可实现TCP、UDP通信;很方便。

关于网线热插拔:我使用CubeMX生成的LWIP裸机项目中发现,网线热插拔在MX_LWIP_Process();已经做了相关处理。直接在轮询中调用即可。

/*** ----------------------------------------------------------------------* Function given to help user to continue LwIP Initialization* Up to user to complete or change this function ...* Up to user to call this function in main.c in while (1) of main(void)*-----------------------------------------------------------------------* Read a received packet from the Ethernet buffers* Send it to the lwIP stack for handling* Handle timeouts if LWIP_TIMERS is set and without RTOS* Handle the llink status if LWIP_NETIF_LINK_CALLBACK is set and without RTOS*/
void MX_LWIP_Process(void)
{
/* USER CODE BEGIN 4_1 */
/* USER CODE END 4_1 */ethernetif_input(&gnetif);/* USER CODE BEGIN 4_2 */
/* USER CODE END 4_2 *//* Handle timeouts */sys_check_timeouts();Ethernet_Link_Periodic_Handle(&gnetif); //检测网线连接状态/* USER CODE BEGIN 4_3 */
/* USER CODE END 4_3 */
}

使用方法,MAIN函数部分。

  /* Initialize all configured peripherals */MX_GPIO_Init();MX_LWIP_Init();/* USER CODE BEGIN 2 */TCP_Client_Init(); //TCP客户端TCP_Server_Init();  //TCP服务端UDP_Echo_Init();  //UDP通信/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){if(tick_1ms){MX_LWIP_Process();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */tick_1ms = false;}}

TCP 客户端

#include "tcpclient.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/init.h"
#include "netif/etharp.h"
#include "lwip/udp.h"
#include "lwip/pbuf.h"
#include <stdio.h>	
#include <string.h>#define TCP_CLIENT_PORT 5001
void TCP_Client_Init(void);static struct tcp_pcb *client_pcb = NULL;static void client_err(void *arg, err_t err)
{printf("connect error! closed by core!!\n");printf("try to connect to server again!!\n");//连接失败的时候释放TCP控制块的内存tcp_close(client_pcb);  //重新连接TCP_Client_Init();
}static err_t client_send(void *arg, struct tcp_pcb *tpcb)
{uint8_t send_buf[]= "This is a TCP Client test...\n";//发送数据到服务器tcp_write(tpcb, send_buf, sizeof(send_buf), 1); return ERR_OK;
}static err_t client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{if (p != NULL) {        /* 接收数据*/tcp_recved(tpcb, p->tot_len);/* 返回接收到的数据*/  tcp_write(tpcb, p->payload, p->tot_len, 1);memset(p->payload, 0 , p->tot_len);pbuf_free(p);} else if (err == ERR_OK) {//服务器断开连接printf("server has been disconnected!\n");tcp_close(tpcb);//重新连接TCP_Client_Init();}return ERR_OK;
}static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{printf("connected ok!\n");//注册一个周期性回调函数tcp_poll(pcb,client_send,2);//注册一个接收函数tcp_recv(pcb,client_recv);return ERR_OK;
}void TCP_Client_Init(void)
{        ip4_addr_t server_ip;/* 创建一个TCP控制块  */client_pcb = tcp_new();	  IP4_ADDR(&server_ip, DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);printf("client start connect!\n");//开始连接tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected); //注册异常处理tcp_err(client_pcb, client_err); 	     
}

TCP服务端

#include "tcpserver.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/init.h"
#include "netif/etharp.h"
#include "lwip/udp.h"
#include "lwip/pbuf.h"
#include <stdio.h>	
#include <string.h>#define TCP_Server_PORT 5001
void TCP_Server_Init(void);static err_t tcpecho_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{if (p != NULL) {        /* 更新窗口*/tcp_recved(tpcb, p->tot_len);/* 返回接收到的数据*/  tcp_write(tpcb, p->payload, p->tot_len, 1);memset(p->payload, 0 , p->tot_len);pbuf_free(p);} else if (err == ERR_OK) {return tcp_close(tpcb);}return ERR_OK;
}static err_t tcpecho_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{     tcp_recv(newpcb, tcpecho_recv);return ERR_OK;
}void TCP_Server_Init(void)
{struct tcp_pcb *pcb = NULL;	            		/* 创建一个TCP控制块  */pcb = tcp_new();	  /* 绑定TCP控制块 */tcp_bind(pcb, IP_ADDR_ANY, TCP_Server_PORT );       /* 进入监听状态 */pcb = tcp_listen(pcb);				/* 处理连接 */	tcp_accept(pcb, tcpecho_accept);   
}

UDP通信

搞不懂,UDP是无连接通信,不区分服务器和客户端;但是总有人分客户端和服务端。

#include "udpecho.h"
#include "lwip/netif.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
#include "lwip/init.h"
#include "netif/etharp.h"
#include "lwip/udp.h"
#include "lwip/pbuf.h"
#include <stdio.h>	
#include <string.h>	#define UDP_ECHO_PORT 5001
void UDP_Echo_Init(void);static void udp_demo_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{struct pbuf *q = NULL;const char* reply = "This is reply!\n";if(arg){printf("%s",(char *)arg);}pbuf_free(p);q = pbuf_alloc(PBUF_TRANSPORT, strlen(reply)+1, PBUF_RAM);if(!q){printf("out of PBUF_RAM\n");return;}memset(q->payload, 0 , q->len);memcpy(q->payload, reply, strlen(reply));udp_sendto(upcb, q, addr, port);pbuf_free(q);
}static char * st_buffer= "We get a data\n";
void UDP_Echo_Init(void)
{struct udp_pcb *udpecho_pcb;/* 新建一个控制块*/      udpecho_pcb = udp_new();    /* 绑定端口号 */udp_bind(udpecho_pcb, IP_ADDR_ANY, UDP_ECHO_PORT);/* 注册接收数据回调函数 */udp_recv(udpecho_pcb, udp_demo_callback, (void *)st_buffer);
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Binius-based zkVM:为Polygon AggLayer开发、FPGA加速的zkVM
  • python机器学习8--网络
  • 【React】JSX 实现列表渲染
  • Linux进程控制——进程等待
  • WEB前端12-axios基础
  • SQL labs-SQL注入(四,sqlmap对于post传参方式的注入)
  • Java Web应用安全防护
  • 03--KVM虚拟化
  • Python 爬虫入门(一):从零开始学爬虫 「详细介绍」
  • ES里面常用的查询语句有哪些?
  • Pytorch使用教学2-Tensor的维度
  • 探索Python的进度条神器:tqdm
  • 51单片机嵌入式开发:20、STC89C52R基于C51嵌入式点阵广告屏的设计
  • springcloud rocketmq 新增的消费者组从哪里开始消费
  • 【开发学习笔记】什么是Springboot?
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 4. 路由到控制器 - Laravel从零开始教程
  • If…else
  • Js基础——数据类型之Null和Undefined
  • LeetCode29.两数相除 JavaScript
  • node和express搭建代理服务器(源码)
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Python连接Oracle
  • session共享问题解决方案
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 力扣(LeetCode)965
  • 前嗅ForeSpider中数据浏览界面介绍
  • 使用agvtool更改app version/build
  • 手写双向链表LinkedList的几个常用功能
  • 手写一个CommonJS打包工具(一)
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • Semaphore
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • # 飞书APP集成平台-数字化落地
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (1)Android开发优化---------UI优化
  • (2)MFC+openGL单文档框架glFrame
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (function(){})()的分步解析
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (算法)大数的进制转换
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)scrum常见工具列表
  • .bashrc在哪里,alias妙用
  • .htaccess 强制https 单独排除某个目录
  • .Net Core和.Net Standard直观理解
  • .net 简单实现MD5
  • .NET的微型Web框架 Nancy
  • .net反编译的九款神器
  • .net中的Queue和Stack