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秒定时(重复)

}

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


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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 这里使用Java语言简单实现了客户端和服务端通信,使用Wireshark抓包工具抓取了过程中的网络包。 客户端IP...
    耿望阅读 552评论 0 0
  • 原文地址://www.greatytc.com/p/25e1113f1b66 在介绍kong插件之前 先...
    jikewang阅读 448评论 0 0
  • 迭代器的优点,为什么使用迭代器 迭代器能实现for,能取里边的数据,但它里边存的不是生成这个序列的结果,而是生成这...
    lppt阅读 107评论 0 0
  • 5)配置共享/data目录 6)创建共享目录 7)平滑重启/etc/init.dnfs reloadshowmou...
    脏页阅读 140评论 0 0
  • 苹果手机试玩无限刷教学 到目前为止试玩已经做了有几年了,首先试玩就是在手机上下载一个专用平台,从这个平台里找一个能...
    东方321阅读 162评论 0 0