STM32F407+CUBEMX+FreeRTOS+lwIP netconn UDP TCP记录
- 注意
- UDP
- UDP1
- UDP2
- TCP
- TCP client
- TCP server
- 图片
注意
1、超时
#include “lwipopts.h”
#define LWIP_SO_RCVTIMEO 1
2、先保证能ping通
3、关于工程创建可参考
【STM32F407+CUBEMX+FreeRTOS+lwIP之UDP记录】
4、其他可参考正点原子和野火的资料
UDP
UDP1
osThreadId_t netconn_udp_TaskHandle;
const osThreadAttr_t netconn_udp_Task_attributes = {
.name = "udp_Task",
.stack_size = 128 * 10,
.priority = (osPriority_t) (osPriorityNormal-1),
};
void Start_netconn_udp_Task(void *argument);
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN StartDefaultTask */
taskENTER_CRITICAL(); /* 进入临界区 */
netconn_udp_TaskHandle = osThreadNew(Start_netconn_udp_Task,
NULL, &netconn_udp_Task_attributes);
// netconn_udp_server_TaskHandle = osThreadNew(Start_netconn_udp_server_Task,
// NULL, &netconn_udp_server_Task_attributes);
// netconn_tcp_client_TaskHandle = osThreadNew(Start_netconn_tcp_client_Task,
// NULL, &netconn_tcp_client_Task_attributes);
// netconn_tcp_server_TaskHandle = osThreadNew(Start_netconn_tcp_server_Task,
// NULL, &netconn_tcp_server_Task_attributes);
taskEXIT_CRITICAL(); /* 退出临界区 */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
void Start_netconn_udp_Task(void *argument){
vTaskDelay(1000);
vTaskDelay(1000);
vTaskDelay(1000);
#define DEST_IP_ADDR0 192
#define DEST_IP_ADDR1 168
#define DEST_IP_ADDR2 123
#define DEST_IP_ADDR3 92
#define LWIP_DEMO_RX_BUFSIZE 2000 /* 定义最大接收数据长度 */
#define LWIP_DEMO_PORT 8083 /* 定义连接的本地端口号 */
/* 接收数据缓冲区 */
uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE];
/* 发送数据内容 */
char *g_lwip_demo_sendbuf = "ALIENTEK DATA\r\n";
err_t err;
static struct netconn *udpconn;
static struct netbuf *sentbuf,*recvbuf;
ip_addr_t destipaddr;
uint32_t data_len = 0;
struct pbuf *q;
static ip_addr_t *addr;
static unsigned short port;
/* 第一步:创建udp控制块 */
udpconn = netconn_new(NETCONN_UDP);
if(udpconn != NULL){
/* 第二步:绑定控制块、本地IP和端口 */
err = netconn_bind(udpconn, IP_ADDR_ANY, LWIP_DEMO_PORT);
/*构造目的IP地址 */
IP4_ADDR(&destipaddr, DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);
/* 第三步:连接或者建立对话框 */
netconn_connect(udpconn, &destipaddr, LWIP_DEMO_PORT); /* 连接到远端主机 */
if(err == ERR_OK){
while(1){
/* 第四步:发送信息 */
sentbuf = netbuf_new();
netbuf_alloc(sentbuf, strlen((char *)g_lwip_demo_sendbuf));
memcpy(sentbuf->p->payload, (void *)g_lwip_demo_sendbuf, strlen((char *)g_lwip_demo_sendbuf));
err = netconn_send(udpconn, sentbuf); /* 将netbuf中的数据发送出去 */
if (err != ERR_OK)
{
printf("发送失败\r\n");
netbuf_delete(sentbuf); /* 删除buf */
}
netbuf_delete(sentbuf); /* 删除buf */
/* 第五步:接收数据 */
netconn_recv(udpconn, &recvbuf);
if(recvbuf != NULL){ /* 接收到数据 */
addr = netbuf_fromaddr(recvbuf);
port = netbuf_fromport(recvbuf);
memset(g_lwip_demo_recvbuf, 0, LWIP_DEMO_RX_BUFSIZE); /* 数据接收缓冲区清零 */
for (q = recvbuf->p; q != NULL; q = q->next) /* 遍历完整个pbuf链表 */
{
/* 判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于 */
/* 的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 */
if (q->len > (LWIP_DEMO_RX_BUFSIZE - data_len)) memcpy(g_lwip_demo_recvbuf + data_len, q->payload, (LWIP_DEMO_RX_BUFSIZE - data_len)); /* 拷贝数据 */
else memcpy(g_lwip_demo_recvbuf + data_len, q->payload, q->len);
data_len += q->len;
if (data_len > LWIP_DEMO_RX_BUFSIZE) break; /* 超出TCP客户端接收数组,跳出 */
}
data_len = 0;
printf("%s,%d,%s\n",inet_ntoa(addr),port,g_lwip_demo_recvbuf);
netbuf_delete(recvbuf); /* 删除buf */
}
vTaskDelay(10);
}
}
}
}
UDP2
osThreadId_t netconn_udp_server_TaskHandle;
const osThreadAttr_t netconn_udp_server_Task_attributes = {
.name = "udp_server_Task",
.stack_size = 128 * 10,
.priority = (osPriority_t) (osPriorityNormal-1),
};
void Start_netconn_udp_server_Task(void *argument);
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN StartDefaultTask */
taskENTER_CRITICAL(); /* 进入临界区 */
// netconn_udp_TaskHandle = osThreadNew(Start_netconn_udp_Task,
// NULL, &netconn_udp_Task_attributes);
netconn_udp_server_TaskHandle = osThreadNew(Start_netconn_udp_server_Task,
NULL, &netconn_udp_server_Task_attributes);
// netconn_tcp_client_TaskHandle = osThreadNew(Start_netconn_tcp_client_Task,
// NULL, &netconn_tcp_client_Task_attributes);
// netconn_tcp_server_TaskHandle = osThreadNew(Start_netconn_tcp_server_Task,
// NULL, &netconn_tcp_server_Task_attributes);
taskEXIT_CRITICAL(); /* 退出临界区 */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
void Start_netconn_udp_server_Task(void *argument){
vTaskDelay(1000);
vTaskDelay(1000);
vTaskDelay(1000);
static struct netconn *conn;
static struct netbuf *buf;
static ip_addr_t *addr;
static unsigned short port;
err_t err, recv_err;
conn = netconn_new(NETCONN_UDP);
if (conn!= NULL)
{
err = netconn_bind(conn, IP_ADDR_ANY, 8081);
if (err == ERR_OK)
{
while (1)
{
recv_err = netconn_recv(conn, &buf);
if (recv_err == ERR_OK)
{
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
netconn_connect(conn, addr, port);
buf->addr.addr = 0;
netconn_send(conn,buf);
netbuf_delete(buf);
}
vTaskDelay(10);
}
}
else
{
netconn_delete(conn);
}
}
}
TCP
TCP client
osThreadId_t netconn_tcp_client_TaskHandle;
const osThreadAttr_t netconn_tcp_client_Task_attributes = {
.name = "tcp_client_Task",
.stack_size = 128 * 24,
.priority = (osPriority_t) (osPriorityNormal-1),
};
void Start_netconn_tcp_client_Task(void *argument);
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN StartDefaultTask */
taskENTER_CRITICAL(); /* 进入临界区 */
// netconn_udp_TaskHandle = osThreadNew(Start_netconn_udp_Task,
// NULL, &netconn_udp_Task_attributes);
// netconn_udp_server_TaskHandle = osThreadNew(Start_netconn_udp_server_Task,
// NULL, &netconn_udp_server_Task_attributes);
netconn_tcp_client_TaskHandle = osThreadNew(Start_netconn_tcp_client_Task,
NULL, &netconn_tcp_client_Task_attributes);
// netconn_tcp_server_TaskHandle = osThreadNew(Start_netconn_tcp_server_Task,
// NULL, &netconn_tcp_server_Task_attributes);
taskEXIT_CRITICAL(); /* 退出临界区 */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
void Start_netconn_tcp_client_Task(void *argument){
vTaskDelay(1000);
vTaskDelay(1000);
vTaskDelay(1000);
/* 接收数据缓冲区 */
uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE];
/* 发送数据内容 */
char *g_lwip_demo_sendbuf = "ALIENTEK DATA\r\n";
static struct netconn *tcp_clientconn = NULL; /* TCP CLIENT网络连接结构体 */
err_t err,recv_err;
ip4_addr_t server_ipaddr,loca_ipaddr;
static uint16_t server_port,loca_port;
struct pbuf *q;
uint32_t data_len = 0;
server_port = LWIP_DEMO_PORT;
IP4_ADDR(&server_ipaddr,DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3); /* 构造目的IP地址 */
while(1)
{;
tcp_clientconn = netconn_new(NETCONN_TCP); /* 创建一个TCP链接 */
/*在网之后再开服务端*/
err = netconn_connect(tcp_clientconn,&server_ipaddr,server_port); /* 连接服务器 */
if (err != ERR_OK)
{
printf("接连失败\r\n");
netconn_delete(tcp_clientconn); /* 返回值不等于ERR_OK,删除tcp_clientconn连接 */
}
else if (err == ERR_OK) /* 处理新连接的数据 */
{
struct netbuf *recvbuf;
tcp_clientconn->recv_timeout = 10;
netconn_getaddr(tcp_clientconn,&loca_ipaddr,&loca_port,1); /* 获取本地IP主机IP地址和端口号 */
printf("连接上服务器%d.%d.%d.%d,本机端口号为:%d\r\n",DEST_IP_ADDR0,DEST_IP_ADDR1, DEST_IP_ADDR2,DEST_IP_ADDR3,loca_port);
while(1){
err = netconn_write(tcp_clientconn ,g_lwip_demo_sendbuf,strlen((char*)g_lwip_demo_sendbuf),NETCONN_COPY); /* 发送tcp_server_sentbuf中的数据 */
if (err != ERR_OK)
{
printf("发送失败\r\n");
}
recv_err = netconn_recv(tcp_clientconn,&recvbuf);
if (recv_err == ERR_OK) /* 接收到数据 */
{
taskENTER_CRITICAL(); /* 进入临界区 */
memset(g_lwip_demo_recvbuf,0,LWIP_DEMO_RX_BUFSIZE); /* 数据接收缓冲区清零 */
for (q = recvbuf->p;q != NULL;q = q->next) /* 遍历完整个pbuf链表 */
{
/* 判断要拷贝到TCP_CLIENT_RX_BUFSIZE中的数据是否大于TCP_CLIENT_RX_BUFSIZE的剩余空间,如果大于 */
/* 的话就只拷贝TCP_CLIENT_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 */
if (q->len > (LWIP_DEMO_RX_BUFSIZE - data_len))
{
memcpy(g_lwip_demo_recvbuf + data_len,q->payload,(LWIP_DEMO_RX_BUFSIZE - data_len));/* 拷贝数据 */
}
else
{
memcpy(g_lwip_demo_recvbuf + data_len,q->payload,q->len);
}
data_len += q->len;
if (data_len > LWIP_DEMO_RX_BUFSIZE)
{
break; /* 超出TCP客户端接收数组,跳出 */
}
}
taskEXIT_CRITICAL(); /* 退出临界区 */
data_len = 0; /* 复制完成后data_len要清零 */
printf("%s\n",g_lwip_demo_recvbuf);
}
else if (recv_err == ERR_CLSD) /* 关闭连接 */
{
netconn_close(tcp_clientconn);
netconn_delete(tcp_clientconn);
printf("服务器%d.%d.%d.%d断开连接\r\n",DEST_IP_ADDR0,DEST_IP_ADDR1, DEST_IP_ADDR2,DEST_IP_ADDR3);
break;
}
vTaskDelay(10);
}
}
vTaskDelay(10);
}
}
TCP server
osThreadId_t netconn_tcp_server_TaskHandle;
const osThreadAttr_t netconn_tcp_server_Task_attributes = {
.name = "tcp_server_Task",
.stack_size = 128 * 24,
.priority = (osPriority_t) (osPriorityNormal-1),
};
void Start_netconn_tcp_server_Task(void *argument);
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN StartDefaultTask */
taskENTER_CRITICAL(); /* 进入临界区 */
// netconn_udp_TaskHandle = osThreadNew(Start_netconn_udp_Task,
// NULL, &netconn_udp_Task_attributes);
// netconn_udp_server_TaskHandle = osThreadNew(Start_netconn_udp_server_Task,
// NULL, &netconn_udp_server_Task_attributes);
// netconn_tcp_client_TaskHandle = osThreadNew(Start_netconn_tcp_client_Task,
// NULL, &netconn_tcp_client_Task_attributes);
netconn_tcp_server_TaskHandle = osThreadNew(Start_netconn_tcp_server_Task,
NULL, &netconn_tcp_server_Task_attributes);
taskEXIT_CRITICAL(); /* 退出临界区 */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
void Start_netconn_tcp_server_Task(void *argument){
vTaskDelay(1000);
vTaskDelay(1000);
vTaskDelay(1000);
static struct netconn *tcp_serverconn = NULL; /* TCP SERVER网络连接结构体 */
err_t err,recv_err;
struct netconn *newconn;
static ip_addr_t ipaddr;
static u16_t port;
uint8_t remot_addr[4];
uint32_t data_len = 0;
struct pbuf *q;
/* 接收数据缓冲区 */
uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE];
/* 发送数据内容 */
char *g_lwip_demo_sendbuf = "ALIENTEK DATA \r\n";
/* 第一步:创建一个TCP控制块 */
tcp_serverconn = netconn_new(NETCONN_TCP); /* 创建一个TCP链接 */
/* 第二步:绑定TCP控制块、本地IP地址和端口号 */
netconn_bind(tcp_serverconn,IP_ADDR_ANY,LWIP_DEMO_PORT); /* 绑定端口 8083号端口 */
/* 第三步:监听 */
netconn_listen(tcp_serverconn); /* 进入监听模式 */
tcp_serverconn->recv_timeout = 10; /* 禁止阻塞线程 等待10ms */
tcp_star:
while (1)
{
/* 第四步:接收连接请求 */
err = netconn_accept(tcp_serverconn,&newconn); /* 接收连接请求 */
if (err == ERR_OK){
newconn->recv_timeout = 10;
}
if (err == ERR_OK) /* 处理新连接的数据 */
{
struct netbuf *recvbuf;
netconn_getaddr(newconn,&ipaddr,&port,0); /* 获取远端IP地址和端口号 */
remot_addr[3] = (uint8_t)(ipaddr.addr >> 24);
remot_addr[2] = (uint8_t)(ipaddr.addr>> 16);
remot_addr[1] = (uint8_t)(ipaddr.addr >> 8);
remot_addr[0] = (uint8_t)(ipaddr.addr);
printf("主机%d.%d.%d.%d连接上服务器,主机端口号为:%d\r\n",remot_addr[0], remot_addr[1],remot_addr[2],remot_addr[3],port);
while (1)
{
err = netconn_write(newconn ,g_lwip_demo_sendbuf,strlen((char*)g_lwip_demo_sendbuf),NETCONN_COPY); /* 发送g_lwip_demo_sendbuf中的数据 */
if(err != ERR_OK)
{
printf("发送失败\r\n");
}
recv_err = netconn_recv(newconn,&recvbuf);
if (recv_err == ERR_OK) /* 接收到数据 */
{
taskENTER_CRITICAL(); /* 进入临界区 */
memset(g_lwip_demo_recvbuf,0,LWIP_DEMO_RX_BUFSIZE); /* 数据接收缓冲区清零 */
for (q = recvbuf->p;q != NULL;q = q->next) /* 遍历完整个pbuf链表 */
{
/* 判断要拷贝到LWIP_DEMO_RX_BUFSIZE中的数据是否大于LWIP_DEMO_RX_BUFSIZE的剩余空间,如果大于 */
/* 的话就只拷贝LWIP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据 */
if(q->len > (LWIP_DEMO_RX_BUFSIZE-data_len))
{
memcpy(g_lwip_demo_recvbuf + data_len,q->payload,(LWIP_DEMO_RX_BUFSIZE - data_len));/* 拷贝数据 */
}
else
{
memcpy(g_lwip_demo_recvbuf + data_len,q->payload,q->len);
}
data_len += q->len;
if(data_len > LWIP_DEMO_RX_BUFSIZE)
{
break; /*超出TCP客户端接收数组,跳出*/
}
}
taskEXIT_CRITICAL(); /* 退出临界区 */
data_len = 0; /* 复制完成后data_len要清零 */
printf("%s\n",g_lwip_demo_recvbuf);
netbuf_delete(recvbuf);
}
else if (recv_err == ERR_CLSD) /* 关闭连接 */
{
netconn_close(newconn);
netconn_delete(newconn);
printf("主机:%d.%d.%d.%d断开与服务器的连接\r\n",remot_addr[0], remot_addr[1],remot_addr[2],remot_addr[3]);
// break;
goto tcp_star;
}
vTaskDelay(10);
}
}
vTaskDelay(10);
}
/*ST*/
// struct netconn *conn, *newconn;
// err_t err, accept_err;
// struct netbuf *buf;
// void *data;
// u16_t len;
// /* Create a new connection identifier. */
// conn = netconn_new(NETCONN_TCP);
//
// if (conn!=NULL)
// {
// /* Bind connection to well known port number 7. */
// err = netconn_bind(conn, NULL, 7);
//
// if (err == ERR_OK)
// {
// /* Tell connection to go into listening mode. */
// netconn_listen(conn);
//
// while (1)
// {
// /* Grab new connection. */
// accept_err = netconn_accept(conn, &newconn);
//
// /* Process the new connection. */
// if (accept_err == ERR_OK)
// {
// while (netconn_recv(newconn, &buf) == ERR_OK)
// {
// do
// {
// netbuf_data(buf, &data, &len);
// printf("%s\n",data);
// netconn_write(newconn, data, len, NETCONN_COPY);
//
// }
// while (netbuf_next(buf) >= 0);
//
// netbuf_delete(buf);
// }
//
// /* Close connection and discard connection identifier. */
// netconn_close(newconn);
// netconn_delete(newconn);
// }
// }
// }
// else
// {
// netconn_delete(newconn);
// }
// }
}