LWIP+TCP客户端

一、TCP API函数

其中tcp_poll()函数的第三个参数表示隔几秒调用一次这个周期性函数

二、修改服务器的IP

三、TCP客户端编程思路

  1. 申请套接字
  2. 绑定服务器IP和端口号
  3. 等待客户端连接 进入连接回调函数
  4. 在连接回调函数中 配置一些回调函数,如接收回调函数,周期回调函数等等(类似于QT里面的信号与槽机制,等待一个信号的来临,然后执行对应的函数)
  5. 在接收回调函数里面将 接收的消息发送给客户端

四、完整代码

tcp_client.c

#include "tcp_client.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>#define IP0 192
#define IP1 168
#define IP2 1
#define IP3 104#define PORT 8080int Tcp_Client_Init(void)
{struct tcp_pcb *tcp_client_pcb;struct ip_addr ipaddr;tcp_client_pcb = tcp_new();//为tcp客户端分配一个tcp_pcb结构体if(tcp_client_pcb)//创建成功{IP4_ADDR(&ipaddr, IP0, IP1, IP2, IP3);//连接到目的地址的指定端口上,当连接成功后回调tcp_client_connected()函数tcp_connect(tcp_client_pcb, &ipaddr, PORT, tcp_client_connected);return 0;//初始化成功}return 1;//初始化失败
}//lwIP TCP连接建立后调用回调函数
static err_t tcp_client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{struct tcp_client_struct *es=NULL;  if(err==ERR_OK)   {//建立连接后发送一个connect success 信息tcp_write(pcb, "STM32F407 connect success \r\n", strlen("STM32F407 connect success \r\n"), 1);es=(struct tcp_client_struct*)malloc(sizeof(struct tcp_client_struct)); es->state=ES_TCPCLIENT_CONNECTED;//状态为连接成功es->pcb=pcb;  es->p=NULL; //更新tpcb所有回调函数的参数arg。pcb:当前TCP连接的控制块、es:需要传递给回调函数的参数tcp_arg(pcb,es);        			//配置接收回调函数tcp_recv(pcb, tcp_client_recv);//配置回调函数,该函数周期性调用,每隔一秒调用一次tcp_poll(pcb,tcp_client_poll,1);     			}else{return tcp_close(pcb);}return ERR_OK;
}//lwIP tcp_recv()函数的回调函数
static err_t tcp_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *tcp_recv_pbuf, err_t err)
{struct pbuf *tcp_send_pbuf;struct tcp_client_struct *es = (struct tcp_client_struct *)arg;//TCP客户端处于连接状态  且  接收到的数据不为空时if (es->state==ES_TCPCLIENT_CONNECTED && tcp_recv_pbuf != NULL){// 扩大收发数据的窗口tcp_recved(pcb, tcp_recv_pbuf->tot_len);// 将接收的数据拷贝给发送结构体 tcp_send_pbuf = tcp_recv_pbuf;// 将接收到的数据再转发出去,最后一个参数为1,表示立即发送数据;0表示将数据放入发送缓冲区,等待下一个发送事件再发送。tcp_write(pcb, tcp_send_pbuf->payload, tcp_send_pbuf->len, 1);pbuf_free(tcp_recv_pbuf);}else if (err != ERR_OK){if(es){free(es);es=NULL;}if(tcp_recv_pbuf){pbuf_free(tcp_recv_pbuf);//释放接收pbuftcp_recv_pbuf=NULL;}return tcp_close(pcb);}return ERR_OK;
}//lwIP tcp_poll的回调函数
err_t tcp_client_poll(void *arg, struct tcp_pcb *tpcb)
{err_t ret_err;struct tcp_client_struct *es = (struct tcp_client_struct*)arg;if(es!=NULL)  //连接处于空闲可以发送数据{}return ret_err;
} 

tcp_client.h

#ifndef __TCP_CLIENT_T
#define __TCP_CLIENT_T#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/tcp.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip_comm.h"//tcp服务器连接状态
enum tcp_client_states
{ES_TCPCLIENT_NONE = 0,		//没有连接ES_TCPCLIENT_CONNECTED,		//连接到服务器了 ES_TCPCLIENT_CLOSING,		//关闭连接
}; //LWIP回调函数使用的结构体
struct tcp_client_struct
{u8 state;//当前连接状态struct tcp_pcb *pcb;    //指向当前的pcbstruct pbuf *p;         //指向接收/或传输的pbuf
};  int Tcp_Client_Init(void);
static err_t tcp_client_connected(void *arg, struct tcp_pcb *pcb, err_t err);
static err_t tcp_client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *tcp_recv_pbuf, err_t err);
err_t tcp_client_poll(void *arg, struct tcp_pcb *tpcb);
void tcp_client_close_connection(struct tcp_pcb *tpcb);#endif

五、注意事项

如果出现客户端连接不上的情况,可以看看是否可以ping通,如果ping的过程中出现TTL传输中过期,可以尝试将以太网禁用然后启用,在等待一定的时间,看是否可以连接成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/8007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客 | 字符金字塔

请打印输出一个字符金字塔&#xff0c;字符金字塔的特征请参考样例 #include <stdio.h> #include <string.h> using namespace std; int main() {char c;scanf("%c", &c);for (int i 1; i < (c - 64); i)//第一个循环决定了有多少行{//c:67 第三…

每日两题 / 138. 随机链表的复制 148. 排序链表(LeetCode热题100)

138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 用哈希表记录原链表中的节点是否被复制过 遍历原链表并通过哈希表维护新链表 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node(int _val) {val _val;next NULL;rand…

Java | Leetcode Java题解之第74题搜索二维矩阵

题目&#xff1a; 题解&#xff1a; class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m matrix.length, n matrix[0].length;int low 0, high m * n - 1;while (low < high) {int mid (high - low) / 2 low;int x matrix[mid / n][m…

人工神经网络初步

大家好&#xff0c;这里是七七&#xff0c;由于各种比赛的缘故&#xff0c;使用了很多人工神经网络模型。但是很多的原理都不是很明白&#xff0c;就导致了不能灵活地运用┭┮﹏┭┮。为此&#xff0c;去看了些人工神经网络原理书&#xff0c;写下此专题。 在进入正文之前要先…

指针再学习笔记

概念 示例 类型 示例 作用 注意&#xff1a;有些内存地址可能系统不会允许任意访问 运算 示例 空指针

ue引擎游戏开发笔记(34)——建立射击映射,并添加特效

1.需求分析&#xff1a; 准备处理射击系统&#xff0c;首先角色需要能射击&#xff0c;有反馈&#xff0c;先建立角色与控制器之间的映射&#xff0c;并添加简单特效&#xff0c;证明映射已经建立。 2.操作实现&#xff1a; 1.首先常规建立映射流程&#xff0c;具体可参考笔记…

《挑战100个产品拆解:抖音》

抖音&#xff0c;作为当今社交媒体领域的明星产品&#xff0c;其背后的产品思维一直备受关注。在这篇文章中&#xff0c;我们将深入拆解抖音的产品思维&#xff0c;揭示其成功的秘密。 产品定位 1.产品是什么样的用户&#xff1a; 年轻人和青少年是抖音的主要用户群体。抖音…

VMware与CentOS的安装

VMware与CentOS的安装 第一章 VMware安装第二章 CentOS上网虚拟机网络IP修改地址配置修改主机名和hosts文件修改主机名称配置Linux克隆机主机名称映射hosts文件&#xff0c;打开/etc/hosts 安装Xshell7和Xftp7 第一章 VMware安装 VMware Workstation Pro 安装包 …

洗地机什么牌子最好?618高性价比家用洗地机品牌

随着科技的发展&#xff0c;智能智能清洁家电越来越受到消费者的欢迎。洗地机作为其中的佼佼者&#xff0c;已经成为许多家庭清洁的好帮手。然而&#xff0c;面对满目琳琅的洗地机品牌型号&#xff0c;究竟哪一款机型适合家用呢&#xff0c;正好618也临近了&#xff0c;又有哪些…

【每日刷题】Day33

【每日刷题】Day33 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 2. 445. 两数相加 II - 力扣&#xff08;…

牛客网刷题 | BC79 小乐乐求和

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 小乐乐最近接触了求…

鸿蒙内核源码分析(时间管理篇) | 谁是内核基本时间单位

时间概念太重要了&#xff0c;在鸿蒙内核又是如何管理和使用时间的呢? 时间管理以系统时钟 g_sysClock 为基础&#xff0c;给应用程序提供所有和时间有关的服务。 用户以秒、毫秒为单位计时.操作系统以Tick为单位计时&#xff0c;这个认识很重要. 每秒的tick大小很大程度上决…

Linux:进程等待 进程替换

Linux&#xff1a;进程等待 & 进程替换 进程等待wait接口statuswaitpid接口 进程替换exec系列接口 当一个进程死亡后&#xff0c;会变成僵尸进程&#xff0c;此时进程的PCB被保留&#xff0c;等待父进程将该PCB回收。那么父进程要如何回收这个僵尸进程的PCB呢&#xff1f;父…

js实现json数据可编辑

背景 项目中有低代码平台&#xff0c;由于历史脏数据和非同步编辑的问题&#xff0c;偶尔会出现数据错乱的问题&#xff0c;希望有一个快捷的方式修改数据 之前在用Formily的时候有注意到designable/react 里面的json数据编辑功能非常不错如果能应用到项目里就完美了 design…

【数据结构】二叉树知识点详解

树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合有一个特殊的结点&#xff0c;称为根结点&#xff0c;根节点没有前驱结点除根节点外&#xff0c;其余结点被分成M(M>0)个互不相交的集合T1、T2、…

【贪心算法】单源最短路径Python实现

文章目录 [toc]问题描述Dijkstra算法Dijkstra算法的正确性贪心选择性质最优子结构性质 Dijkstra算法应用示例Python实现时间复杂性 问题描述 给定一个带权有向图 G ( V , E ) G (V , E) G(V,E)&#xff0c;其中每条边的权是非负实数&#xff0c;给定 V V V中的一个顶点&…

【busybox记录】【shell指令】expand

目录 内容来源&#xff1a; 【GUN】【expand】指令介绍 【busybox】【expand】指令介绍 【linux】【expand】指令介绍 使用示例&#xff1a; 把制表符转化为空格 - 默认输出 把制表符转化为空格 - 修改制表符转空格的个数 把制表符转化为空格 - 修改制表符转空格的个数…

四川易点慧电子商务抖音小店:潜力无限的新零售风口

在当今数字化浪潮中&#xff0c;电子商务已经成为推动经济发展的重要引擎。四川易点慧电子商务有限公司凭借其敏锐的市场洞察力和创新精神&#xff0c;成功在抖音小店这一新兴平台上开辟出一片新天地。本文将探讨四川易点慧电子商务抖音小店的潜力及其在新零售领域的影响力。 一…

多C段的美国站群服务器有什么用途?

多C段的美国站群服务器有什么用途? 多C段的美国站群服务器是一种常见的网络运营策略&#xff0c;其用途主要体现在以下几个方面&#xff1a; 多C段的美国站群服务器有什么用途? 1. 提高站点排名和流量 部署多个站点在不同的C段IP地址上&#xff0c;可以通过不同的IP地址发布…

OpenGrok使用

以前都是用的find&#xff0c;或者VScode里面的浏览&#xff0c;但是到了Android这个就不行了&#xff0c;代码太多了。都在用OpenGrok&#xff0c;所以俺也用一下。 这里有两个步骤&#xff0c;一个是安装&#xff0c;是一个使用。 1 安装 大概看了一下&#xff0c;安装是to…