ESP8266_13服务器端模式下的TCP通信

上一节说的是TCP客户端模式下的通信,这一节说一下服务器端模式下的通信,总体来说,代码是差不多的,只是关键地方有些调整。

另外,包括上一节在内,这两节的代码里,ESP8266的工作模式设置为了station+softap模式。但在进行TCP通信时,都是以station的身份通信。后面会说一下,如果以softap身份通信有什么注意事项。

还有就是,有的朋友留言问,如果想快速开发APP,实现手机和ESP8266的通信调试,一般怎么实现。就我个人,一般是在物联网后台上直接看数据,很少在手机上操作。有没有想过自己写APP?

有,确实想过,但还是之前提过的,我是个硬件工程师~自己写APP?跨度有点大,我倒是做过一些工作,研究过易安卓和安卓studio,感兴趣的可以试着从这两方便入手试试,或者有其它的,大家也可以留言。

好,继续。这里保留上一节引用的“TCP编程的服务器端一般步骤”,作为参考:

TCP编程的服务器端一般步骤是:

1、创建一个socket,用函数socket();

2、设置socket属性,用函数setsockopt(); * 可选

3、绑定IP地址、端口等信息到socket上,用函数bind();

4、开启监听,用函数listen();

5、接收客户端上来的连接,用函数accept();

6、收发数据,用函数send()和recv(),或者read()和write();

7、关闭网络连接;

8、关闭监听;

因为步骤和上一节相似程度很高,所以我会做一些简化,如果有看不懂的地方,建议对比上一节内容。另外,学习类的东西,建议在电脑端打开,个人感觉手机上看的效果一般,只能看个大概。深度学习,个人还是习惯在电脑上进行。好,演示开始。

因为做了简化,步骤分为4步。

1、包含头文件

跟上一节一样,所以略过。

2、设置工作模式为station+ soft-ap模式,并连接到当前环境下的wifi

跟上一节一样,但是这次的代码加了一句。虽然设置为了station+ soft-ap模式,设置了AP名字和密码,但好像不用输入密码就能连接,这是因为没有设置加密模式:

config.authmode = AUTH_WPA_PSK; //加密模式

增加这一行之后,就可以了。更多信息建议看一下“softap_config”这个结构体的定义,里面比较详细。

3、确定TCP服务器端的参数,并初始化

我是谁——ESP8266,连接家里路由成功之后,会自动获得一个IP,这是服务器端IP

谁要和我连接——因为是在我电脑上使用网络调试助手模拟TCP客户端端,所以客户端端的IP是我电脑的IP:192.168.1.103

连接的端口——这里选1025.

struct ip_info info;

const char remote_ip[4]={192,168,1,103}; //TCP客户端IP

wifi_get_ip_info(STATION_IF,&info); //获取8266的WIFI信息

server_init((struct ip_addr *)remote_ip,&info.ip,1025);

可以看到,和上一节相比,函数名字变了,但其实内容大部分都一样:

{

         LOCAL struct espconn esp_conn;

         //初始化espconn参数

         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);

         os_memcpy(esp_conn.proto.tcp->remote_ip,remote_ip,4);

         esp_conn.proto.tcp->local_port=port;

 

         //注册连接成功回调函数和重新连接回调函数

         espconn_regist_connectcb(&esp_conn,server_listen);

         espconn_regist_reconcb(&esp_conn,server_recon);

         //创建TCP server,建立监听

         espconn_accept(&esp_conn);

}

不一样的地方,我用加粗和斜线的方式标了出来。先说:

espconn_accept(&esp_conn);

因为这个简单,上一节是TCP客户端,创建连接,所以用:

espconn_connect(&user_tcp_conn);

而这一节是服务器端,是一个等待别人来连接我的角色,所以要监听别人。

然后是回调函数server_listen,它的内容也和客户端不一样。具体区别看第4步。

4、定义连接成功的回调函数

函数内容如下:

         struct espconn *pespconn=arg;

         os_printf("\r\nconnect success!\r\n");

         espconn_regist_recvcb(pespconn,server_recv);

         espconn_regist_sentcb(pespconn,server_sent);

         espconn_regist_disconcb(pespconn,server_discon);

客户端的函数代码如下:

struct espconn *pespconn=arg;

espconn_regist_recvcb(pespconn,user_tcp_recv_cb);

espconn_regist_sentcb(pespconn,user_tcp_sent_cb);

espconn_regist_disconcb(pespconn,user_tcp_discon_cb);

espconn_sent(pespconn,"hello,this is esp8266!",strlen("hello,this is esp8266!"));

不考虑printf的打印信息,创建的这三个回调函数,功能大部分基本是一样的。都是接收完成回调函数、发送完成回调函数和断开连接回调函数。区别在于客户端连接成功后会主动发送信息,而服务器端被动一些,收到信息后,才会根据需要有所返回。

那几个回调函数,功能大同小异,就不说了。所以除了这些,基本上就没什么区别了。感兴趣的童鞋,建议把代码下载下来,依次对比一下,这样可以有一个比较深的理解。

好,到此为止,程序修改完毕。

注:本例程里提到的大部分函数,都参照手册2c-esp8266_sdk_api_guide_cn_v1.5.4。

程序修改完成,保存、清理、编译、下载一条龙,然后重新上电。这里,需要借助串口助手和网络调试助手两个工具来查看效果。效果如下所示:

设置网络调试助手:

注意事项:需要等到ESP8266连接家里wifi成功以后,也就是串口助手打印出:Wifi connect success!之后,网络调试助手才能进行连接。

因为在此之前,TCP server端还没有初始化完成,这时候TCP客户端即便想连接,也找不到对象。

TCP连接成功之后,串口助手输出信息:connect success!

这时,手动从网络调试助手那里发送信息:MCU LOVER

可以看到串口助手打印出来,这说明ESP8266已经收到了。

这时,在网络调试助手这里点击“断开”,可以看到串口助手打印:TCP cliend disconnected!

说明连接断开成功(client 写成了 cliend,不要在意这些细节)。

最后,有的人可能会问,你说的这些步骤、工作流程都是怎么来的?不可能是瞎猜的吧?

确实,这个问题很关键,所有工作都要有一个明确的工作流程。其实答案还是在手册里:2c-esp8266_sdk_api_guide_cn_v1.5.4,第216页:

有了手册,再参考SDK里面的例程,基本就差不多了。还是那句话,多看手册。好,这一节说完了,欢迎大家动手尝试!

完整工程源码,请关注公众号:单片机爱好者,回复关键字:ESP8266,即可获取。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据