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 }
实现效果: