https://www.cnblogs.com/yangfengwu/p/11432795.html

注:这节实现的功能是WIFI模块作为TCP 客户端,连接咱的TCP服务器,然后实现透传

本来想着做成断线重连,但是无论如何测试,使用官方给的API默认大约2个小时以后就会主动断开连接......

其实和咱 https://www.cnblogs.com/yangfengwu/p/11112014.html  (TCP 服务器差不多)

先看下程序测试 (连接路由器测试,让电脑和WIFI连接同一个路由器)

打开网络调试助手

我的TCP服务器IP是 192.168.1.93   端口号是 60000     根据自己的修改

下载进去

配网就不说了,如果不是从前面看过来的,去看前面文章哈

正常运行后

测试通信

不用这个调试助手了,关掉这个调试助手,咱用另一个网络调试助手,带自动发送的

关掉调试助手以后,会发现客户端一直在尝试重新连接

启动以后客户端会自动连接上

好,现在看一下程序

连接放在了

#include "esp_common.h"
#include "gpio.h"
#include "uart.h"
#include "esp_timer.h"
#include "hw_timer.h"
#include "pwm.h"
#include "data_dispose.h"
#include "espconn.h"
#include "esp_wifi.h"
#include "lwip/api.h" #include "crc.h"
#include "smart_config.h" LOCAL os_timer_t public_timer;//定时器
u32 public_timer_cnt=;//累加
u32 public_timer_state=;//状态
u32 public_timer_out=;//超时
u32 public_timer_cnt1=;//累加 extern u8 Usart1ReadBuff[Usart1ReadLen];//接收数据的数组
extern u32 Usart1ReadCnt;//串口1接收到的数据个数
extern u32 Usart1ReadCntCopy;//串口1接收到的数据个数拷贝
extern u8 Usart1ReadFlage;//串口1接收到一条完整数据 #define SSID "Learn8266" //无线名称
#define PWD "11223344" //密码
struct softap_config soft_ap_Config;//AP模式配置 //连接的路由器信息
#define APssid "qqqqq"
#define APpassword "11223344"
struct station_config stationConf; //TCP客户端
struct espconn TcpClient;
esp_tcp esptcp; ResolveData ResolveDataTest;//解析数据IEEE754
//uint32 pin_info_list[1][3]={PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5,5};//配置GPIO5作为PWM输出
//int duty[1]={0};//高电平时间是0us /******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32 user_rf_cal_sector_set(void)
{
flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = ; switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = - ;
break; case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = - ;
break; case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = - ;
break; case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = - ;
break; default:
rf_cal_sec = ;
break;
} return rf_cal_sec;
} //串口调用此函数就说明接收到了一条完整的数据,就可以去处理了
void UartReadCallback()//定义一个函数
{
espconn_send(&TcpClient,Usart1ReadBuff,Usart1ReadCntCopy);//串口接收的数据发给网络
} //网络接收到数据
void TcpClientRecv(void *arg, char *pdata, unsigned short len)
{
while(len--)
{
uart0_write_char(*(pdata++));//发送到串口
}
} //断开了连接
void TcpClientDisCon(void *arg)
{
dbg_printf("\nTcpClientDisCon\n");
espconn_connect(&TcpClient);//重新连接服务器
} int keep_alive_sec = ;//设置心跳包
//连接上服务器
void TcpConnected(void *arg)
{
dbg_printf("\nTcpConnected\n"); //设置启用心跳包
dbg_printf("\nespconn_set_opt=%d\n",espconn_set_opt(&TcpClient,ESPCONN_KEEPALIVE));//成功:0 失败:其它
//客户端断开直接释放内存
dbg_printf("\nespconn_set_opt=%d\n",espconn_set_opt(&TcpClient,ESPCONN_REUSEADDR));//成功:0 失败:其它 //每隔ESPCONN_KEEPIDLE 开始启动心跳包探测,
//如果探测失败,则每每隔 ESPCONN_KEEPINTVL 发送一次探测,
//探测 ESPCONN_KEEPCNT 次以后还是无相应,则进入 espconn_reconnect_callback 回调函数 (espconn_regist_reconcb(&TcpClient, TcpConnectErr);//注册连接出错函数) keep_alive_sec = ;//每隔30S开始一次探测
espconn_set_keepalive(&TcpClient,ESPCONN_KEEPIDLE,&keep_alive_sec); keep_alive_sec = ;//开始探测后,心跳包每隔1S发送一次
espconn_set_keepalive(&TcpClient,ESPCONN_KEEPINTVL,&keep_alive_sec); keep_alive_sec = ;//心跳包总共发送3次
espconn_set_keepalive(&TcpClient,ESPCONN_KEEPCNT,&keep_alive_sec); espconn_regist_recvcb(&TcpClient, TcpClientRecv);//设置接收回调
espconn_regist_disconcb(&TcpClient, TcpClientDisCon);//设置断开连接回调
} //连接出错
void TcpConnectErr(void *arg, sint8 err)
{
dbg_printf("\nTcpConnectErr=%d\n",err);
espconn_connect(&TcpClient);//链接
} //监听WiFi状态改变
void wifi_event_monitor_handle_event_cb(System_Event_t *evt)
{
switch (evt->event_id)
{
case EVENT_STAMODE_CONNECTED://连接上路由器
dbg_printf("\n\tSTAMODE_CONNECTED\n"); dbg_printf("\tConnected to SSID %s, Channel %d\n",
evt->event_info.connected.ssid,
evt->event_info.connected.channel);
break; case EVENT_STAMODE_DISCONNECTED://和路由器断开
dbg_printf("\n\tSTAMODE_DISCONNECTED\n"); dbg_printf("\tDisconnect from SSID %s, reason %d\n",
evt->event_info.disconnected.ssid,
evt->event_info.disconnected.reason);
break; case EVENT_STAMODE_AUTHMODE_CHANGE://这个是 啥..
dbg_printf("\n\tSTAMODE_AUTHMODE_CHANGE\n"); dbg_printf("\tAuthmode: %u -> %u\n",
evt->event_info.auth_change.old_mode,
evt->event_info.auth_change.new_mode);
break; case EVENT_STAMODE_GOT_IP://连接上路由器,并获取了IP
dbg_printf("\n\tGOT_IP\n"); dbg_printf("\tIP:" IPSTR ",Mask:" IPSTR ",GW:" IPSTR "\n",
IP2STR(&evt->event_info.got_ip.ip),
IP2STR(&evt->event_info.got_ip.mask),
IP2STR(&evt->event_info.got_ip.gw)); if(public_timer_state == )//正常运行下连接的路由器
{
espconn_connect(&TcpClient);//连接TCP服务器
} break; case EVENT_STAMODE_DHCP_TIMEOUT://连接上路由器,但是路由器给WIFI模块分配IP等信息超时了
dbg_printf("\n\tSTAMODE_DHCP_TIMEOUT\n");
break; case EVENT_SOFTAPMODE_STACONNECTED://AP模式下,有设备连接WIFI模块的无线
dbg_printf("\n\tSOFTAPMODE_STACONNECTED\n"); dbg_printf("\tStation: " MACSTR "join, AID = %d\n",
MAC2STR(evt->event_info.sta_connected.mac),
evt->event_info.sta_connected.aid);
break; case EVENT_SOFTAPMODE_STADISCONNECTED://AP模式下,有设备断开和WIFI模块的无线连接
dbg_printf("\n\tSOFTAPMODE_STADISCONNECTED\n"); dbg_printf("\tstation: " MACSTR "leave, AID = %d\n",
MAC2STR(evt->event_info.sta_disconnected.mac),
evt->event_info.sta_disconnected.aid);
break; case EVENT_SOFTAPMODE_PROBEREQRECVED://这是啥??,,,信号强度改变了
dbg_printf("\n\tSOFTAPMODE_PROBEREQRECVED\n"); dbg_printf("Station PROBEREQ: " MACSTR " RSSI = %d\n",
MAC2STR(evt->event_info.ap_probereqrecved.mac),
evt->event_info.ap_probereqrecved.rssi);
break; default://其它错误
dbg_printf("\n\tswitch/case default\n");
break;
}
} //所有需要定时操作的函数在此函数中执行
LOCAL void ICACHE_FLASH_ATTR
public_timer_callback(void)
{
if(GPIO_INPUT_GET() == )//按键按下
{
public_timer_cnt++;
if(public_timer_cnt>= && public_timer_state==)//3S
{
dbg_printf("\nstartsmart\n");
public_timer_state=;
wifi_station_disconnect();
wifi_set_opmode(STATION_MODE);
smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS);//SmartConfig + AirKiss
xTaskCreate(smartconfig_task, "smartconfig_task", , NULL, , NULL);
}
}
else
{
if(public_timer_state!= && public_timer_cnt> && public_timer_cnt<)//短按复位
{
dbg_printf("\nsystem_restart\n");
system_restart();//复位
}
public_timer_cnt=;
} switch(public_timer_state)
{
case :break;
case :
public_timer_out++;
public_timer_cnt1++;
if(public_timer_out>=)//60S
{
dbg_printf("\nsmartconfig_timeout\n");
system_restart();//复位
}
if(public_timer_cnt1>)//LED快闪
{
public_timer_cnt1=;
GPIO_OUTPUT_SET(, -GPIO_INPUT_GET());//LED快闪
}
break;
default:break;
}
} /******************************************************************************
* FunctionName : user_init
* Description : entry of user application, init user function here
* Parameters : none
* Returns : none
*******************************************************************************/
void user_init(void)
{
GPIO_OUTPUT_SET(, );
GPIO_OUTPUT_SET(, );//让两个灯初始的状态一样,GOIO2是反接的,0的时候是亮
GPIO_OUTPUT_SET(, );
uart_init_new();
printf("SDK version:%s\n", system_get_sdk_version()); wifi_set_opmode(STATIONAP_MODE);//配置WiFi的模式STATION + AP AP--连接WIFI自身的无线实现通信 STATION--wifi连接路由器,手机或者电脑也连接路由器,实现通信
soft_ap_Config.ssid_len = strlen(SSID);//热点名称长度,与你实际的名称长度一致就好
memcpy(soft_ap_Config.ssid,SSID,soft_ap_Config.ssid_len);//实际热点名称设置,可以根据你的需要来
memcpy(soft_ap_Config.password,PWD,strlen(PWD));//热点密码设置
soft_ap_Config.authmode = AUTH_WPA2_PSK;//加密模式
soft_ap_Config.channel = ;//信道,共支持1~13个信道
soft_ap_Config.max_connection = ;//最大连接数量,最大支持四个,默认四个 wifi_softap_set_config_current(&soft_ap_Config);//设置 Wi-Fi SoftAP 接口配置,不保存到 Flash
// wifi_softap_set_config(&soft_ap_Config);//设置 Wi-Fi SoftAP 接口配置,保存到 Flash
UartCallbackRegister(UartReadCallback);//把 UartReadCallback 函数地址传过去,在串口里面调用 os_timer_disarm(&public_timer);
os_timer_setfn(&public_timer, (os_timer_func_t *)public_timer_callback, NULL);
os_timer_arm(&public_timer, , );//10ms //设置连接的路由器,如果想直接测试不想配网,请去掉屏蔽
// stationConf.bssid_set = 0;
// memcpy(stationConf.ssid,APssid,strlen(APssid));//路由器名称
// memcpy(stationConf.password,APpassword,strlen(APpassword));//路由器密码
// wifi_station_disconnect();
// wifi_station_set_config(&stationConf); wifi_set_event_handler_cb(wifi_event_monitor_handle_event_cb);//监听WiFi状态改变 //初始化TCP
espconn_init();
TcpClient.type = ESPCONN_TCP;
TcpClient.state = ESPCONN_NONE;
TcpClient.proto.tcp = &esptcp; //服务器IP 地址
TcpClient.proto.tcp->remote_ip[]=;
TcpClient.proto.tcp->remote_ip[]=;
TcpClient.proto.tcp->remote_ip[]=;
TcpClient.proto.tcp->remote_ip[]=; TcpClient.proto.tcp->remote_port = ;//连接端口号 espconn_regist_connectcb(&TcpClient, TcpConnected);//注册连接函数
espconn_regist_reconcb(&TcpClient, TcpConnectErr);//注册连接出错函数 //espconn_regist_time(&TcpClient,0,0);//测试2个小时自动断开问题
}

大家自己去测试。

https://www.cnblogs.com/yangfengwu/p/11458917.html

28-ESP8266 SDK开发基础入门篇--编写wifi模块TCP 客户端程序(官方API版,非RTOS版)的更多相关文章

  1. 26-ESP8266 SDK开发基础入门篇--编写WIFI模块 SmartConfig/Airkiss 一键配网

    https://www.cnblogs.com/yangfengwu/p/11427504.html SmartConfig/Airkiss 配网需要APP/微信公众号,这节大家先使用我做好的APP/ ...

  2. 29-ESP8266 SDK开发基础入门篇--编写TCP 客户端程序(Lwip RAW模式,非RTOS版,精简入门)

    https://www.cnblogs.com/yangfengwu/p/11456667.html 由于上一节的源码长时间以后会自动断开,所以再做这一版非RTOS版的,咱直接用lua源码里面别人写的 ...

  3. 25-ESP8266 SDK开发基础入门篇--控制WIFI连接路由器

    https://www.cnblogs.com/yangfengwu/p/11324411.html 说个事情,现在SDK的版本已经出到3.0了,但是我还是使用2.0 如果只是为了学习研究   选择3 ...

  4. 8-ESP8266 SDK开发基础入门篇--编写串口上位机软件

    https://www.cnblogs.com/yangfengwu/p/11087558.html 咱用这个编写 ,版本都无所谓哈,只要自己有就可以,不同版本怎么打开 https://www.cnb ...

  5. 27-ESP8266 SDK开发基础入门篇--编写Android SmartConfig一键配网程序

    style="font-size: 18pt;">https://www.cnblogs.com/yangfengwu/p/11429007.html https://wik ...

  6. 22-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 连接和断开

    https://www.cnblogs.com/yangfengwu/p/11192618.html 有些很细致的东西参考这篇   https://www.cnblogs.com/yangfengwu ...

  7. 9-ESP8266 SDK开发基础入门篇--编写串口上位机软件

    https://www.cnblogs.com/yangfengwu/p/11087613.html 页面修改成这样子             现在看串口发送数据 点击点亮 发送0xaa 0x55 0 ...

  8. 23-ESP8266 SDK开发基础入门篇--编写Android TCP客户端 , 加入消息处理

    https://www.cnblogs.com/yangfengwu/p/11203546.html 先做接收消息 然后接着 public class MainActivity extends App ...

  9. 19-ESP8266 SDK开发基础入门篇--C# TCP客户端编写 , 连接和断开

    https://www.cnblogs.com/yangfengwu/p/11130428.html 渐渐的看过去,,,好多节了... 这节做一个C# TCP客户端 新建项目啥子的就不详细截图写了,自 ...

随机推荐

  1. js拼接url以及为html某标签属性赋值

    记录 js拼接url 比如有些时候我们需要为某按钮实现跳转,可以利用下面的方式做到: function ReturnIndex() { var rex = RegExp("tools&quo ...

  2. 解决C#调用COM组件异常来自 HRESULT:0x80010105 (RPC_E_SERVERFAULT)的错误

    最近C#调用COM时,遇到了异常来自 HRESULT:0x80010105 (RPC_E_SERVERFAULT)的错误 后面找了一下,发现是在线程里调用COM组件引起的. C++调用COM时,会调用 ...

  3. System.Web.NullPointerException

    在.Net异步webApi中我们需要记录日志信息,需要获取客户端的ip地址,我们需要使用:HttpContext.Current.Request.ServerVariables["REMOT ...

  4. SQLite介绍和使用

    SQLite特点: (1)轻量级,跨平台的关系型数据库,所以支持视图,事务,触发器等. (2)零配置-无需安装和管理配置,存储在单一磁盘文件中的完整的数据库 (3)数据库文件可共享,支持多种开发语言. ...

  5. jQuery.Form.js使用方法

    一.jQuery.Form.js 插件的作用是实现Ajax提交表单. 方法: 1.formSerilize() 用于序列化表单中的数据,并将其自动整理成适合AJAX异步请求的URL地址格式. 2.cl ...

  6. onActivityResult方法的使用

    转发自:https://blog.csdn.net/hacker_crazy/article/details/78345450 在进行界面间的跳转和传递数据的时候,我们有的时候要获得跳转之后界面传递回 ...

  7. 【开发笔记】- 永远不要在MySQL中使用UTF-8

    原文地址:https://mp.weixin.qq.com/s/I3Tkvn8vSyC5lEpD9HzwiA 最近我遇到了一个bug,我试着通过Rails在以“utf8”编码的MariaDB中保存一个 ...

  8. Vue.js详解

    vuejs介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能 ...

  9. Openlayers学习开始前序

    Openlayers将抽象事物具体化为类,其核心类是Map.Layers.Source.View,几乎所有的动作都是围绕这几个核心类展开.Map的实例就是内嵌于网页的交互式地图,因此,最关键的是Map ...

  10. Abp vNext抽茧剥丝01 使用using临时更改当前租户

    在Abp vNext中,如果开启了多租户功能,在业务代码中默认使用当前租户的数据,如果我们需要更改当前租户,可以使用下面的方法 /* 此时当前租户 */ using (CurrentTenant.Ch ...