美文网首页
2020-02-07

2020-02-07

作者: 等一个人咖啡_2c04 | 来源:发表于2020-02-08 20:30 被阅读0次

    TCP server 服务器


    TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议

    TCP server 是TCP服务

    TCP所提供服务的主要特点

      1.面向连接的传输;   2.端到端的通信;   3.高可靠性,确保传输数据的正确性,不出现丢失或乱序;   4.全双工方式传输;   5.采用字节流方式,即以字节为单位传输字节序列;   6.紧急数据传送功能。

    ESP8266_AP_TCP_SERVE

    ESP8266作为一个服务器,需设置端口号,也可以设置IP地址,默认为192.168.4.1

    首先定义库的一些函数就不写了

    #define ProjectName "AP_TCP_Server" // 工程名宏定义

    #define ESP8266_AP_SSID "伍俊大哥哥" // 创建的WIFI名

    #define ESP8266_AP_PASS "12345678" // 创建的WIFI密码

    #define LED_ON       GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0) // LED亮

    #define LED_OFF     GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1) // LED灭

    //==================================================================================

    // 全局变量

    //==================================================================================

    os_timer_t OS_Timer_1; // 定义软件定时器    一般情况用软件定时器,硬件定时器可能会冲突

    //配置esp8266为AP模式:热点模式

    void ICACHE_FLASH_ATTR ESP8266_AP_Init_JX()

    {

    struct softap_config AP_Config; // AP参数结构体   具体结构参考技小新视频

    wifi_set_opmode(0x02); // 设置为AP模式,并保存到Flash

    // 结构体赋值(注意:【服务集标识符/密码】须设为字符串形式)

    //--------------------------------------------------------------------------------------

    //将结构体整体清空为0,再设置AP信息

    os_memset(&AP_Config, 0, sizeof(struct softap_config)); // AP参数结构体 = 0

    os_strcpy(AP_Config.ssid,ESP8266_AP_SSID); // 设置SSID(将字符串复制到ssid数组)

    os_strcpy(AP_Config.password,ESP8266_AP_PASS); // 设置密码(将字符串复制到password数组)

    AP_Config.ssid_len=os_strlen(ESP8266_AP_SSID); // 设置ssid长度(和SSID的长度一致)

    AP_Config.channel=1;                      // 通道号1~13

    AP_Config.authmode=AUTH_WPA2_PSK;          // 设置加密模式

    AP_Config.ssid_hidden=0;                  // 不隐藏SSID

    AP_Config.max_connection=4;              // 最大连接数

    AP_Config.beacon_interval=100;            // 信标间隔时槽100~60000 ms

    wifi_softap_set_config(&AP_Config); // 设置soft-AP,并保存到Flash

    }

    // 成功发送网络数据的回调函数

    //==========================================================

    void ICACHE_FLASH_ATTR ESP8266_WIFI_Send_Cb_JX(void *arg)

    {

    os_printf("\nESP8266_WIFI_Send_OK\n");

    }

    // 成功接收网络数据的回调函数【参数1:网络传输结构体espconn指针、参数2:网络传输数据指针、参数3:数据长度】

    //=========================================================================================================

    void ICACHE_FLASH_ATTR ESP8266_WIFI_Recv_Cb_JX(void * arg, char * pdata, unsigned short len)

    {

    struct espconn * T_arg = arg; // 缓存网络连接结构体指针

    // 根据数据设置LED的亮/灭

    //-------------------------------------------------------------------------------

    if(pdata[0] == 'k' || pdata[0] == 'K') LED_ON; // 首字母为'k'/'K',灯亮

    else if(pdata[0] == 'g' || pdata[0] == 'G') LED_OFF; // 首字母为'g'/'G',灯灭

    os_printf("\nESP8266_Receive_Data = %s\n",pdata); // 串口打印接收到的数据

    //--------------------------------------------------------------------

    OLED_ShowIP(24,6,T_arg->proto.tcp->remote_ip); // 显示远端主机IP地址

    //--------------------------------------------------------------------

    //【TCP通信是面向连接的,向远端主机回应时可直接使用T_arg结构体指针指向的IP信息】

    //-----------------------------------------------------------------------------------------------

    espconn_send(T_arg,"ESP8266_WIFI_Recv_OK",os_strlen("ESP8266_WIFI_Recv_OK")); // 向对方发送应答

    }

    // TCP连接断开成功的回调函数

    //================================================================

    void ICACHE_FLASH_ATTR ESP8266_TCP_Disconnect_Cb_JX(void *arg)

    {

    os_printf("\nESP8266_TCP_Disconnect_OK\n");

    }

    void ICACHE_FLASH_ATTR ESP8266_TCP_Connect_Cb_JX(void *arg)

    {

    espconn_regist_sentcb((struct espconn *)arg, ESP8266_WIFI_Send_Cb_JX); // 注册网络数据发送成功的回调函数

    espconn_regist_recvcb((struct espconn *)arg, ESP8266_WIFI_Recv_Cb_JX); // 注册网络数据接收成功的回调函数

    espconn_regist_disconcb((struct espconn *)arg,ESP8266_TCP_Disconnect_Cb_JX); // 注册成功断开TCP连接的回调函数

    os_printf("\n--------------- ESP8266_TCP_Connect_OK ---------------\n");

    }

    // TCP连接异常断开时的回调函数

    //====================================================================

    void ICACHE_FLASH_ATTR ESP8266_TCP_Break_Cb_JX(void *arg,sint8 err)

    {

    os_printf("\nESP8266_TCP_Break\n");

    }

    // 定义espconn型结构体

    //-----------------------------------------------

    struct espconn ST_NetCon; // 网络连接结构体

    // 初始化网络连接(TCP通信)

    //=============================================================================================================

    void ICACHE_FLASH_ATTR ESP8266_NetCon_Init_JX()

    {

    // 结构体赋值

    //--------------------------------------------------------------------------

    ST_NetCon.type = ESPCONN_TCP ; // 通信协议:TCP

    ST_NetCon.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); // 申请内存

    // 此处无需设置目标IP/端口(ESP8266作为Server,不需要预先知道Client的IP/端口)

    //--------------------------------------------------------------------------

    ST_NetCon.proto.tcp->local_port = 8266 ; // 设置本地端口

    //ST_NetCon.proto.tcp->remote_port = 8888; // 设置目标端口

    //ST_NetCon.proto.tcp->remote_ip[0] = 192; // 设置目标IP地址

    //ST_NetCon.proto.tcp->remote_ip[1] = 168;

    //ST_NetCon.proto.tcp->remote_ip[2] = 4;

    //ST_NetCon.proto.tcp->remote_ip[3] = 2;

    // 注册连接成功回调函数、异常断开回调函数

    //--------------------------------------------------------------------------------------------------

    espconn_regist_connectcb(&ST_NetCon, ESP8266_TCP_Connect_Cb_JX); // 注册TCP连接成功建立的回调函数

    espconn_regist_reconcb(&ST_NetCon, ESP8266_TCP_Break_Cb_JX); // 注册TCP连接异常断开的回调函数

    // 创建TCP_server,建立侦听

    //----------------------------------------------------------

    espconn_accept(&ST_NetCon); // 创建TCP_server,建立侦听

    // 请在 espconn_accept 之后,连接未建立之前,调用本接口

    // 如果超时时间设置为 0,ESP8266_TCP_server将始终不会断开已经不与它通信的TCP_client,不建议这样使用。

    //---------------------------------------------------------------------------------------------------

    espconn_regist_time(&ST_NetCon, 300, 0); //设置超时断开时间。单位=秒,最大值=7200

    }

    void ICACHE_FLASH_ATTR OS_Timer_1_cb(void)

    {

    struct ip_info ST_ESP8266_IP; // IP信息结构体

    u8 ESP8266_IP[4]; // 点分十进制形式保存IP

    wifi_get_ip_info(SOFTAP_IF,&ST_ESP8266_IP); // 查询AP模式下ESP8266的IP地址

    if(ST_ESP8266_IP.ip.addr != 0 ) // ESP8266成功获取到IP地址

    {

    ESP8266_IP[0] = ST_ESP8266_IP.ip.addr; // 点分十进制IP的第一个数 <==> addr低八位

    ESP8266_IP[1] = ST_ESP8266_IP.ip.addr>>8; // 点分十进制IP的第二个数 <==> addr次低八位

    ESP8266_IP[2] = ST_ESP8266_IP.ip.addr>>16; // 点分十进制IP的第三个数 <==> addr次高八位

    ESP8266_IP[3] = ST_ESP8266_IP.ip.addr>>24; // 点分十进制IP的第四个数 <==> addr高八位

    // 显示ESP8266的IP地址

    //-----------------------------------------------------------------------------------------------

    os_printf("ESP8266_IP = %d.%d.%d.%d\n",ESP8266_IP[0],ESP8266_IP[1],ESP8266_IP[2],ESP8266_IP[3]);

    OLED_ShowIP(24,2,ESP8266_IP); // OLED显示ESP8266的IP地址

    //-----------------------------------------------------------------------------------------------

    os_timer_disarm(&OS_Timer_1); // 关闭定时器

    ESP8266_NetCon_Init_JX(); // 初始化网络连接(TCP通信)

    }

    }

    //=============================================================================================================

    // 软件定时器初始化(ms毫秒)

    //=====================================================================================

    void ICACHE_FLASH_ATTR OS_Timer_1_Init_JX(u32 time_ms, u8 time_repetitive)

    {

    os_timer_disarm(&OS_Timer_1); // 关闭定时器

    os_timer_setfn(&OS_Timer_1,(os_timer_func_t *)OS_Timer_1_cb, NULL); // 设置定时器

    os_timer_arm(&OS_Timer_1, time_ms, time_repetitive);  // 使能定时器

    }

    //=====================================================================================

    // LED初始化

    //=============================================================================

    void ICACHE_FLASH_ATTR LED_Init_JX(void)

    {

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4); // GPIO4设为IO口

    GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1); // IO4 = 1

    }

    //=============================================================================

    // user_init:entry of user application, init user function here

    //=============================================================================

    void ICACHE_FLASH_ATTR user_init(void)

    {

    uart_init(115200,115200); // 初始化串口波特率

    os_delay_us(10000); // 等待串口稳定

    os_printf("\r\n=================================================\r\n");

    os_printf("\t Project:\t%s\r\n", ProjectName);

    os_printf("\t SDK version:\t%s", system_get_sdk_version());

    os_printf("\r\n=================================================\r\n");

    // OLED显示初始化

    //--------------------------------------------------------

    OLED_Init(); // OLED初始化

    OLED_ShowString(0,0,"ESP8266 = AP"); // ESP8266模式

    OLED_ShowString(0,2,"IP:"); // ESP8266_IP地址

    OLED_ShowString(0,4,"Remote  = STA"); // 远端主机模式

    OLED_ShowString(0,6,"IP:"); // 远端主机IP地址

    //--------------------------------------------------------

    LED_Init_JX(); // LED初始化

    ESP8266_AP_Init_JX(); // 初始化ESP8266_AP模式

    OS_Timer_1_Init_JX(1000,1); // 1秒定时(重复)

    }

    //=============================================================================

    已经理解了一部分,还是有一些模糊的方面未完待写

    相关文章

      网友评论

          本文标题:2020-02-07

          本文链接:https://www.haomeiwen.com/subject/cyrvxhtx.html