IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 野火挑战者V2 STM32F429IGT6开发板TCP客户端通信实现 -> 正文阅读

[网络协议]野火挑战者V2 STM32F429IGT6开发板TCP客户端通信实现

在上一篇推文?野火挑战者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 <stdio.h>	
#include <string.h>

  
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中,最后再通过串口将接收的消息以字符串的格式打印出来。

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

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 13:08:02  更:2022-10-17 13:11:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 3:31:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码