野火挑战者V2 STM32F429IGT6开发板TCP客户端通信实现

您所在的位置:网站首页 野火f429核心板v1原理图 野火挑战者V2 STM32F429IGT6开发板TCP客户端通信实现

野火挑战者V2 STM32F429IGT6开发板TCP客户端通信实现

2024-01-03 18:56| 来源: 网络整理| 查看: 265

在上一篇推文 野火挑战者V2 STM32F429IGT6开发板TCP客户端通信实现 https://mp.csdn.net/mp_blog/creation/editor/127216854 的基础上进行如下改变

1、在工程中添加 tcpclient.c、tcpclient.h 两个文件,代码如下:

        tcpclient.c  记得修改代码中服务端的IP地址和端口号

#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 #include 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); client_send(arg,pcb); return ERR_OK; } void TCP_Client_Init(void) { ip4_addr_t server_ip; /* 创建一个TCP控制块 */ client_pcb = tcp_new(); IP4_ADDR(&server_ip, 192,168,0,15); printf("client start connect!\n"); //开始连接 tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected); //注册异常处理 tcp_err(client_pcb, client_err); }

        tcpclient.h

#ifndef _TCPCLIENT_H_ #define _TCPCLIENT_H_ #define TCP_CLIENT_PORT 5001 void TCP_Client_Init(void); #endif

2、在main.c中添加头文件 #include "tcpclient.h" 以及在 main函数的wahile(1) 以前添加 TCP_Client_Init(); 语句。

编译工程,烧录到开发板中,打开串口助手和网络调试助手。网络调试助手创建TCP服务端,IP地址和端口 要和代码中的对应。如图:

 随后给开发板上电,同时监听串口助手和网络调试助手的状态。当串口调试助手出现

  client start connect!   connected ok! 则表示开发板已成功连接至电脑,同时网络调试助手也会增加变成以下状态:

 从图中可以看到,已经有一个客户端连接上了服务端,IP地址为192.168.0.14,端口为55325,这就是开发板的IP地址。同时在网络调试助手的数据接收串口内可以看到一句话 This is a TCP Client test... 而这句话就是在 tcpclient.c 代码的 client_send 函数中。该函数在 client_connected 中被调用,只要成功连接至TCP服务器就会发送该语句。

在网络调试助手的输入框中输入1234,然后点击发送数据可以看到数据接收窗口有如下变化:

 这是在 tcpclient.c 代码的 client_recv 函数中 有如下代码:

    tcp_write(tpcb, p->payload, p->tot_len, 1);          memset(p->payload, 0 , p->tot_len);     pbuf_free(p);

这段代码的作用就是在接收到服务端的内容后再将该内容写入到LWIP的tpcb控制块的发送寄存器中,然后通过LWIP发送出去。如果我们需要进行其他操作只需要修改这几条语句即可。

在此基础上稍微做如下修改:

        在tcpclient.c 文件开头添加如下代码:

                unsigned char TCP_Rrcrive_Date[255];                 unsigned int TCP_Rrcrive_length = 0;

        在 tcpclient.c 代码的 client_recv 函数修改成如下语句:

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_Rrcrive_length = p->tot_len; memcpy(TCP_Rrcrive_Date,p->payload,TCP_Rrcrive_length); /* 返回接收到的数据*/ tcp_write(tpcb, p->payload, p->tot_len, 1); memset(p->payload, 0 , p->tot_len); pbuf_free(p); printf("%s\n",TCP_Rrcrive_Date); } else if (err == ERR_OK) { //服务器断开连接 printf("server has been disconnected!\n"); tcp_close(tpcb); //重新连接 TCP_Client_Init(); } return ERR_OK; }

修改后的代码可以将TCP接收的来自服务器的数据储存在一个全局变量数组TCP_Rrcrive_Date中,同时还将数据长度储存在TCP_Rrcrive_length中,最后再通过串口将接收的消息以字符串的格式打印出来。

这里只是简单的演示下对接收数据的处理,事实上我们完全可以自己编写一个服务端数据处理函数,自定义自己的通信协议,进而实现不同的功能。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3