打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ESP8266

TCP Server模式

  • ESP8266 工作在station模式下,需确认ESP8266已经分配到IP地址,在启用server侦听
  • ESP8266 工作在Soft-AP 模式下,可以直接启动server侦听

TCP Server模式配置流程:

  • 根据工作协议初始化espconn参数
  • 注册连接成功的回调函数和连接失败重新连接的回调函数(espconn_regist_connectcb和espconn_regist_reconcb)
  • 调用espconn_accept侦听TCP连接
  • TCP连接成功后,在连接成功的回调函数(espconn_connect_callback)中,注册接收数据的回调函数,发送数据成功的回调函数和断开连接的回调函数(espconn_regist_recvcb,espconn_regist_sentcb和espconn_regist_disconcb)

一样的借用WiFi扫描连接的基础代码,并在WiFi连接的功能函数里面添加TCP连接功能,WiFi连接在主入口函数中的业务代码

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);//Client端初始化主函数        my_server_init(&info.ip,1213);//Server端初始化主函数        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脭脗14脠脮 *      Author: yuanlifu */#include "ets_sys.h"#include "driver/uart.h"#include "user_main.h"#include "user_interface.h"#include "client.h"#include "server.h"ETSTimer connect_timer;void ICACHE_FLASH_ATTR Wifi_conned(void *arg){    static uint8 count=0;    uint8 opmode;    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);        opmode = wifi_get_opmode_default();        os_printf("\r\n当前的工作模式:%d\r\n",opmode);        //my_station_init((struct ip_addr *)remote_ip,&info.ip,1025);//Client端初始化主函数        my_server_init(&info.ip,1213);//Server端初始化主函数        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(){}

接下来就是编写TCP server的套路了

  • 根据工作协议初始化espconn参数
  • 注册连接成功的回调函数和连接失败重新连接的回调函数(espconn_regist_connectcb和espconn_regist_reconcb)
  • 调用espconn_accept侦听TCP连接
  • TCP连接成功后,在连接成功的回调函数(espconn_connect_callback)中,注册接收数据的回调函数,发送数据成功的回调函数和断开连接的回调函数(espconn_regist_recvcb,espconn_regist_sentcb和espconn_regist_disconcb)

server.h

/***server.h**/#ifndef APP_INCLUDE_SERVER_H#define APP_INCLUDE_SERVER_H#include "user_main.h"#include "espconn.h"#include "mem.h"void my_server_init(struct ip_addr *local_ip,int port);#endif/*APP_INCLUDE_SERVER_H*/

server.c

* server.c * *  Created on: 2017年3月17日 *      Author: yulifu */#include "server.h"void ICACHE_FLASH_ATTR server_recv(void *arg,            char *pdata,            unsigned short len){//接收数据的回调函数        os_printf("收到PC发来的数据:%s\r\n",pdata);//将客户端发过来的数据打印出来        espconn_sent((struct espconn *)arg,"发送已经收到\r\n",strlen("发送已经收到"));//往客户机发送数据}void ICACHE_FLASH_ATTR server_sent(void *arg){//发送数据成功的回调函数    os_printf("发送数据成功!!\r\n");}void ICACHE_FLASH_ATTR server_discon(void *arg){//断开连接的回调函数    os_printf("连接已经断开\r\n");}void ICACHE_FLASH_ATTR server_listen(void *arg){//服务器监听函数    struct espconn *pespconn=arg;    espconn_regist_recvcb(pespconn,server_recv);//注册一个接收数据的回调函数    espconn_regist_sentcb(pespconn,server_sent);//注册一个发送数据成功的回调函数    espconn_regist_disconcb(pespconn,server_discon);//注册一个断开连接的回调函数}void ICACHE_FLASH_ATTR server_recon(void *arg,sint8 err){//重新连接回调函数    os_printf("连接错误,错误代码为:%s\r\n",err);//输出重新连接的错误代码}void ICACHE_FLASH_ATTR my_server_init(struct ip_addr *local_ip,int port){    LOCAL struct espconn esp_conn;    esp_conn.type=ESPCONN_TCP;    esp_conn.state=ESPCONN_NONE;    esp_conn.proto.tcp=(esp_tcp *)os_malloc(sizeof(esp_tcp));    os_memcpy(esp_conn.proto.tcp->local_ip,local_ip,4);    esp_conn.proto.tcp->local_port=port;    //注册连接成功的回调函数和连接失败重新连接的回调函数    espconn_regist_connectcb(&esp_conn,server_listen);//注册一个连接成功回调函数    espconn_regist_reconcb(&esp_conn,server_recon);//注册一个连接失败重新连接回调函数    espconn_accept(&esp_conn);}

———————————————————————————

效果:
PC端:

手机端APP效果:

找到了一份ESP8266关于TCP通信的源码感觉还不错,怕忘记了就把它放在这里:
tcp.c

/* * tcp.c * *  Created on: 2017年3月23日 *      Author: yuanlifu */#include "ets_sys.h"#include "osapi.h"#include "user_interface.h"#include "mem.h"#include "espconn.h"#include "driver/uart.h"#include "tcp.h"typedef enum{  teClient,  teServer}teType;typedef struct{    BOOL linkEn;  BOOL teToff;    uint8_t linkId;    teType teType;    uint8_t repeaTime;    uint8_t changType;    uint8 remoteIp[4];    int32_t remotePort;    struct espconn *pCon;}linkConType;typedef struct{  BOOL linkEn;  BOOL teToff;  uint8_t linkId;  teType teType;  uint8_t repeaTime;  struct espconn *pCon;} espConnectionType;linkConType pLink;espConnectionType user_contype;static struct espconn *pTcpServer;//os_event_t    procTaskQueue[procTaskQueueLen];bool Connect_break;bool Send_Flag;/* * 函数名:void Wifi_AP_Init() * 功能wifi_ap初始化 */void WIFIAPInit(){    struct softap_config apConfig;    /***************************模式设置************************************/         if(wifi_set_opmode(SOFTAP_MODE)){          //  设置为AP模式         }else{         }    /***************************名字设通道置************************************/          os_bzero(&apConfig, sizeof(struct softap_config));          wifi_softap_get_config(&apConfig);          apConfig.ssid_len=7;                      //设置ssid长度          os_strcpy(apConfig.ssid,"213联盟");         //设置ssid名字          os_strcpy(apConfig.password,"12345678");  //设置密码          apConfig.authmode =3;                     //设置加密模式          ETS_UART_INTR_DISABLE();                  //关闭串口中断          wifi_softap_set_config(&apConfig);        //配置          ETS_UART_INTR_ENABLE();                   //打开串口}/* *函数名:void TcpServer_Listen_Recv(void *arg, char *pdata, unsigned short len) *功能:接收监听函数 */void TcpServer_Listen_Recv(void *arg, char *pdata, unsigned short len){    uart0_sendStr(pdata);}/* * 函数名:void TcpServer_Listen_Recb(void *arg, sint8 errType) * 功能:连接监听函数 */void TcpServer_Listen_recon_cb(void *arg, sint8 errType){    struct espconn *pespconn = (struct espconn *)arg;      linkConType *linkTemp = (linkConType *)pespconn->reverse;      Connect_break=0;}/* * 函数名:void Tcp_Server_Listen_discon_cb(void *arg) * 功能:正常断开时监听函数 */void Tcp_Server_Listen_discon_cb(void *arg){      struct espconn *pespconn = (struct espconn *) arg;      linkConType *linkTemp = (linkConType *) pespconn->reverse;      Connect_break=0;}/* * 函数名:void Tcp_Server_Listen_sent_cb(void *arg) * 功能:发送成功监听函数 */void Tcp_Server_Listen_sent_cb(void *arg){      struct espconn *pespconn = (struct espconn *) arg;     linkConType *linkTemp = (linkConType *) pespconn->reverse;     Send_Flag=0;}/* * 函数名:void TcpServer_Listen_PCon(void *arg) * 功能:手机连入AP监听函数 */void TcpServerListen_PCon(void *arg){    struct espconn *pespconn = (struct espconn *)arg;      pLink.teToff = FALSE;      pLink.linkId = 1;      pLink.teType = teServer;      pLink.repeaTime = 0;      pLink.pCon = pespconn;      pespconn->reverse = &pLink;      espconn_regist_recvcb(pespconn, TcpServer_Listen_Recv);                           //注册接收监听函数      espconn_regist_reconcb(pespconn, TcpServer_Listen_recon_cb);                      //注册连接监听函数      espconn_regist_disconcb(pespconn, Tcp_Server_Listen_discon_cb);                   //注册正常断开时监听函数      espconn_regist_sentcb(pespconn, Tcp_Server_Listen_sent_cb);                       //注册发送成功监听函数}/* * 函数名:void WIFI_Server_MODE() * 功能:设置服务器模式 */void WIFIServerMode(void){        espconn_tcp_set_max_con(1);                                         //设置TCP连接的最大多少        pTcpServer = (struct espconn *)os_zalloc(sizeof(struct espconn));        pTcpServer->type = ESPCONN_TCP;                                     //TCP服务        pTcpServer->state = ESPCONN_NONE;                                   //状态        pTcpServer->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));        pTcpServer->proto.tcp->local_port = 8888;                           //断开号        espconn_regist_connectcb(pTcpServer, TcpServerListen_PCon);        espconn_accept(pTcpServer);        espconn_regist_time(pTcpServer, 180, 0);                            //设置超时断开时间 单位s}/* * 函数名:void WIFI_TCP_SendNews(unsigned char *dat) * 功能:像TCP服务器发送消息 */void WIFI_TCP_SendNews(unsigned char *dat,uint16 len){    espconn_sent(pLink.pCon,dat,len);}/*void SendTask(os_event_t *events){    struct station_info *pstation_info=wifi_softap_get_station_info();        if((pstation_info!=NULL)&&(Connect_break==1)){            if(Send_Flag==0){                Send_Flag=1;            WIFI_TCP_Send(xReceive,xLen);            }else{                uart0_sendStr("bus");            }        }else{            Send_Flag=0;            uart0_sendStr("NO device");        }        xLen=0;}void Task_Init(){//  uart_init(BIT_RATE_9600,BIT_RATE_9600);     system_os_task(SendTask, procTaskPrio, procTaskQueue, procTaskQueueLen);}*/

tcp.h

/* * tcp.h * *  Created on: 2017年3月23日 *      Author: yuanlifu */#ifndef APP_USER_TCP_H_#define APP_USER_TCP_H_void WIFIAPInit();void WIFIServerMode(void);void TcpServerListen_PCon(void *arg);void WIFI_TCP_SendNews(unsigned char *dat,uint16 len);//void Task_Init();#endif /* APP_USER_TCP_H_ */
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
基于Tricore的UDP/TCP入门工程
ESP8266 入门-NONSDK-LED-UDP
ESP8266模块使用
LWIP的移植
Socket网络编程指导
libnids 详解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服