搜索
bottom↓
回复: 0

《DNESP32S3使用指南-IDF版_V1.6》第五十三章 TCPClient实验

[复制链接]

出0入234汤圆

发表于 2024-8-6 15:54:12 | 显示全部楼层 |阅读模式
2.jpg
1)实验平台:正点原子ESP32S3开发板
2)购买链接:https://detail.tmall.com/item.htm?id=768499342659
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-347618-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学ESP32S3快速入门视频教程:https://www.bilibili.com/video/BV1sH4y1W7Tc
6)正点原子FPGA交流群:132780729
1.png
3.png

第五十三章 TCPClient实验


       本章作者重点讲解lwIP的Socket接口如何配置TCP客户端,并在此基础上实现收发功能。
       本章分为如下几个部分:
       53.1 Socket编程TCPClient连接流程
       53.2 硬件设计
       53.3 软件设计
       53.4 下载验证

       53.1 Socket编程TCPClient连接流程
       在实现TCP协议之前,用户需要按照以下步骤配置结构体sockaddr_in的成员变量,以便建立TCPClient连接:

       ①:配置ESP32-S3设备连接网络(必须的,因为WiFi是无线通信,所以需搭建通信桥梁)。

       ②:将sin_family设置为AF_INET,表示使用IPv4网络协议。

       ③:设置sin_port为所需的端口号,例如8080。

       ④:设置sin_addr.s_addr为远程IP地址。

       ⑤:调用函数Socket创建Socket连接。请注意,该函数的第二个参数指定连接类型。SOCK_STREAM表示TCP连接,而SOCK_DGRAM表示UDP连接。

       ⑥:调用函数connect连接远程IP地址。

       ⑦:调用适当的收发函数来接收或发送数据。

       通过遵循这些步骤,用户可成功地配置并建立TCPClient连接,以实现数据的发送和接收。

       53.2 硬件设计

       1. 例程功能
       本章实验功能简介:
       本实验主要通过Socket编程接口实现了一个TCPClient客户端。这个客户端具有以下功能:

       ①:可以通过按键发送TCPClient数据发送至服务器。

       ②:能够接收服务器发送的数据。

       ③:实时将接收到的数据显示在LCD屏幕上。

       通过这个实验,用户可深入了解TCP协议的工作原理,并掌握如何使用Socket编程接口来实现TCP通信。这对于开发基于TCP的网络应用程序非常有用,例如实时传输、文件传输等。


       2. 硬件资源

       1)LED灯
              LED-IO1

       2)XL9555
              IIC_INT-IO0(需在P5连接IO0)
              IIC_SDA-IO41
              IIC_SCL-IO42

       3)SPILCD
              CS-IO21
              SCK-IO12
              SDA-IO11
              DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)
              PWR- IO1_3(XL9555)
              RST- IO1_2(XL9555)

       4)ESP32-S3内部WiFi

       3. 原理图
       本章实验使用的WiFi为ESP32-S3的片上资源,因此并没有相应的连接原理图。

       53.3 软件设计

       53.3.1 程序流程图
       程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图:

第五十三章 TCPClient实验1139.png
图53.3.1.1 程序流程图

       53.3.2 程序解析
       在本章节中,我们主要关注两个文件:lwip_demo.c和lwip_demo.h。lwip_demo.h文件主要定义了发送标志位并声明了lwip_demo函数,这部分相对简单,所以我们暂不详细解释。主要关注点是lwip_demo.c文件中的函数。在lwip_demo函数中,我们配置了相关的TCPClient参数,并创建了一个名为lwip_send_thread的发送数据线程。这个线程通过调用scokec函数来发送数据到服务器。接下来,我们将分别详细解释lwip_demo函数和lwip_send_thread任务。
  1. /* 需要自己设置远程IP地址 */
  2. #define IP_ADDR   "192.168.101.33"

  3. #define LWIP_DEMO_RX_BUFSIZE            100                           /* 最大接收数据长度 */
  4. #define LWIP_DEMO_PORT                   8080                         /* 连接的本地端口号 */
  5. #define LWIP_SEND_THREAD_PRIO                  ( tskIDLE_PRIORITY + 3 )/* 发送数据线程优先级 */
  6. /* 接收数据缓冲区 */
  7. uint8_t g_lwip_demo_recvbuf[LWIP_DEMO_RX_BUFSIZE];

  8. /* 发送数据内容 */
  9. uint8_t g_lwip_demo_sendbuf[] = "ALIENTEK DATA \r\n";
  10. /* 数据发送标志位 */
  11. uint8_t g_lwip_send_flag;
  12. int g_sock = -1;
  13. int g_lwip_connect_state = 0;
  14. static void lwip_send_thread(void *arg);


  15. /**
  16. * @brief       发送数据线程
  17. * @param       无
  18. * @retval      无
  19. */
  20. void lwip_data_send(void)
  21. {
  22. xTaskCreate(lwip_send_thread, "lwip_send_thread", 4096,
  23. NULL, LWIP_SEND_THREAD_PRIO, NULL);
  24. }

  25. /**
  26. * @brief       lwip_demo实验入口
  27. * @param       无
  28. * @retval      无
  29. */
  30. void lwip_demo(void)
  31. {
  32.     struct sockaddr_in atk_client_addr;
  33.     err_t err;
  34.     int recv_data_len;
  35.     char *tbuf;
  36.    
  37.     lwip_data_send();                                        /* 创建发送数据线程 */
  38.    
  39.     while (1)
  40.     {
  41. sock_start:
  42.         g_lwip_connect_state = 0;
  43.         atk_client_addr.sin_family = AF_INET;                 /* 表示IPv4网络协议 */
  44.         atk_client_addr.sin_port = htons(LWIP_DEMO_PORT);       /* 端口号 */
  45.         atk_client_addr.sin_addr.s_addr = inet_addr(IP_ADDR);   /* 远程IP地址 */
  46.         g_sock = socket(AF_INET, SOCK_STREAM, 0);/* 可靠数据流交付服务既是TCP协议 */
  47.         memset(&(atk_client_addr.sin_zero), 0,
  48.                sizeof(atk_client_addr.sin_zero));
  49.         
  50.         tbuf = malloc(200);                                     /* 申请内存 */
  51.         sprintf((char *)tbuf, "Port:%d", LWIP_DEMO_PORT);       /* 客户端端口号 */
  52.         lcd_show_string(5, 170, 200, 16, 16, tbuf, MAGENTA);
  53.         
  54.         /* 连接远程IP地址 */
  55.         err = connect(g_sock, (struct sockaddr *)&atk_client_addr,
  56. sizeof(struct sockaddr));

  57.         if (err == -1)
  58.         {
  59.             lcd_show_string(5, 190, 200, 16, 16, "State:Disconnect", MAGENTA);
  60.             g_sock = -1;
  61.             closesocket(g_sock);
  62.             free(tbuf);
  63.             vTaskDelay(10);
  64.             goto sock_start;
  65.         }

  66.         lcd_show_string(5,190,200,16,16,"State:Connection Successful", MAGENTA);
  67.         g_lwip_connect_state = 1;
  68.         
  69.         while (1)
  70.         {
  71.             recv_data_len = recv(g_sock,g_lwip_demo_recvbuf,
  72.                                  LWIP_DEMO_RX_BUFSIZE,0);
  73.             if (recv_data_len <= 0 )
  74.             {
  75.                 closesocket(g_sock);
  76.                 g_sock = -1;
  77.                 lcd_fill(5, 190, lcd_self.width,320, WHITE);
  78.                 lcd_show_string(5, 190, 200,16,16,"State:Disconnect", MAGENTA);
  79.                 free(tbuf);
  80.                 goto sock_start;
  81.             }
  82.             
  83.             printf("%s\r\n",g_lwip_demo_recvbuf);
  84.             vTaskDelay(10);
  85.         }
  86.     }
  87. }

  88. /**
  89. * @brief       发送数据线程函数
  90. * @param       pvParameters : 传入参数(未用到)
  91. * @retval      无
  92. */
  93. void lwip_send_thread(void *pvParameters)
  94. {
  95.     pvParameters = pvParameters;
  96.    
  97.     err_t err;
  98.    
  99.     while (1)
  100.     {
  101.         while (1)
  102.         {
  103.             if(((g_lwip_send_flag & LWIP_SEND_DATA) == LWIP_SEND_DATA)
  104. && (g_lwip_connect_state == 1)) /* 有数据要发送 */
  105.             {
  106.                 err = write(g_sock, g_lwip_demo_sendbuf,
  107.                             sizeof(g_lwip_demo_sendbuf));
  108.                
  109.                 if (err < 0)
  110.                 {
  111.                     break;
  112.                 }
  113.                
  114.                 g_lwip_send_flag &= ~LWIP_SEND_DATA;
  115.             }
  116.             
  117.             vTaskDelay(10);
  118.         }
  119.         
  120.         closesocket(g_sock);
  121.     }
  122. }
复制代码
       在上述源码中,首先创建了一个用于发送ESP32-S3设备数据的任务。然后,对TCPClient进行网络参数配置,并调用connect函数来建立与远程服务器的连接。当连接成功时,系统将进入接收轮询任务。如果出现断开连接的情况,系统将尝试重新连接服务器。在发送线程中,发送数据前会检查标志位。如果标志位有效,则通过write函数发送数据并重置标志位。

       53.4 下载验证
       在程序中,首先需要设置好能够连接的网络账号和密码。然后,使用笔记本电脑作为终端,确保它与ESP32-S3设备处于同一网络段内。当ESP32-S3设备成功连接到网络时,它的LCD显示屏上会显示相应的内容:

第五十三章 TCPClient实验5284.png
图53.4.1 设备连接到网络时,LCD显示的信息

       打开网络调试助手,然后配置网络参数,如TCPServer协议、端口号等,设置内容如下图所示。

第五十三章 TCPClient实验5360.png

       在确保网络连接正常后,可以通过按下开发板上的KEY0按键来发送数据至网络调试助手。当网络调试助手接收到“ALIENTEK DATA”字符串时,它会在显示区域展示这个信息。此外,用户还可以在调试助手的发送区域自行输入要发送的数据,然后点击发送键,将数据发送至ESP32-S3设备。此时,ESP32-S3的串口将打印接收到的数据,具体操作和输出如下图所示。

第五十三章 TCPClient实验5539.png
图53.4.3 接收网络调试助手的数据

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 06:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表