RAW 编程接口 TCP 简介

一、LWIP 中 中 RAW API  编程接口中与 TCP  相关的函数

二、LWIP TCP RAW API 函数

三、LwIP_Periodic_Handle函数

LwIP_Periodic_Handle 函数是一个必须被无限循环调用的 LwIP支持函数,一般在 main函数的无限循环中调用,主要功能是为 LwIP各个模块提供时间并查询链路状态,该 函数有一个形参,用于指示当前时间,单位为 ms。 对于 TCP功能,每 250ms执行一次 tcp_tmr函数;对于 ARP,每 5s 执 行一次 etharp_tmr函数;对于链路状态检测,每 1s 执行一次ETH_CheckLinkStatus 函数; 对于 DHCP功能,每 500ms执行一次 dhcp_fine_tmr函数,如果 DHCP处于DHCP_START 或 DHCP_WAIT_ADDRESS 状态就执行LwIP_DHCP_Process_Handle 函数,对于 DHCP功 能,还有每 60s 执行一次 dhcp_coarse_tmr函数。

四、TCP客户端连接代码

tcpclinet.c

#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>
#include "main.h"


static void client_err(void *arg, err_t err)       //出现错误时调用这个函数,打印错误信息,并尝试重新连接
{
    printf("连接错误!!\n");
    printf("尝试重连!!\n");
  
	printf("重新初始化客户端\n");
	TCP_Client_Init();
}


static err_t client_send(void *arg, struct tcp_pcb *tpcb)   //发送函数,调用了tcp_write函数
{
  uint8_t send_buf[]= "我是客户端,是你的好哥哥\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("服务器断开连接!\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)
{        
	struct tcp_pcb *client_pcb = NULL;   //这一句一定要放在里面,否则会没用
  ip4_addr_t server_ip;     //因为客户端要主动去连接服务器,所以要知道服务器的IP地址
  /* 创建一个TCP控制块  */
  client_pcb = tcp_new();	  

  IP4_ADDR(&server_ip, DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);//合并IP地址

  printf("客户端开始连接!\n");
  
  //开始连接
  tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected);
	ip_set_option(client_pcb, SOF_KEEPALIVE);	
	
	printf("已经调用了tcp_connect函数\n");
  
  //注册异常处理
  tcp_err(client_pcb, client_err);
	printf("已经注册异常处理函数\n");	
}

tcpclinet.h 

#ifndef _TCPCLIENT_H_
#define _TCPCLIENT_H_

#define TCP_CLIENT_PORT 5001

void TCP_Client_Init(void);

#endif

五、TCP服务器连接代码

tcpserver.c

#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>


static err_t tcpecho_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{                                   //对应接收数据连接的控制块   接收到的数据   
  if (p != NULL) 
  {        
	//int a = 666;
	/* 更新窗口*/
	tcp_recved(tpcb, p->tot_len);     //读取数据的控制块   得到所有数据的长度   
			
    /* 返回接收到的数据*/  
  //tcp_write(tpcb, p->payload, p->tot_len, 1);

	uint8_t send_buf1[]= "我收到了你的信息!是";
	uint8_t send_buf2[]= "吗?\n";	
	tcp_write(tpcb, send_buf1, sizeof(send_buf1), 1);
	tcp_write(tpcb, p->payload, p->tot_len, 1);	
	tcp_write(tpcb, send_buf2, sizeof(send_buf2), 1);	
    
  memset(p->payload, 0 , p->tot_len);
  pbuf_free(p);
    
  } 
  else if (err == ERR_OK)    //检测到对方主动关闭连接时,也会调用recv函数,此时p为空
  {
    return tcp_close(tpcb);
  }
  return ERR_OK;
}

static err_t tcpecho_accept(void *arg, struct tcp_pcb *newpcb, err_t err) //由于这个函数是*tcp_accept_fn类型的
																																					//形参的数量和类型必须一致
{     

  tcp_recv(newpcb, tcpecho_recv);    //当收到数据时,回调用户自己写的tcpecho_recv
  return ERR_OK;
}

void TCP_Echo_Init(void)
{
  struct tcp_pcb *server_pcb = NULL;	            		
  
  /* 创建一个TCP控制块  */
  server_pcb = tcp_new();	
	printf("创建了一个控制块\n");
  
  /* 绑定TCP控制块 */
  tcp_bind(server_pcb, IP_ADDR_ANY, TCP_ECHO_PORT);       
	printf("已经绑定一个控制块\n");

  /* 进入监听状态 */
  server_pcb = tcp_listen(server_pcb);
	printf("进入监听状态\n");	

  /* 处理连接 注册函数,侦听到连接时被注册的函数被回调 */	
  tcp_accept(server_pcb, tcpecho_accept);  //侦听到连接后,回调用户编写的tcpecho_accept 
																	  //这个函数是*tcp_accept_fn类型的
}

tcpserver.h

#ifndef _TCPECHO_H_
#define _TCPECHO_H_

#define TCP_ECHO_PORT 5001

void TCP_Echo_Init(void);

#endif

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

由于找不到d3dx9_43.dll无法继续执行的解决方法,5种有效的方法

丢失d3dx9_43.dll文件可能会引发一系列运行问题&#xff0c;具体表现在哪些方面呢&#xff1f;首先&#xff0c;它是DirectX 9.0c的一个重要动态链接库文件&#xff0c;对于许多基于此版本DirectX开发的老旧或经典PC游戏至关重要。一旦缺失&#xff0c;可能导致这些游戏无法启动…

element ui 安装 简易过程 已解决

我之所以将Element归类为Vue.js&#xff0c;其主要原因是Element是&#xff08;饿了么团队&#xff09;基于MVVM框架Vue开源出来的一套前端ui组件。我最爱的就是它的布局容器&#xff01;&#xff01;&#xff01; 下面进入正题&#xff1a; 1、Element的安装 首先你需要创建…

基于Java+Selenium的WebUI自动化测试框架(一)---页面元素定位器

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

糖尿病性视网膜病变(DR)的自动化检测和分期

糖尿病性视网膜病变&#xff08;DR&#xff09;的自动化检测和分期 提出背景DR的阶段及其特征 历年解法计算机视觉方法多分类方法 新的解法深度学习方法迁移学习大模型多模型集成全流程分析 总结特征1&#xff1a;图像分割特征2&#xff1a;疾病分级特征3&#xff1a;治疗建议生…

二进制中-1加上+1如果按照原码相加会存在什么问题?

问题描述&#xff1a;二进制中-1加上1如果按照原码相加会存在什么问题&#xff1f; 问题解答&#xff1a; -1加1等于-2&#xff0c;这明显是不对的。 因此引入反码的概念 然后再将计算后反码在取反码&#xff0c;得到-0&#xff0c;如下图所示。 -0不太精确&#xff0c;因此再…

美团面试:说说Java OOM的三大场景和解决方案?

美团面试&#xff1a;说说Java OOM的场景和解决方案&#xff1f; 尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&…

day05_方法

今日内容 流程控制关键字 break,continue方法 复习 1 循环的四要素 初始值控制条件循环内容迭代 2 for循环执行流程 for(初始值;控制条件;迭代){ 循环体; } 3 while和do-while什么区别 while先判断后执行dowhile是先执行再判断(先斩后奏) 4 手写代码,写出使用for循环输出1-10的…

区块链笔记(五)---德勤相关分析报告

web3.0 定义&#xff1a; 在《Insights into a Modern World》提出&#xff0c;“信息将由用户自己发布、保管、不可追溯且永远不会泄露&#xff0c;用户的任何行为将不需要任何中间机构来帮助传递”&#xff1b;用来指代一种区块链技术&#xff0c;可以基于“无须信任的交互…

微信小程序开发:通过wx.login()获取用户唯一标识openid和unionid

下面代码展示了 openid 的获取过程。 想获取 unionid 需要满足条件&#xff1a;小程序已绑定到微信开放平台账号下&#xff0c;不然只会返回 openid。 【相关文档】 微信小程序开发&#xff1a;appid 和 secret 的获取方法 wx.login({success (res) {if (res.code) {// 发起网…

【机器学习的基本术语和概念】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 简述概要知识图谱 简述概要 提示&#xff1a;简要描述文章内容&#xff0c;适合哪些人观看 知识图谱 样本&#xff08;Sample&#xff09;/实例&#xff08;Instance&#xff09;&#xff1a;在机器学习中&#xff0c;我…

Linux中的各类时间 与 find命令的常用参数

之前研究wal日志清理的副产物&#xff0c;wal日志名被修改后文件的哪个时间会变&#xff1f;应该如何删除&#xff1f;由此整理一下Linux中atime、mtime、ctime的区别&#xff0c;以及find的常见用法。 一、 Linux中的各类时间 1. 各类时间的定义 Linux中有三种用于文件时间戳…

你听说过柔性数组吗?

目录 1. 柔性数组的概念 2. 柔性数组的特点 3. 柔性数组的使用 4. 柔性数组的优势 5.完结散花 悟已往之不谏&#xff0c;知来者犹可追 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#…

个人博客系列-项目部署-nginx(3)

使用Nginx uwsgi进行部署django项目 一. 检查项目是否可以运行 启动项目 python manage.py runserver 0.0.0.0:8099输入ip:8099 查看启动页面 出现上述页面表示运行成功 二. 安装uwsgi并配置 2.1 下载uwsgi pip install uwsgi新建文件test.py写入内容&#xff0c;测试一…

【操作系统】磁盘文件管理系统

实验六 磁盘文件管理的模拟实现 实验目的 文件系统是操作系统中用来存储和管理信息的机构&#xff0c;具有按名存取的功能&#xff0c;不仅能方便用户对信息的使用&#xff0c;也有效提高了信息的安全性。本实验模拟文件系统的目录结构&#xff0c;并在此基础上实现文件的各种…

【前端素材】推荐优质后台管理系统Spica Admin平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

会话技术之cookie和session

COOKIE 什么是COOKIE? Cookie是由网站存储在用户计算机上的小型文本文件&#xff0c;用于在用户访问网站时跟踪和识别用户。Cookie可以在用户的计算机上存储有关用户行为和偏好的信息&#xff0c;以便在用户下次访问相同网站时提供个性化的体验。以下是一些关于Cookie的重要…

C语言——指针——第2篇——(第20篇)

坚持就是胜利 文章目录 一、指针和数组二、二级指针1、什么是 二级指针&#xff1f;2、二级指针 解引用 三、指针数组模拟二维数组 一、指针和数组 问&#xff08;1&#xff09;&#xff1a;指针和数组之间是什么关系呢&#xff1f; 答&#xff1a;指针变量就是指针变量&…

【Linux】一站式教会:Ubuntu(无UI界面)使用apache-jmeter进行压测

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、Java…

C++:string类

标准库中的string类 string类 1. 字符串是表示字符序列的类 2. 标准的字符串类提供了对此类对象的支持&#xff0c;其接口类似于标准字符容器的接口&#xff0c;但添加了专门用于操作单字节字符字符串的设计特性。 3. string类是使用char(即作为它的字符类型&#xff0c;使用…

统计图曲线图绘制方法

统计图曲线图绘制方法 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图环形图绘制较难。 曲线图的曲线绘制较难&#xff0c;今提供曲线图的绘制方法供参考。 本方法采用C语言的最基本功能&#xff1a; &#xff…
最新文章