[网络篇]ESP8266-SDK教程(三)之TCP通信Server-Client
[⽹络篇]ESP8266-SDK教程(三)之TCP通信Server-Client
纳尼?昨天刚刚打印了个“Hello World!”,今天你就让我学习TCP通信?有没有搞错~哈哈,相信很多读者会很迷,其实学习这东西嘛,单单学⼀些⽐较简单的,相信没两天就没⼈看了,所以咱就在基础篇和⽹络篇穿插着去学习⼀下ESP8266,毕竟兴趣才是最好的⽼师嘛!⼤家以后遇到问题了,来翻⽂章建议⼤家根据[XX篇]去快速定位该去哪⼀篇⽂章中去查问题,当然具体会在哪⼀篇⽂章中有讲,也不⼀定了,后⾯也会穿插着写⼀点[项⽬篇][进阶篇][闲扯篇],总的来说就是,本系列⽂章并没有固定的路线,⼤家不如忍忍?当然这⾥写的⽂章也不⼀定是对的,⼤家在实际测试中如果遇到了问题,还请私信我,或者在Github上提交issue!
闲话少说,既然要学习TCP通信的知识,那么我们得先要了解⼀下TCP到底是个什么东西(玩意),正所谓孙⼦曾经⽈过“知彼知⼰,百战不殆”,那我们先补⼀些关于TCP的知识吧!
TCP基础知识:
是什么?
TCP(Transmission Control Protocol)是⼀种⾯向连接的、可靠的、基于字节流的通信协议。(百度词条搜到的~)
说⽩了就是⼀种传输协议,就像我们串⼝、232、485等⼀样的通讯协议,只不过TCP多⽤于⽹络间的通讯,不过TCP是在IP层之上的,相信你肯定见过或者听说过TCP/IP协议,没错,这哥俩是绑在⼀块的,TCP是依赖IP协议的。
通讯机制
TCP与我们常使⽤的串⼝等通讯协议有什么不同呢?⾸先是两台主机建⽴TCP连接机制是⽐较⿇烦的,要经过三次握⼿协议,才能建⽴连接,过程⽤汉字描述如下:
客户端发送SYN(SEQ=x)报⽂给服务器端,进⼊SYN_SEND状态。
服务器端收到SYN报⽂,回应⼀个SYN (SEQ=y)ACK(ACK=x+1)报⽂,进⼊状态。
客户端收到服务器端的SYN报⽂,回应⼀个ACK(ACK=y+1)报⽂,进⼊Established状态。
看字⽐较⿇烦,我们还是看图吧!
既然有建⽴连接,那么肯定也有断开连接,但是没想到断开连接⽐建⽴连接还要⿇烦,还有四次挥⼿协议,纳尼?是的,断开连接需要经过四次挥⼿协议,直接看图吧:
可靠性
上⾯说的通讯机制之所以这么⿇烦,主要还是为了传输的可靠性,因为TCP是在整个⽹络中去传输,只要你有IP地址,并且在⼴域⽹中访问,那我们就可以建⽴TCP连接,说会悄悄话~所以,两者之间的可靠性就显得很重要了,客户端与服务端之间的连接可靠性靠很多策略去实现的⽐如⼼跳包机制,这⾥就不再详细叙述了,有点跑题了,这是ESP8266学习笔记~
数据包格式
TCP的数据包相对来说是⽐较⿇烦的,确认信息占据了整个数据包的很⼤⼀部分,设计的这么复杂主要原因还是保证在整个⽹络当中每包数据传输的正确性,这⾥我们就看⼀下数据包到底有多么复杂:
ESP8266作为TCP Client跟Server(PC)通信
了解了⼀点点基础知识后,我们还是要落实到实践上,下⾯我们正式开始,⾸先我们需要先看⼀下官⽅SDK编程指导⼿册,还没有?不知道去哪⾥下?好嘞,直接戳下⾯卡⽚下载好了~王骏迪生活不检点
英⽂版戳这⾥,如果你英语跟⼩编⼀样好的话,建议看英⽂版,要不断提升⾃⼰的英语~
咳咳咳,那我们先打开这个英⽂⽂档,到97页的TCP/UDP接⼝,我们先看⼀下接⼝分了⼏类:
咳咳咳,不要怀疑,使⽤的PDF查看软件有⾃动翻译动能,⼿动滑稽.jpg,可以看到⼀共分了4类,本篇⽂章我们先研究下通⽤ API和TCP API,关于UDP和mDNS的我们再后⾯的⽂章中再继续学习,你可以先⼤体看⼀下,每个API的注释都讲的很明⽩,我们不妨直接copy点代码直接跑⼀下?
1 git clone git@github:imliubo/makingfunxyz-esp8266.git 23 #如果之前有clong过,可以直接 git pull,不会⽤?那肯定是没好好看廖雪峰的git教程
下载完成后,打开ESP_IDE导⼊在makingfunxyz-esp8266-NONOS⽂件中的6.TCP_UDP_Server_Client这个⼯程,然后先修改⼀点东西,这⼀步很重要,请不要忽略:
Wi-Fi名称跟密码相信你肯定知道,TCP_SERVER_IP应该要修改成什么呢?就是你电脑的IP地址,这⾥每个⼈的都不⼀样,建议你先去查看⼀下,⽅法看视频~
视频还在托管⽅~
可以看到我这⾥是192.168.0.109,那我就将它修改成192.168.0.109,这三个地⽅都修改好了后,我们直接先编译代码,先跑⼀下看看!编译好代码后,下载到ESP8266,这⾥跟上篇⽂章中是⼀样的,就不再详述,下载地址参考:
eagle.flash.bin-------->0x00000
eagle.irom0text.bin---->0x10000
esp_init_data_default_v08.bin --> 0x3FC000
blank.bin --> 0x3FE000
下载完成后,我们先不要急着去看结果,因为我们还没有开启TCP Server,那我们该怎么开启TCP Server呢?我这⾥⽤Python写了⼀个很简单的Server端程序,⼤家可以使⽤我这个,要是使⽤别的TCP调试助⼿,注意TCP_SERVER_PORT也要修改⼀下,运⾏我们的Server很简单,但是你需要安
装⼀下Python,我这⾥没有打包成可执⾏⽂件,先去安装⼀下Python吧,我⽤的是Python3,建议⼤家也安装Python3,因为Python2跟Python3有些语法不⼀样,戳卡⽚下载:
下载安装完成后,开始搞起来,我们需要在6.TCP_UDP_Server_Client这个⽂件夹下到TCP_Server.py这个⽂件夹,然后打开修改⼀下IP地址,将IP地址修改成上⾯我们查看的本机地址,看图:
最后我们还需要设置⼀下开放端⼝,这⾥步骤有点多,就不再细述了,⼤家可以直接看这个百度知道,写的很详细:
然后打开命令窗⼝,具体操作办法,在此⽂件下按住shift键,然后右键选择打开powershell窗⼝(WIN7 应该是cmd窗⼝),然后:
1 start cmd
2 #可以直接在powershell⾥⾯执⾏,但是我还是⽐较喜欢cmd窗⼝,所以就~win7不⽤,因为打开的就是cmd窗⼝
3 #cmd窗⼝打开后,输⼊以下命令
4 python
TCP_Server.py
视频还在托管⽅~
ESP8266作为TCP Server跟Client(PC)通信
上⾯是ESP8266作为Client去跟Server通信,但是ESP8266不仅可以作为Client还可以作为Server等待Client去建⽴连接去通信,这⾥我们修改⼏个地⽅,就可以将ESP8266作为Server 去跟Client通信了,我在源码中已经都写好了,这⾥我们将同样将ESP8266的6666作为PC去连接的端⼝号:
其中TCP_Client.py⽂件中的IP地址需要在ESP8266上电打印后修改⼀下,我们将上⾯⼩节中的tcp_client_init()注释掉,tcp_server_init()取消注释,然后重新编译代码下载就好了,PC上的Client程序跟Server程序运⾏⼀样,这⾥我们直接看⼀下视频吧!
视频还在托管⽅~
这⾥代码就不再解释了,我写的注释还算全,⼤家⼀看就懂,主要代码:
1/****************************
2 *  TCP CLIENT FUNCTIONS  *
3 ****************************/
4
5/**********************************
6 *  TCP CLIENT STATIC PROTOTYPES  *
7 **********************************/
8static void tcp_client_sent_cb(void *arg);
9static void tcp_client_recv_cb(void *arg,char *pdata,unsigned short length);
10static void tcp_client_recon_cb(void *arg,sint8 error);
11static void tcp_client_discon_cb(void *arg);
12static void tcp_client_connect_cb(void *arg);
13
14/**********************************
15 *  TCP CLIENT STATIC VARIABLES  *
16 **********************************/
17 os_timer_t tcp_client_send_data_timer;
18struct espconn tcp_client;
19 uint8 i;
20
21/**********************************
22 *  TCP CLIENT STATIC FUNCTIONS  *
23 **********************************/
24
25/**
26 * TCP Client数据发送回调函数
27*/
dnf啊修罗28static void ICACHE_FLASH_ATTR
29 tcp_client_sent_cb(void *arg){
30    os_printf("tcp client send data successful\r\n");
31 }
32
33/**
34 * TCP Client数据接收回调函数,可以在这处理收到Server发来的数据
35*/
36static void ICACHE_FLASH_ATTR
37 tcp_client_recv_cb(void *arg,char *pdata,unsigned short len){
38    os_printf("tcp client receive tcp server data\r\n");
39    os_printf("length: %d \r\ndata: %s\r\n",len,pdata);
40
41//TO DO
42
43/**
44    *process the receive data
45*/
46 }
47
48/**
49 * TCP Client重连回调函数,可以在此函数⾥做重连接处理
50*/
51static void ICACHE_FLASH_ATTR
52 tcp_client_recon_cb(void *arg,sint8 error){
53    os_printf("tcp client connect tcp server error %d\r\n",error);
54    os_timer_disarm(&tcp_client_send_data_timer);//取消定时发送数据定时器包头旅游
55 }
56
57/**
58 * TCP Client断开连接回调函数
59*/
60static void ICACHE_FLASH_ATTR
61 tcp_client_discon_cb(void *arg){
62    os_printf("tcp client disconnect tcp server successful\r\n");
63    os_timer_disarm(&tcp_client_send_data_timer);
64 }
65
66/**
67 * TCP Client连接成功回调函数
68*/
69static void ICACHE_FLASH_ATTR
70 tcp_client_connect_cb(void *arg){
71struct espconn *pespconn = arg;
72
73    os_printf("tcp client connect tcp server successful\r\n");
74    espconn_regist_recvcb(pespconn,tcp_client_recv_cb);//注册接收数据回调函数
75    espconn_regist_sentcb(pespconn,tcp_client_sent_cb);//注册数据发送完成回调函数
76    espconn_regist_disconcb(pespconn,tcp_client_discon_cb);//注册断开连接回调函数
77
78    os_timer_disarm(&tcp_client_send_data_timer);
79    os_timer_setfn(&tcp_client_send_data_timer, (os_timer_func_t *) tcp_client_send_data,NULL);//注册Client定时发送数据回调函数
80    os_timer_arm(&tcp_client_send_data_timer, 1000, true);//时间设置为1s
81 }
82
83/**********************************
84 *  TCP CLIENT GLOBAL FUNCTIONS  *
85 **********************************/
有人欠钱不还怎么办86/**
87 * TCP Client定时发送数据回调函数
88*/
89void ICACHE_FLASH_ATTR
90 tcp_client_send_data(void){
91char buf[256],length;
92    os_printf("tcp client send data tcp server\r\n");
93    length = os_sprintf(buf,(char *)"Hi this is ESP8266 client! message num %d",i);
94    i++;
95    espconn_sent(&tcp_client,buf,length);
96 }
97
98/**
99 * TCP Client初始化函数
100 * @remote_ip    要连接的TCP Server IP地址
101 * @local_ip    ESP8266 IP地址
102 * @remote_port  要连接的TCP Server端⼝号
103*/
104void ICACHE_FLASH_ATTR
105 tcp_client_init(uint8 *remote_ip,struct ip_addr *local_ip, int remote_port){
106
107    uint32 server_ip = ipaddr_addr(remote_ip);
108
109    os_printf("tcp client connect to tcp server\r\n");
110    tcp_p = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
111    pe = ESPCONN_TCP;
112
113    os_memcpy(tcp_p->remote_ip,&server_ip,4);//设置要连接的Server IP地址
114    tcp_p->remote_port = remote_port;//设置要连接的Server 端⼝号
115    os_memcpy(tcp_p->local_ip,local_ip,4);//设置本地IP地址
116    tcp_p->local_port = espconn_port();//设置本地端⼝号
117失之毫厘的下一句
118    espconn_regist_connectcb(&tcp_client,tcp_client_connect_cb);//注册连接成功回调函数
119    espconn_regist_reconcb(&tcp_client,tcp_client_recon_cb);//注册断连重新连接回调函数
120
121    espconn_connect(&tcp_client);//Client连接Server
122 }
123
124
125
126/****************************
127 *  TCP SERVER FUNCTIONS  *
128 ****************************/
129/**********************************
130 *  TCP SERVER STATIC PROTOTYPES  *
131 **********************************/
132static void tcp_server_sent_cb(void *arg);
133static void tcp_server_recv_cb(void *arg,char *pdata,unsigned short length);
134static void tcp_server_recon_cb(void *arg,sint8 error);
135static void tcp_server_discon_cb(void *arg);
136static void tcp_server_listen_cb(void *arg);
137
138/**********************************
139 *  TCP SERVER STATIC VARIABLES  *
140 **********************************/
141 os_timer_t tcp_server_send_data_timer;
142struct espconn tcp_server;
143 uint8 z;
144
145/**********************************
空调内机漏水是什么原因怎么解决146 *  TCP server STATIC FUNCTIONS  *
147 **********************************/
148
149/**
150 * TCP Server数据发送回调函数
151*/
152static void ICACHE_FLASH_ATTR
153 tcp_server_sent_cb(void *arg){
154    os_printf("tcp server send data successful\r\n");
155
156 }
157
158/**
159 * TCP Server数据接收回调函数,可以在这处理收到Client发来的数据
160*/
161static void ICACHE_FLASH_ATTR
162 tcp_server_recv_cb(void *arg,char *pdata,unsigned short len){
163    os_printf("tcp server receive tcp client data\r\n");
164    os_printf("length: %d \r\ndata: %s\r\n",len,pdata);
165
166//TO DO
167
168/**
169    *process the receive data
170*/
171 }
172
173/**
174 * TCP Server重连回调函数,可以在此函数⾥做重连接处理
175*/
176static void ICACHE_FLASH_ATTR
177 tcp_server_recon_cb(void *arg,sint8 error){
178    os_printf("tcp server connect tcp client error %d\r\n",error);
179    os_timer_disarm(&tcp_server_send_data_timer);
180 }
181
182/**
183 * TCP Server断开连接回调函数
184*/
185static void ICACHE_FLASH_ATTR
186 tcp_server_discon_cb(void *arg){
187    os_printf("tcp server disconnect tcp client successful\r\n");
188    os_timer_disarm(&tcp_server_send_data_timer);
189 }
190
191/**
192 * TCP Server监听Client连接回调函数
193*/
194static void ICACHE_FLASH_ATTR
195 tcp_server_listen_cb(void *arg){
196struct espconn *pespconn = arg;
197
198    os_printf("tcp server have tcp client connect\r\n");
199    espconn_regist_recvcb(pespconn,tcp_server_recv_cb);//注册收到数据回调函数
200    espconn_regist_sentcb(pespconn,tcp_server_sent_cb);//注册发送完数据回调函数
201    espconn_regist_disconcb(pespconn,tcp_server_discon_cb);//注册断开连接回调函数
202
203    os_timer_disarm(&tcp_server_send_data_timer);
204    os_timer_setfn(&tcp_server_send_data_timer, (os_timer_func_t *) tcp_server_send_data,NULL);//注册Server定时发送数据回调函数205    os_timer_arm(&tcp_server_send_data_timer, 1000, true);//设置时间为1s
206 }
207
208/**********************************
209 *  TCP CLIENT GLOBAL FUNCTIONS  *
210 **********************************/
211
212/**
213 * TCP Server定时发送数据回调函数
214*/
215void ICACHE_FLASH_ATTR
216 tcp_server_send_data(void){

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。