程序实现内容:

1.在station模式下,ESP8266作为client、server进行TCP连接
2.实现数据的发送、接收(同时回传)
实现思路:
TCP网络通信分层为:应用层、网络层、数据链路层、物理层;
1. 设置ESP8266为station模式,在数据链路层连接AP,获取IP地址;
2. 在网络层进行TCP连接:作为client连接远程server,作为server监听远程client信息;

数据链路层:

1. 设置ESP8266为station模式:wifi_set_opmode(STATION_MODE);

2. 配置连接到AP的相关参数,在该步骤中,需要知道AP的名称( ssid )、密码( password ): 官方所给的SDK中,该配置执行后,wifi模块自动与AP进行连接

 void user_set_station_config(){

   struct station_config stationconf;

   char ssid[]     = "Hello world";
char password[] = "chenyuping"; stationconf.bssid_set = ;
memset(stationconf.ssid, , sizeof(stationconf.ssid));
memset(stationconf.password, , sizeof(stationconf.password)); memcpy(stationconf.ssid, ssid, sizeof(ssid));
memcpy(stationconf.password, password, sizeof(password)); wifi_station_set_config(&stationconf); return ;
}

为确保ESP8266已同AP建立稳定的连接并且已获取到IP地址,可注册该事件的回调函数进行判定:
1.注册回调函数

 wifi_set_event_handler_cb(wifi_handle_even_cb);

 void wifi_handle_even_cb(System_Event_t *evt){
switch(evt->event_id){
case EVENT_STAMODE_GOT_IP:
flag_sta_conip = TRUE;
printf("Have got IP!!\n");
break;
defaut: printf("Have'n got IP\n");
break;
}
}

2.注册定时器,对回调函数中的flag_sta_conip进行判定以确定是否已获得IP地址

   os_timer_disarm(&ser_timer);
os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL);
os_timer_arm(&ser_timer, , ); os_timer_disarm(&cli_timer);
os_timer_setfn(&cli_timer, espconn_cli_timer_cb, NULL);
os_timer_arm(&cli_timer, , );

网络层:

1. 检测ESP8266是否已同AP建立稳定连接,若是,则开始建立TCP client连接:

 void espconn_cli_timer_cb(void *timer_arg)
{
struct ip_info ipconfig; os_timer_disarm(&cli_timer);
wifi_get_ip_info(STATION_IF, &ipconfig); if (flag_sta_conip){
printf("connect successful !!!\n");
espconn_tcp_client_connect();
}
else {
printf("connect fail !!!\n");
os_timer_setfn(&cli_timer, espconn_cli_timer_cb, NULL);
os_timer_arm(&cli_timer, , );
}
}

建立TCP client连接(在该设置中,需要知道远程server的IP地址及端口号),同时注册连接、收发数据的回调函数:

 void espconn_tcp_client_connect(){

   user_tcp_conn.proto.tcp = &user_tcp;
user_tcp_conn.type = ESPCONN_TCP;
user_tcp_conn.state = ESPCONN_NONE; const char esp_tcp_server_ip[] = {, , , }; // remote IP of TCP server memcpy(user_tcp_conn.proto.tcp->remote_ip, esp_tcp_server_ip, );
user_tcp_conn.proto.tcp->remote_port = ; espconn_regist_connectcb(&user_tcp_conn, espconn_connect_cb);
espconn_regist_reconcb(&user_tcp_conn, espconn_reconnect_cb); espconn_regist_sentcb(&user_tcp_conn, espconn_sent_cb);
espconn_regist_recvcb(&user_tcp_conn, espconn_recv_data_cb); espconn_connect(&user_tcp_conn); }

2. ESP8266开启server服务(在该步骤中,通过对espconn_accept()函数返回值的判定,TRUE则关闭设置server开启的定时器,FALSE则继续保持开通,直到开启成功)

 void espconn_ser_timer_cb(void *timer_arg)
{
user_tcp_conn.proto.tcp = &user_tcp;
user_tcp_conn.type = ESPCONN_TCP;
user_tcp_conn.state = ESPCONN_NONE; os_timer_disarm(&ser_timer); user_tcp_conn.proto.tcp->local_port = espconn_port();
printf("The local port is %d\n",user_tcp_conn.proto.tcp->local_port); sint8 ret = espconn_accept(&user_tcp_conn);
printf("%d\n", ret);
if(!ret){
printf("Begin to listen!!!\n");
}
else{
printf("Fail to listen!!!\n");
os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL);
os_timer_arm(&ser_timer, , );
}
}

接收数据的回调函数:

 espconn_regist_recvcb(&user_tcp_conn, espconn_recv_data_cb);

 void espconn_recv_data_cb(void *arg, char *pdata, unsigned short len)
{
uint8 *pDat;
const char str[] = "Light ON"; pDat = (uint8 *)malloc(len + );
memcpy(pDat, pdata, len);
*(pDat+len) = ;
// pDat[len] = 0; printf("The receiver data is %s",pDat);
printf("\n\n"); if(memcmp(pDat, str, sizeof(str)) == ) {
printf("Now Light is Run!\n");
espconn_send(&user_tcp_conn, "Now Light is Run!\n", );
} free(pDat);
}

发送数据的回调函数:

 espconn_regist_sentcb(&user_tcp_conn, espconn_sent_cb);

 void espconn_ser_timer_cb(void *timer_arg)
{
user_tcp_conn.proto.tcp = &user_tcp;
user_tcp_conn.type = ESPCONN_TCP;
user_tcp_conn.state = ESPCONN_NONE; os_timer_disarm(&ser_timer);
user_tcp_conn.proto.tcp->local_port = espconn_port();
printf("The local port is %d\n",user_tcp_conn.proto.tcp->local_port); sint8 ret = espconn_accept(&user_tcp_conn);
printf("%d\n", ret);
if(!ret){
printf("Begin to listen!!!\n");
}
else{
printf("Fail to listen!!!\n");
os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL);
os_timer_arm(&ser_timer, , );
}
}

实现效果:

ESP8266 station模式下建立client、server TCP连接的更多相关文章

  1. .NET默认一个客户端对同一个服务器地址同时只能建立2个TCP连接

    做一个客户端的测试小程序测试web service的并发处理.开始用async task做,不管创建多少个task,用netstat看同时只有两个tcp连接.以为是async task的问题,改用Ba ...

  2. Windows下建立ArcGIS Server集群

    原创文章,转载须标明出处自: http://www.cnblogs.com/gisspace/p/8269525.html -------------------------------------- ...

  3. NAT模式下VMware中CentOS7无法连接外网的解决方法

    故障现象 ----------------------------------------------------------------------------------------------- ...

  4. TCP连接的状态与关闭方式及其对Server与Client的影响

    TCP连接的状态与关闭方式及其对Server与Client的影响 1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用. ...

  5. TCP连接的状态与关闭方式,及其对Server与Client的影响

    1. TCP连接的状态 首先介绍一下TCP连接建立与关闭过程中的状态.TCP连接过程是状态的转换,促使状态发生转换的因素包括用户调用.特定数据包以及超时等,具体状态如下所示: CLOSED:初始状态, ...

  6. ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库

        在网络篇①中,博主主要讲解了Arduino上开发ESP8266的插件库 Arduino Core For ESP8266.但是,并没有讲到关于这个模块的工作模式,所以本篇讲着重讲解ESP826 ...

  7. 嵌入式Linux下BOA网页server的移植

    **************************************************************************************************** ...

  8. 简述TCP连接的建立与释放(三次握手、四次挥手)

    在介绍TCP连接的建立与释放之前,先回顾一下相关知识. TCP是面向连接的运输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,H ...

  9. TCP连接的建立与释放(三次握手与四次挥手)

    TCP连接的建立与释放(三次握手与四次挥手) TCP是面向连接的运输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,HTTP协议 ...

随机推荐

  1. spring boot +druid数据库连接池配置

    1.启动应用入口修改 增加servlet注解 import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFacto ...

  2. GridView 子项长度和宽度一样

    下面是gridview 控件,每行放置四个,因此用宽度除4. 下面展现出来的的界面就显的比较美观. public class HotSearchAdapter extends BaseAdapter ...

  3. 阅读基于sketch的软件定义网络测量数据平面硬件模型

    概要 硬件实现 基于sketch 功能:采集包数.流长数据,恢复五元组 重点:高速条件下性能较好,节省硬件资源 摘要: 提出一种基于sketch 数据结构的软件定义测量数据平面硬件模型,并在以现场可编 ...

  4. Decorator(装饰)模式

    1. 概述 若你从事过面向对象开发,实现给一个类或对象增加行为,使用继承机制,这是所有面向对象语言的一个基本特性.如果已经存在的一个类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继 ...

  5. Java并发编程(三)什么是线程池

    什么是线程池 学习编程的小伙伴们会经常听到“线程池”.“连接池”这类的词语,可是到底“池”是什么意思呢?我讲个故事大家就理解了:在很久很久以前有一家银行,一年之中只有一个客户来办理业务,随着时间的推移 ...

  6. windows10 通过命令行来查看wifi密码

    c:\Windows\System32>netsh netsh>wlan show profile 接口 WLAN 上的配置文件: 组策略配置文件(只读) ---------------- ...

  7. transfrom、transition、animation区别

    transfrom transform是静态属性,非动画属性,和margin-left.margin-top类似. translate:平移,类似position:relative;translate ...

  8. php以数组做为配置文件的读取和写入操作

    最近想用php开发个简单的文章管理系统,主要是做一批垃圾采集站,目前网上的cms都太多功能了,导致修改个模板要很多文件,花费很多功夫.开始用thinkphp框架做,感觉还是麻烦,后来改用ci,做好了后 ...

  9. java 加载并读取Properties 文件

    1 .系统自带的application.properties  (以下代码仅供参考,不能粘贴复制) 假设application.properties文件有下面两个值: come.test.name = ...

  10. Delphi无边框Form拖动

    用Delphi做登陆窗口,如果使用无边框Form,想要拖动窗口,可以在某个控件的OnMouseDown事件中写下以下代码 ReleaseCapture; Perform(WM_SYSCOMMAND, ...