ESP8266--学习笔记(四)TCP通信--TCP-Client

TCP Client模式

  • ESP8266工作在station模式下,需确认ESP8266已经连接AP(路由器)并分配到IP地址,启用client连接
  • ESP8266工作在soft-AP模式下,需确认连接ESP8266的设备已被分配到IP地址,启用client连接

ESP8266 TCP Client模式配置流程

  • 依据协议初始化espconn参数
  • 注册连接成功的回调函数和连接失败重连的回调函数(espconn_regist_connectcb和espconn_cegist_reconcb)
  • 调用espconn_connect建立与TCP Server的连接
  • TCP连接建立成功后,在连接成功的回调函数(espconn_connect_callback)中,注册接收数据的回调函数(espconn_regist_recvcb)、发送数据成功的回调函数(espconn_regist_sentcb)和断开连接的回调函数(espconn_regist_disconncb)。
  • 接收数据的回调函数,或者发送数据成功的回调函数中,执行断开连接操作时,建议适当延时一定时间,确保底层函数执行结束。

———————————————————–

 TCP连接功能WiFi连接在主入口函数中的业务代码


ETSTimer connect_timer;
void ICACHE_FLASH_ATTR Wifi_conned(void *arg){
    static uint8 count=0;
    struct ip_info info; //用于获取IP地址的信息
    uint8 status;
    os_timer_disarm(&connect_timer);
    count++;
    status=wifi_station_get_connect_status();
    if(status==STATION_GOT_IP){
        os_printf("Wifi connect success!");

        const char remote_ip[4]={192,168,1,103};//用于存放本地IP地址,一定要是自己的电脑真实的本地IP地址
        wifi_get_ip_info(STATON_IF,&info);

        my_station_init((struct ip_addr *)remote_ip,&info.ip,1025);//TCP client端的业务主函数入口
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,NULL);
}

user_main.c的全部代码

/*
 * user_main.c
 *
 *  Created on: 2017年3月17日
 *      Author: yuanlifu
 */
#include "ets_sys.h"
#include "driver/uart.h"
#include "user_main.h"
#include "user_interface.h"
#include "client.h"

ETSTimer connect_timer;
void ICACHE_FLASH_ATTR Wifi_conned(void *arg){
    static uint8 count=0;
    struct ip_info info; //用于获取IP地址的信息
    uint8 status;
    os_timer_disarm(&connect_timer);
    count++;
    status=wifi_station_get_connect_status();
    if(status==STATION_GOT_IP){
        os_printf("Wifi connect success!");

        const char remote_ip[4]={192,168,1,103};//用于存放本地IP地址,一定要是自己的电脑真实的本地IP地址
        wifi_get_ip_info(STATON_IF,&info);

        my_station_init((struct ip_addr *)remote_ip,&info.ip,1025);//TCP client端的业务主函数入口
        return;
    }else{
        if(count>=7){
        os_printf("Wifi connect fail!");
        return;
        }
    }
    os_timer_arm(&connect_timer,2000,NULL);
}

void ICACHE_FLASH_ATTR scan_done(void *arg,STATUS status){

     uint8 ssid[33];
      char temp[128];
      struct station_config stationConf;
      if (status == OK)
       {
         struct bss_info *bss_link = (struct bss_info *)arg;
         bss_link = bss_link->next.stqe_next;//ignore first

         while (bss_link != NULL)
         {
           os_memset(ssid, 0, 33);
           if (os_strlen(bss_link->ssid) <= 32)
           {
             os_memcpy(ssid, bss_link->ssid, os_strlen(bss_link->ssid));
           }
           else
           {
             os_memcpy(ssid, bss_link->ssid, 32);
           }
           os_sprintf(temp,"+CWLAP:(%d,\"%s\",%d,\""MACSTR"\",%d)\r\n",
                      bss_link->authmode, ssid, bss_link->rssi,
                      MAC2STR(bss_link->bssid),bss_link->channel);
           os_printf("%s",temp);
           bss_link = bss_link->next.stqe_next;
         }
        os_memcpy(&stationConf.ssid, "MERCURY_2784", 32);
        os_memcpy(&stationConf.password, "123456789", 64);
        wifi_station_set_config_current(&stationConf);
        wifi_station_connect();
        os_timer_setfn(&connect_timer,Wifi_conned,NULL);
        os_timer_arm(&connect_timer,2000,NULL);
       }
       else
       {
     //     os_sprintf(temp,"err, scan status %d\r\n", status);
     //     uart0_sendStr(temp);
        os_printf("%s","Error");
       }
}
void to_scan(void)  { wifi_station_scan(NULL,scan_done); }

void user_init(){
    struct softap_config config;
        uint8 opmode;
        uart_init(115200,115200);
        wifi_set_opmode(0x03);//设置为AP模式
        opmode = wifi_get_opmode_default();
        os_printf("\r\n当前的工作模式:%d\r\n",opmode);

        wifi_softap_get_config(&config);
        os_memcpy(config.ssid,"ESP8266",strlen("ESP8266"));
        os_memcpy(config.password,"123456789",strlen("123456789"));
        config.ssid_len = strlen("ESP8266");
        wifi_softap_set_config(&config);

        system_init_done_cb(to_scan);//扫描WiFi需要系统初始化完成之后
}

void user_rf_pre_init(){

}

client.h

/*
 * client.h
 *
 *  Created on: 2017年3月17日
 *      Author: yuanlifu
 */

#ifndef APP_INCLUDE_CLIENT_H_
#define APP_INCLUDE_CLIENT_H_
#include "user_main.h"
#include "espconn.h"
#include "mem.h"

struct espconn user_tcp_conn;

void my_station_init(struct ip_addr *remote_ip,struct ip_addr *local_ip,int remote_port);//client业务主函数

#endif /* APP_INCLUDE_CLIENT_H_ */

licent.c 的代码编写都是依照那个编程流程来的。

  • 依据协议初始化espconn参数
  • 注册连接成功的回调函数和连接失败重连的回调函数(espconn_regist_connectcb和espconn_cegist_reconcb)
  • 调用espconn_connect建立与TCP Server的连接
  • TCP连接建立成功后,在连接成功的回调函数(espconn_connect_callback)中,注册接收数据的回调函数(espconn_regist_recvcb)、发送数据成功的回调函数(espconn_regist_sentcb)和断开连接的回调函数(espconn_regist_disconncb)。
  • 接收数据的回调函数,或者发送数据成功的回调函数中,执行断开连接操作时,建议适当延时一定时间,确保底层函数执行结束。

ESP8266--学习笔记(四)TCP通信--TCP-Client_第1张图片

#include "../include/client.h"

void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg,
        char *pdata,
        unsigned short len){//接收数据的回调函数
    os_printf("收到数据:%s\r\n");//将接收到的数据打印出来

    os_delay_us(300);//延一下时
    //espconn_disconnect((struct espconn *)arg);//断开连接,是作为客户机完成一次请求然后断开的意思
}

void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg){//发送数据成功的回调函数
    os_printf("发送数据成功!!\r\n");
}

void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg){//断开连接的回调函数
    os_printf("断开连接成功!\r\n");
}

void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg,sint8 err){//重连回调函数
    os_printf("连接错误,错误代码为%d\r\n",err);//打印出连接错误代码
}

void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg){
    struct espconn *pespconn = arg;

    espconn_regist_recvcb(pespconn,user_tcp_recv_cb);//注册接收数据的回调函数
    espconn_regist_sentcb(pespconn,user_tcp_sent_cb);//注册发送数据成功的回调函数
    espconn_regist_disconcb(pespconn,user_tcp_discon_cb);//注册断开连接的回调函数

    espconn_sent(pespconn,"这是ESP8266",strlen("这是ESP8266"));
}

void ICACHE_FLASH_ATTR my_station_init(struct ip_addr *remote_ip,struct ip_addr *local_ip,int remote_port){
    user_tcp_conn.type=ESPCONN_TCP;
    user_tcp_conn.state=ESPCONN_NONE;
    user_tcp_conn.proto.tcp=(esp_tcp *)os_zalloc(sizeof(esp_tcp));

    //espconn参数配置
    os_memcpy(user_tcp_conn.proto.tcp->local_ip,local_ip,4);
    os_memcpy(user_tcp_conn.proto.tcp->remote_ip,remote_ip,4);
    user_tcp_conn.proto.tcp->local_port=espconn_port();
    user_tcp_conn.proto.tcp->remote_port=remote_port;

    //注册回调函数和重连回调函数
    espconn_regist_connectcb(&user_tcp_conn,user_tcp_connect_cb);
    espconn_regist_reconcb(&user_tcp_conn,user_tcp_recon_cb);

    //启用连接
    espconn_connect(&user_tcp_conn);
}

效果:
ESP8266--学习笔记(四)TCP通信--TCP-Client_第2张图片

你可能感兴趣的:(ESP8266,C)