ESP8266 station模式下建立client、server TCP连接


程序实现内容:

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进行连接

 1 void user_set_station_config(){  2 
 3   struct station_config stationconf;  4 
 5   char ssid[32]     = "Hello world";  6   char password[64] = "chenyuping";  7 
 8   stationconf.bssid_set = 0;  9   memset(stationconf.ssid, 0, sizeof(stationconf.ssid)); 10   memset(stationconf.password, 0, sizeof(stationconf.password)); 11 
12   memcpy(stationconf.ssid, ssid, sizeof(ssid)); 13   memcpy(stationconf.password, password, sizeof(password)); 14 
15   wifi_station_set_config(&stationconf); 16 
17   return ; 18 }

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

 1 wifi_set_event_handler_cb(wifi_handle_even_cb);  2 
 3 void wifi_handle_even_cb(System_Event_t *evt){  4   switch(evt->event_id){  5     case EVENT_STAMODE_GOT_IP:  6       flag_sta_conip = TRUE;  7       printf("Have got IP!!\n");  8       break;  9    defaut: printf("Have'n got IP\n"); 10            break; 11  } 12 }

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

1   os_timer_disarm(&ser_timer); 2   os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL); 3   os_timer_arm(&ser_timer, 900, 0); 4 
5   os_timer_disarm(&cli_timer); 6   os_timer_setfn(&cli_timer, espconn_cli_timer_cb, NULL); 7   os_timer_arm(&cli_timer, 500, 0);

网络层:

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

 1 void espconn_cli_timer_cb(void *timer_arg)  2 {  3   struct ip_info ipconfig;  4 
 5   os_timer_disarm(&cli_timer);  6   wifi_get_ip_info(STATION_IF, &ipconfig);  7 
 8  if (flag_sta_conip){  9     printf("connect successful !!!\n"); 10  espconn_tcp_client_connect(); 11  } 12    else { 13     printf("connect fail !!!\n"); 14     os_timer_setfn(&cli_timer, espconn_cli_timer_cb, NULL); 15     os_timer_arm(&cli_timer, 500, 0); 16  } 17 }

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

 1 void espconn_tcp_client_connect(){  2 
 3   user_tcp_conn.proto.tcp = &user_tcp;  4   user_tcp_conn.type      = ESPCONN_TCP;  5   user_tcp_conn.state     = ESPCONN_NONE;  6 
 7   const char esp_tcp_server_ip[4] = {192, 168, 31, 155}; // remote IP of TCP server
 8 
 9   memcpy(user_tcp_conn.proto.tcp->remote_ip, esp_tcp_server_ip, 4); 10   user_tcp_conn.proto.tcp->remote_port = 9003; 11 
12   espconn_regist_connectcb(&user_tcp_conn, espconn_connect_cb); 13   espconn_regist_reconcb(&user_tcp_conn, espconn_reconnect_cb); 14 
15   espconn_regist_sentcb(&user_tcp_conn, espconn_sent_cb); 16   espconn_regist_recvcb(&user_tcp_conn, espconn_recv_data_cb); 17 
18   espconn_connect(&user_tcp_conn); 19 
20   }

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

 1 void espconn_ser_timer_cb(void *timer_arg)  2 {  3   user_tcp_conn.proto.tcp = &user_tcp;  4   user_tcp_conn.type      = ESPCONN_TCP;  5   user_tcp_conn.state     = ESPCONN_NONE;  6 
 7   os_timer_disarm(&ser_timer);  8 
 9   user_tcp_conn.proto.tcp->local_port = espconn_port(); 10   printf("The local port is %d\n",user_tcp_conn.proto.tcp->local_port); 11 
12   sint8 ret = espconn_accept(&user_tcp_conn); 13   printf("%d\n", ret); 14   if(!ret){ 15     printf("Begin to listen!!!\n"); 16  } 17   else{ 18     printf("Fail to listen!!!\n"); 19     os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL); 20     os_timer_arm(&ser_timer, 900, 0); 21  } 22 }

接收数据的回调函数:

 1 espconn_regist_recvcb(&user_tcp_conn, espconn_recv_data_cb);  2 
 3 void espconn_recv_data_cb(void *arg, char *pdata, unsigned short len)  4 {  5   uint8 *pDat;  6   const char str[] = "Light ON";  7 
 8   pDat = (uint8 *)malloc(len + 1);  9  memcpy(pDat, pdata, len); 10   *(pDat+len) = 0; 11  // pDat[len] = 0;
12 
13   printf("The receiver data is %s",pDat); 14   printf("\n\n"); 15 
16   if(memcmp(pDat, str, sizeof(str)) == 0) { 17     printf("Now Light is Run!\n"); 18     espconn_send(&user_tcp_conn, "Now Light is Run!\n", 18); 19  } 20 
21   free(pDat); 22 }

发送数据的回调函数:

 1 espconn_regist_sentcb(&user_tcp_conn, espconn_sent_cb);  2 
 3 void espconn_ser_timer_cb(void *timer_arg)  4 {  5   user_tcp_conn.proto.tcp = &user_tcp;  6   user_tcp_conn.type      = ESPCONN_TCP;  7   user_tcp_conn.state     = ESPCONN_NONE;  8 
 9   os_timer_disarm(&ser_timer); 10   user_tcp_conn.proto.tcp->local_port = espconn_port(); 11   printf("The local port is %d\n",user_tcp_conn.proto.tcp->local_port); 12 
13   sint8 ret = espconn_accept(&user_tcp_conn); 14   printf("%d\n", ret); 15   if(!ret){ 16     printf("Begin to listen!!!\n"); 17  } 18   else{ 19     printf("Fail to listen!!!\n"); 20     os_timer_setfn(&ser_timer, espconn_ser_timer_cb, NULL); 21     os_timer_arm(&ser_timer, 900, 0); 22  } 23 }

实现效果:


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM