2020-02-07
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秒定时(重复)
}
//=============================================================================