十一、【ESP32开发全栈指南: TCP通信服务端】

news2025/6/8 17:56:23

一、TCP与UDP协议对比

1.1 基本特性比较

TCP(传输控制协议)和UDP(用户数据报协议)是两种最常用的传输层协议,它们在ESP32网络编程中都有广泛应用:

  1. 连接方式

    • TCP是面向连接的协议,通信前需要先建立连接(三次握手)
    • UDP是无连接的协议,直接发送数据包
  2. 可靠性

    • TCP提供可靠传输,保证数据无差错、不丢失、不重复且按序到达
    • UDP提供尽力而为的交付,不保证可靠性
  3. 实时性

    • UDP具有更好的实时性,传输效率更高
    • TCP由于重传机制和流量控制,实时性相对较低
  4. 连接模式

    • TCP仅支持点到点通信
    • UDP支持一对一、一对多、多对多等多种通信模式
  5. 资源消耗

    • TCP需要维护连接状态,系统资源消耗较大
    • UDP实现简单,资源消耗较少

1.2 ESP32中的协议栈支持

ESP-IDF使用开源的lwIP轻量级TCP/IP协议栈,并对原始版本进行了优化和扩展:

  • 支持BSD Socket API标准接口
  • 支持Netconn API(但官方不推荐使用)
  • 针对嵌入式系统进行了内存优化
  • 支持IPv4和IPv6双协议栈

二、TCP服务器核心API

2.1 关键Socket函数

ESP32通过BSD Socket接口实现TCP通信,主要API包括:

  1. socket() - 创建通信端点
  2. bind() - 绑定本地地址和端口
  3. listen() - 开始监听连接请求
  4. accept() - 接受客户端连接
  5. recv()/send() - 接收/发送数据
  6. shutdown()/close() - 关闭连接

2.2 特殊功能支持

除了标准BSD Socket API外,ESP32还支持:

  • fcntl() - 控制socket属性
  • ioctl() - I/O设备控制
  • select() - I/O多路复用
  • poll() - (通过select实现)

三、TCP服务器实现流程

3.1 完整实现步骤

  1. 创建socket

    int listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if(listen_sock < 0) {
        ESP_LOGE(TAG, "创建socket失败: errno %d", errno);
    }
    
  2. 配置服务器地址

    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    dest_addr.sin_port = htons(TCP_PORT);
    
  3. 绑定地址

    int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if(err != 0) {
        ESP_LOGE(TAG, "绑定失败: errno %d", errno);
        close(listen_sock);
    }
    
  4. 开始监听

    err = listen(listen_sock, 1);  // 参数1表示最大等待连接数
    if(err != 0) {
        ESP_LOGE(TAG, "监听失败: errno %d", errno);
        close(listen_sock);
    }
    
  5. 接受连接

    struct sockaddr_in6 source_addr;
    uint addr_len = sizeof(source_addr);
    int connect_sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
    
  6. 数据收发

    // 接收数据
    len = recv(connect_sock, rx_buffer, sizeof(rx_buffer), 0);
    
    // 发送数据
    send(connect_sock, tx_buffer, len, 0);
    

3.2 连接管理注意事项

  • 每个accept()会创建一个新的socket专门用于该连接
  • 原始监听socket继续用于接受新连接
  • 需要合理管理连接资源,及时关闭不再使用的socket
  • 对于多客户端场景,建议使用多任务或select/poll管理

四、Wi-Fi模式配置

4.1 Station模式(连接路由器)

// 使用示例提供的辅助函数连接Wi-Fi
ESP_ERROR_CHECK(example_connect());

4.2 AP模式(创建热点)

void wifi_init_softap(void) {
    // 初始化网络接口
    esp_netif_create_default_wifi_ap();
    
    // 配置AP参数
    wifi_config_t wifi_config = {
        .ap = {
            .ssid = "ESP32_AP",
            .password = "12345678",
            .max_connection = 4,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        },
    };
    
    // 启动AP
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}

五、完整示例代码分析

5.1 主任务流程

void app_main(void)
{
    // 初始化NVS存储
    ESP_ERROR_CHECK(nvs_flash_init());
    
    // 初始化网络
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    
    // 连接Wi-Fi(Station模式)或创建AP
    // ESP_ERROR_CHECK(example_connect());  // Station模式
    wifi_init_softap();                   // AP模式
    
    // 创建TCP服务器任务
    xTaskCreate(tcp_server_task, "tcp_server", 4096, (void*)AF_INET, 5, NULL);
}

5.2 TCP服务器任务

static void tcp_server_task(void *pvParameters)
{
    // 1. 创建socket
    int listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    
    // 2. 绑定地址
    struct sockaddr_in dest_addr;
    // ... 配置地址 ...
    bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    
    // 3. 开始监听
    listen(listen_sock, 1);
    
    while(1) {
        // 4. 接受新连接
        int sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len);
        
        // 5. 处理连接
        do_retransmit(sock);
        
        // 6. 关闭连接
        close(sock);
    }
}

5.3 数据传输处理

static void do_retransmit(const int sock)
{
    char rx_buffer[128];
    
    while(1) {
        // 接收数据
        int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
        
        if(len > 0) {
            // 处理接收到的数据
            process_data(rx_buffer, len);
            
            // 发送响应
            send(sock, response, response_len, 0);
        } else if(len == 0) {
            // 连接关闭
            break;
        } else {
            // 错误处理
            handle_error();
        }
    }
}

六、性能优化与调试

6.1 常见问题解决

  1. 连接失败

    • 检查Wi-Fi连接状态
    • 确认端口未被占用
    • 检查防火墙设置
  2. 数据传输不稳定

    • 增加接收缓冲区大小
    • 实现重传机制
    • 优化任务优先级
  3. 内存不足

    • 调整lwIP内存池大小
    • 及时释放socket资源
    • 使用内存优化配置

6.2 配置选项

通过menuconfig配置关键参数:

idf.py menuconfig

重要配置项:

  • Component config → LWIP → 内存配置
  • Example Connection Configuration → Wi-Fi/以太网设置
  • Example Configuration → 服务器端口号

七、应用场景扩展

7.1 物联网控制

  • 实现远程设备控制
  • 状态监控与数据采集
  • 固件OTA升级

7.2 工业应用

  • 设备间可靠通信
  • 实时数据传输
  • 远程诊断与维护

7.3 智能家居

  • 家庭设备组网
  • 集中控制与管理
  • 安全通信保障

通过合理设计和优化,ESP32 TCP服务器可以满足各种物联网应用的通信需求,提供稳定可靠的数据传输服务。

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

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

相关文章

ESP32开发之LED闪烁和呼吸的实现

硬件电路介绍GPIO输出模式GPIO配置过程闪烁灯的源码LED PWM的控制器(LEDC)概述LEDC配置过程及现象整体流程 硬件电路介绍 电路图如下&#xff1a; 只要有硬件基础的应该都知道上图中&#xff0c;当GPIO4的输出电平为高时&#xff0c;LED灯亮&#xff0c;反之则熄灭。如果每间…

【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录

【产品业务设计】支付业务设计规范细节记录&#xff0c;含订单记录、支付业务记录、支付流水记录 前言 我为什么要写这个篇文章 总结设计经验生成设计模板方便后期快速搭建 一个几张表 一共5张表&#xff1b; 分别是&#xff1a; 订单主表&#xff1a;jjy_orderMain订单产…

2025软件供应链安全最佳实践︱证券DevSecOps下供应链与开源治理实践

项目背景&#xff1a;近年来&#xff0c;云计算、AI人工智能、大数据等信息技术的不断发展、各行各业的信息电子化的步伐不断加快、信息化的水平不断提高&#xff0c;网络安全的风险不断累积&#xff0c;金融证券行业面临着越来越多的威胁挑战。特别是近年以来&#xff0c;开源…

WebRTC通话原理与入门难度实战指南

波煮的实习公司主要是音视频业务&#xff0c;所以最近在补习WebRTC的相关内容&#xff0c;会不定期给大家分享学习心得和笔记。 文章目录 WebRTC通话原理进行媒体协商&#xff1a;彼此要了解对方支持的媒体格式网络协商&#xff1a;彼此要了解对方的网络情况&#xff0c;这样才…

N元语言模型 —— 一文讲懂!!!

目录 引言 一. 基本知识 二.参数估计 三.数据平滑 一.加1法 二.减值法/折扣法 ​编辑 1.Good-Turing 估计 ​编辑 2.Back-off (后备/后退)方法 3.绝对减值法 ​编辑4.线性减值法 5.比较 三.删除插值法(Deleted interpolation) 四.模型自适应 引言 本章节讲的…

.NET 9中的异常处理性能提升分析:为什么过去慢,未来快

一、为什么要关注.NET异常处理的性能 随着现代云原生、高并发、分布式场景的大量普及&#xff0c;异常处理&#xff08;Exception Handling&#xff09;早已不再只是一个冷僻的代码路径。在高复杂度的微服务、网络服务、异步编程环境下&#xff0c;服务依赖的外部资源往往不可…

Mac 安装git心路历程(心累版)

省流版&#xff1a;直接安装Xcode命令行工具即可&#xff0c;不用安Xcode。 git下载官网 第一部分 上网初步了解后&#xff0c;打算直接安装Binary installer&#xff0c;下载完安装时&#xff0c;苹果还阻止安装&#xff0c;只好在“设置–安全性与隐私”最下面的提示进行安…

计算机网络第2章(下):物理层传输介质与核心设备全面解析

目录 一、传输介质1.1 传输介质的分类1.2 导向型传输介质1.2.1 双绞线&#xff08;Twisted Pair&#xff09;1.2.2 同轴电缆&#xff08;Coaxial Cable&#xff09;1.2.3 光纤&#xff08;Optical Fiber&#xff09;1.2.4 以太网对有线传输介质的命名规则 1.3 非导向型传输介质…

C# 类和继承(扩展方法)

扩展方法 在迄今为止的内容中&#xff0c;你看到的每个方法都和声明它的类关联。扩展方法特性扩展了这个边 界&#xff0c;允许编写的方法和声明它的类之外的类关联。 想知道如何使用这个特性&#xff0c;请看下面的代码。它包含类MyData&#xff0c;该类存储3个double类型 的…

MySQL复杂SQL(多表联查/子查询)详细讲解

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 MySQL复杂SQL&#xff08;多表联查/子查询&a…

STM32使用土壤湿度传感器

1.1 介绍&#xff1a; 土壤湿度传感器是一种传感装置&#xff0c;主要用于检测土壤湿度的大小&#xff0c;并广泛应用于汽车自动刮水系统、智能灯光系统和智能天窗系统等。传感器采用优质FR-04双料&#xff0c;大面积5.0 * 4.0厘米&#xff0c;镀镍处理面。 它具有抗氧化&…

Windows平台RTSP/RTMP播放器C#接入详解

大牛直播SDK在Windows平台下的RTSP、RTMP播放器模块&#xff0c;基于自研高性能内核&#xff0c;具备极高的稳定性与行业领先的超低延迟表现。相比传统基于FFmpeg或VLC的播放器实现&#xff0c;SmartPlayer不仅支持RTSP TCP/UDP自动切换、401鉴权、断网重连等网络复杂场景自适应…

从 JDK 8 到 JDK 17:Swagger 升级迁移指南

点击上方“程序猿技术大咖”&#xff0c;关注并选择“设为星标” 回复“加群”获取入群讨论资格&#xff01; 随着 Java 生态向 JDK 17 及 Jakarta EE 的演进&#xff0c;许多项目面临从 JDK 8 升级的挑战&#xff0c;其中 Swagger&#xff08;API 文档工具&#xff09;的兼容性…

使用 Coze 工作流一键生成抖音书单视频:全流程拆解与技术实现

使用 Coze 工作流一键生成抖音书单视频&#xff1a;全流程拆解与技术实现&#xff08;提供工作流&#xff09; 摘要&#xff1a;本文基于一段关于使用 Coze 平台构建抖音爆火书单视频的详细讲解&#xff0c;总结出一套完整的 AI 视频自动化制作流程。内容涵盖从思路拆解、节点配…

【发布实录】云原生+AI,助力企业全球化业务创新

5 月 22 日&#xff0c;在最新一期阿里云「飞天发布时刻」&#xff0c;阿里云云原生应用平台产品负责人李国强重磅揭晓面向 AI 场景的云原生产品体系升级&#xff0c;通过弹性智能的一体化架构、开箱即用的云原生 AI 能力&#xff0c;为中国企业出海提供新一代技术引擎。 发布会…

LabVIEW主轴故障诊断案例

LabVIEW 开发主轴机械状态识别与故障诊断系统&#xff0c;适配工业场景主轴振动监测需求。通过整合品牌硬件与软件算法&#xff0c;实现从信号采集到故障定位的全流程自动化&#xff0c;为设备维护提供数据支撑&#xff0c;提升数控机床运行可靠性。 ​ 面向精密制造企业数控机…

计算机组成与体系结构:补码数制二(Complementary Number Systems)

目录 4位二进制的减法 补码系统 &#x1f9e0;减基补码 名字解释&#xff1a; 减基补码有什么用&#xff1f; 计算方法 ❓为什么这样就能计算减基补码 &#x1f4a1; 原理揭示&#xff1a;按位减法&#xff0c;模拟总减法&#xff01; 那对于二进制呢&#xff1f;&…

C#使用MindFusion.Diagramming框架绘制流程图(2):流程图示例

上一节我们初步介绍MindFusion.Diagramming框架 C#使用MindFusion.Diagramming框架绘制流程图(1):基础类型-CSDN博客 这里演示示例程序: 新建Windows窗体应用程序FlowDiagramDemo,将默认的Form1重命名为FormFlowDiagram. 右键FlowDiagramDemo管理NuGet程序包 输入MindFusio…

【物联网-ModBus-RTU

物联网-ModBus-RTU ■ 优秀博主链接■ ModBus-RTU介绍■&#xff08;1&#xff09;帧结构■&#xff08;2&#xff09;查询功能码 0x03■&#xff08;3&#xff09;修改单个寄存器功能码 0x06■&#xff08;4&#xff09;Modbus RTU 串口收发数据分析 ■ 优秀博主链接 Modbus …

Java应用10(客户端与服务器通信)

Java客户端与服务器通信 Java提供了多种方式来实现客户端与服务器之间的通信&#xff0c;下面我将介绍几种常见的方法&#xff1a; 1. 基于Socket的基本通信 服务器端代码 import java.io.*; import java.net.*;public class SimpleServer {public static void main(String…