0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【HarmonyOS HiSpark Wi-Fi IoT 套件试用连载】九:远程TCP通信

开发板试用精选 来源:开发板试用 作者:电子发烧友论坛 2022-11-02 14:18 次阅读
本文来源电子发烧友社区,作者:李元江, 帖子地址:https://bbs.elecfans.com/jishu_2028163_1_1.html

今天的帖子是关于如何让手机可以与wifiiot进行远程通信。通过远程的TCP中转服务端,让手机与板子进行可以进行远程数据传输。
一、数据传输过程
该过程与局域网内的TCP服务端与客户端数据传输过程很类似。局域网内是这样的,两个设备在同一个局域网内,一个作为TCP服务端,一个作为TCP客户端,这样这两个设备就是进行局域网内的数据通信。但是两个设备不在同一个网络内,数据传输在上面的方法是行不通的。这时可以借助一个在公网的TCP中转服务端,实现两个设备的远程数据传输。数据传输过程为两个设备都作为TCP客户端,一个设备把数据传输到服务端,然后服务端把数据传输到另一个设备。但是这也要求,这两个设备的网络是可以连接到公网的,否则是无法连接到公网的TCP服务端。
二、软件设计
首先我们需要一个在公网的TCP客户端。如果各位自己有云服务器的,可以自行搭建一个TCP中转服务端。我使用的客户端是别人用于测试的客户端。软件方面需要考虑几个问题:
  • 连接服务器的切换在我的上几个帖子上,需要连接其他服务器获取时间数据或者获取天气数据。这时,我们需要在进行连接服务器切换,确保获取的数据正常。
  • 连接状态检测我们还需要进行连接状态检查,如果与TCP服务端断开,是无法正常进行数据交互的。
  • 连接重连如果检查到连接断开,或者没有连接成功,需要重新尝试进行与服务端的连接。
1、TCP相关函数
新建tcp_connect.c tcp_connect.h文件,里面主要是与TCP连接、TCP连接断开、TCP数据发送、数据接收相关的函数。注意:TCPIPADDR、TCPPORT是公网TCP客户端IP地址和端口号。其实这几个函数是在之前的tcp例程中拆分出来的,把一个函数划分为四个函数而已。
  • 设置接收超时之前的例程中,没有加入接收超时机制,如果没有接收到数据,会一直呈现阻塞状态,其他任务可能会出现无法正常运行的状态,所以我们需要加入超时机制,超过一定时间没接收到数据,也会推出退出接收过程。timeval 在头文件中。//设置接收超时struct timeval timeout={2,0};//1sif (setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval)) == -1){ printf("setsockopt failed!rn"); //goto do_cleanup;}
  • tcp_connect.c
  1. #include "tcp_connect.h"
  2. //#define TCPIPADDR "192.168.3.9"
  3. //#define TCPPORT 5678
  4. #define TCPIPADDR "115.29.109.104"
  5. #define TCPPORT 6545
  6. static int sockfd;
  7. static int netId;
  8. static struct sockaddr_in serverAddr = {0};
  9. TCP_STATIC connect_status = DISCONNECTED;
  10. //extern char sendData[30];
  11. bool TcpConnect(void)
  12. {
  13. bool connectflag = false;
  14. WifiDeviceConfig config = {0};
  15. // 准备AP的配置参数
  16. strcpy(config.ssid, PARAM_HOTSPOT_SSID);
  17. strcpy(config.preSharedKey, PARAM_HOTSPOT_PSK);
  18. config.securityType = PARAM_HOTSPOT_TYPE;
  19. osDelay(10);
  20. netId= ConnectToHotspot(&config);
  21. sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
  22. serverAddr.sin_family = AF_INET;// AF_INET表示IPv4协议
  23. serverAddr.sin_port = htons(TCPPORT);// 端口号,从主机字节序转为网络字节序
  24. if (inet_pton(AF_INET, TCPIPADDR , &serverAddr.sin_addr) <= 0) {  // 将主机IP地址从“点分十进制”字符串 转化为 标准格式(32位整数)
  25. printf("inet_pton failed!rn");
  26. goto do_cleanup;
  27. }
  28. //设置接收超时
  29. struct timeval timeout={2,0};//1s
  30. if (setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval)) == -1)
  31. {
  32. printf("setsockopt failed!rn");
  33. //goto do_cleanup;
  34. }
  35. // 尝试和目标主机建立连接,连接成功会返回0 ,失败返回 -1
  36. if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
  37. printf("connect failed!rn");
  38. goto do_cleanup;
  39. }
  40. printf("connect to server %s success!rn",TCPIPADDR);
  41. connectflag = true;
  42. connect_status = CONNECTED;
  43. do_cleanup:
  44. return connectflag;
  45. }
  46. bool TcpDisconnect(void){
  47. close(sockfd);
  48. DisconnectWithHotspot(netId);
  49. connect_status = DISCONNECTED;
  50. return true;
  51. }
  52. bool TcpSend(char *data,int len){
  53. // printf("send start!n");
  54. int retval = send(sockfd, data , len, 0);
  55. if (retval < 0) {
  56. //printf("send request failed!rn");
  57. return false;
  58. }
  59. else{
  60. // printf("send OK!n");
  61. return true;
  62. }
  63. }
  64. extern char revData[30];
  65. bool TcpRev(void){
  66. int retval =0;
  67. retval = recv(sockfd, &revData, sizeof(revData), 0);
  68. if (retval <= 0) {
  69. // printf("rev from server failed or done, %ld!rn", retval);
  70. return false;
  71. }
  72. revData[retval] = '';
  73. return true;
  74. }
复制代码
  • tcp_connect.h
  1. #ifndef __TCP_CONNECT_H
  2. #define __TCP_CONNECT_H
  3. #include
  4. #include
  5. #include
  6. #include "net_demo.h"
  7. #include "net_common.h"
  8. #include "net_params.h"
  9. #include "wifi_connecter.h"
  10. #include "ohos_init.h"
  11. #include "cmsis_os2.h"
  12. typedef enum{
  13. DISCONNECTED = 0,
  14. CONNECTED,
  15. }TCP_STATIC;
  16. extern TCP_STATIC connect_status;
  17. bool TcpConnect(void);
  18. bool TcpDisconnect(void);
  19. bool TcpSend(char *data,int len);
  20. bool TcpRev(void);
  21. #endif/*__TCP_CONNECT_H*/
复制代码
2、TCP数据接收和发送任务
新建tcptask.c 这里面这要是新建两个任务,一个是数据发送任务,一个是数据发送任务。
  • 数据发送任务在数据发送任务中,如果与服务端连接状态正常,会每隔两秒发送一次数据到服务端。这里有连接状态检查和连接重连机制,如果数据发送不成功,则把连接状态看为是未连接状态。在未连接状态,每隔两秒会尝试重新连接服务端,直到再一次成功连接上服务端。
  • 数据接收任务为了保证能够随时接收到服务端发送过来的数据,该任务会每10ms调度一次。在连接状态为已连接情况下,会执行TCP数据接收函数。

  1. #include
  2. #include
  3. #include
  4. #include "tcp_connect.h"
  5. #include "ohos_init.h"
  6. #include "cmsis_os2.h"
  7. char sendData[]="hellow tcp!";
  8. char revData[30]="";
  9. typedef enum{
  10. GET_NORMAL =0 ,
  11. GET_PROPRESS,
  12. GET_SUC,
  13. GET_FAIL,
  14. }GET_STATUS;
  15. extern GET_STATUS Get_Status;
  16. static void TcpSendTask(void *arg)
  17. {
  18. sleep(3);
  19. uint8_t i = 0;
  20. while(1){
  21. if(TcpConnect())
  22. {
  23. printf("Tcp Connect Sucn");
  24. break;
  25. }
  26. else{
  27. i++;
  28. }
  29. if(i>10)
  30. break;
  31. }
  32. if(i>10)
  33. printf("Tcp Connect failn");
  34. (void)arg;
  35. while(1)
  36. {
  37. if(connect_status == CONNECTED)
  38. {
  39. if(!TcpSend(sendData,sizeof(sendData)-1)){
  40. connect_status = DISCONNECTED;
  41. TcpDisconnect();
  42. }
  43. }
  44. else{
  45. if(Get_Status == GET_NORMAL){
  46. if(TcpConnect()){
  47. printf("Tcp Connect Sucn");
  48. }
  49. }
  50. }
  51. sleep(2);
  52. }
  53. }
  54. static void TcpSendTaskHandle(void)
  55. {
  56. osThreadAttr_t attr;
  57. attr.name = "TcpSendTask";
  58. attr.attr_bits = 0U;
  59. attr.cb_mem = NULL;
  60. attr.cb_size = 0U;
  61. attr.stack_mem = NULL;
  62. attr.stack_size = 4096;
  63. attr.priority = osPriorityNormal;
  64. if (osThreadNew(TcpSendTask, NULL, &attr) == NULL) {
  65. printf("[TcpSendTaskHandle] Falied to create TcpSendTask!n");
  66. }
  67. }
  68. APP_FEATURE_INIT(TcpSendTaskHandle);
  69. static void TcpRevTask(void *arg){
  70. (void)arg;
  71. while(1)
  72. {
  73. if(connect_status == CONNECTED)
  74. {
  75. if(TcpRev()){
  76. printf("%s",revData);
  77. }
  78. }
  79. usleep(10000);
  80. }
  81. }
  82. static void TcpRevTaskHandle(void)
  83. {
  84. osThreadAttr_t attr;
  85. attr.name = "TcpRevTask";
  86. attr.attr_bits = 0U;
  87. attr.cb_mem = NULL;
  88. attr.cb_size = 0U;
  89. attr.stack_mem = NULL;
  90. attr.stack_size = 4096;
  91. attr.priority = osPriorityNormal;
  92. if (osThreadNew(TcpRevTask, NULL, &attr) == NULL) {
  93. printf("[TcpRevTaskHandle] Falied to create TcpRevTask!n");
  94. }
  95. }
  96. APP_FEATURE_INIT(TcpRevTaskHandle);
复制代码
3、连接服务器切换
前面也说了,在获取时间或者天气数据时,需要进行连接服务端的切换,确保能接收到正确的数据。在keytask.c文件进行修改。在获取时间和天气函数前加上TCP服务断开函数,获取完之后,加上TCP连接函数。

  1. if((voltage>0.45 && voltage<0.65)&&(!keyflag))
  2. {
  3. keyflag = true;
  4. if(connect_status == CONNECTED)
  5. TcpDisconnect();
  6. //OledShowString(16,7,"Sync time...",1);
  7. //getNtpTime();
  8. //OledFillScreen(0);
  9. switch (Now_Screen){
  10. case TIMESCREEN:
  11. //OledShowString(16,7,"Sync time...",1);
  12. Get_Status = GET_PROPRESS;
  13. if(getNtpTime()){
  14. Get_Status = GET_SUC;
  15. }
  16. //OledFillScreen(0);
  17. else
  18. {
  19. //OledShowString(0,7,"Get fail...",1);
  20. Get_Status = GET_FAIL;
  21. }
  22. break;
  23. case NOWSCREEN:
  24. //OledShowString(0,7,"Get Weather...",1);
  25. Get_Status = GET_PROPRESS;
  26. if(getWeather())
  27. //OledFillScreen(0);
  28. Get_Status = GET_SUC;
  29. else
  30. {
  31. //OledShowString(0,7,"Get fail...",1);
  32. Get_Status = GET_FAIL;
  33. }
  34. break;
  35. case TOSCREEN:
  36. Get_Status = GET_PROPRESS;
  37. if(getWeather())
  38. Get_Status = GET_SUC;
  39. else
  40. {
  41. Get_Status = GET_FAIL;
  42. }
  43. break;
  44. case ATOSCREEN:
  45. Get_Status = GET_PROPRESS;
  46. if(getWeather())
  47. Get_Status = GET_SUC;
  48. else
  49. {
  50. Get_Status = GET_FAIL;
  51. }
  52. break;
  53. default:
  54. break;
  55. }
  56. TcpConnect();
  57. }
复制代码
三、演示情况
在手机端需要安装网络调试助手,附件里有我在大学时自己做的一个APP,里面包含网络调试功能。感兴趣的可以自己下载安装,就是界面很丑,有时间再进行好好进行优化。
连接到服务端,该服务端与wifiiot连接的服务端IP和端口一致。
211727v97o5r3o58pd1o0p.jpg
手机数据接收情况,每隔两秒会接收到wifiiot发送过来的“hello tcp!”信息
211735a2sxxx3z07fxsosx.jpg
手机端发送123456,wifiiot成功接收到数据,并通过串口打印出来。
211751uy3ml242j8338z1b.png
四、总结
通过公网的TCP中转服务端,实现两个不同网络的设备之间进行远程数据传输,这只是两个设备之间进行远程通信的一种方式。现在不能设置连接wifi和服务端的IP、端口,后面有时间再慢慢进行改进吧。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • wi-fi
    +关注

    关注

    14

    文章

    2107

    浏览量

    124315
  • HarmonyOS
    +关注

    关注

    79

    文章

    1967

    浏览量

    30006
  • HiSpark
    +关注

    关注

    1

    文章

    156

    浏览量

    6901
收藏 人收藏

    评论

    相关推荐

    Wi-Fi 8要来了!未来Wi-Fi技术演进方向揭秘

    产品销售中,虽然Wi-Fi 7产品的销量份额快速从年初的个位数百分比增长至14%,但Wi-Fi 6产品的销量份额依然稳定在60%左右。如果从存量设备来看,那么Wi-Fi 7路由器的占比将远远小于这个数。   智能手机等终端设备已
    的头像 发表于 11-24 03:14 145次阅读
    <b class='flag-5'>Wi-Fi</b> 8要来了!未来<b class='flag-5'>Wi-Fi</b>技术演进方向揭秘

    Wi-Fi 7与Wi-Fi 6E有什么区别

    也许很多人还在考虑是否要将使用的Wi-Fi设备升级到Wi-Fi 6或Wi-Fi 6E,而这些标准的继任者却已经开始“登堂入室”了。Wi-Fi 7是新一代
    的头像 发表于 11-07 11:38 461次阅读

    DA16200 超低功耗 Wi-Fi 模块开发套件 Pro数据手册

    电子发烧友网站提供《DA16200 超低功耗 Wi-Fi 模块开发套件 Pro数据手册.rar》资料免费下载
    发表于 05-30 17:53 1次下载
    DA16200 超低功耗 <b class='flag-5'>Wi-Fi</b> 模块开发<b class='flag-5'>套件</b> Pro数据手册

    DA16200 超低功耗 Wi-Fi 模块开发套件数据手册

    电子发烧友网站提供《DA16200 超低功耗 Wi-Fi 模块开发套件数据手册.rar》资料免费下载
    发表于 05-30 17:13 0次下载
    DA16200 超低功耗 <b class='flag-5'>Wi-Fi</b> 模块开发<b class='flag-5'>套件</b>数据手册

    华为获得全球首个国际Wi-Fi联盟WFA企业级Wi-Fi 7认证!

    Wi-Fi联盟已发布Wi-Fi 7认证标准,华为是第一批送测厂商,获得业界首个企业级Wi-Fi 7 的Wi-Fi联盟官方认证。
    的头像 发表于 04-28 10:17 637次阅读
    华为获得全球首个国际<b class='flag-5'>Wi-Fi</b>联盟WFA企业级<b class='flag-5'>Wi-Fi</b> 7认证!

    验证物联网Wi-Fi HaLow用例的MM6108-EKH08开发套件来啦

    验证物联网Wi-Fi HaLow用例的MM6108-EKH08开发套件来啦 MM6108-EKH08开发套件专为验证物联网Wi-Fi HaLow用例而设计。该
    的头像 发表于 04-11 12:01 1652次阅读
    验证物联网<b class='flag-5'>Wi-Fi</b> HaLow用例的MM6108-EKH08开发<b class='flag-5'>套件</b>来啦

    Wi-Fi 7与Wi-Fi 6的相关知识科普

    科普:Wi-Fi 7 vs. Wi-Fi 6,青出于蓝
    的头像 发表于 03-12 10:59 688次阅读
    <b class='flag-5'>Wi-Fi</b> 7与<b class='flag-5'>Wi-Fi</b> 6的相关知识科普

    Wi-Fi的诞生与发展

    短距离无线通信技术有Wi-Fi、ZigBee、蓝牙以及Z-Wave,今天我们先揭开Wi-Fi的神秘面纱。Chrent短距离无线通信技术——Wi-Fi
    的头像 发表于 03-07 08:26 1129次阅读
    <b class='flag-5'>Wi-Fi</b>的诞生与发展

    XMC4700是否可以通过SDIO接口与Wi-Fi模块通信

    XMC4700 数据表中的外设列表显示\"SD 和多媒体卡接口(SDMMC),用于数据存储记忆卡\" ,但是否可以通过 SDIO 接口与 Wi-Fi 模块通信Wi-Fi 模块可与 SDIO 接口
    发表于 03-06 07:26

    Wi-Fi HaLow和传统Wi-Fi的区别

    Wi-Fi HaLow和传统Wi-Fi的区别  Wi-Fi是一种无线网络技术,可以连接到互联网或局域网,为用户提供无线上网的便利。随着科技的发展和互联网的普及,Wi-Fi也在不断演进和
    的头像 发表于 02-02 15:28 1107次阅读

    康普携手Wi-Fi联盟,RUCKUS Wi-Fi 7系列接入点成Wi-Fi

     康普高级副总裁兼网络、智能蜂窝和安全解决方案总裁Bart Giordano对此表示: “我们非常荣幸能与Wi-Fi Alliance形成长期合作伙伴关系,将我们的RUCKUS Wi-Fi 7 接入点平台作为Wi-Fi CERT
    的头像 发表于 01-23 14:10 700次阅读

    BT Wi-Fi模式是否可以通过ModustoolBox对套件进行编程来实现?

    想配置用于分析 CYW43439 的 CY8CPROTO-062S2-43439 原型开发套件。 浏览文档我无法弄清楚如何在不同的 Wi-Fi 和蓝牙模式(电源模式、连接模式等)下配置套件。 在
    发表于 01-22 06:19

    Wi-Fi 6和Wi-Fi 5之间有哪些区别呢?

    Wi-Fi 6和Wi-Fi 5之间有哪些区别呢? Wi-Fi 6和Wi-Fi 5是无线局域网标准的两个版本,它们之间存在很多区别。Wi-Fi
    的头像 发表于 12-09 16:09 2191次阅读

    紫光展锐Wi-Fi 6成功通过Wi-Fi联盟认证

    80000多项产品,Wi-Fi CERTIFIED有助于确保产品符合高水准的互操性和安全性。 紫光展锐深耕移动通信20多年,在标准及专利、蜂窝/短距通信、基
    的头像 发表于 11-30 13:30 766次阅读

    什么是2.4 GHz Wi-Fi? 如何提升2.4 GHz Wi-Fi的性能?

    GHz Wi-Fi现在还有用吗?  2.4 GHz Wi-Fi是一种无线通信技术,通过使用2.4 GHz频段的无线电波来传输数据。它是目前最常见的Wi-Fi频段之一,并且被广泛用于家
    的头像 发表于 11-27 17:09 2291次阅读