上一節說的是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(" nconnect success! ");
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已經收到了。
這時,在網絡調試助手這里點擊“斷開”,可以看到串口助手打?。篢CP cliend disconnected!
說明連接斷開成功(client 寫成了 cliend,不要在意這些細節)。
最后,有的人可能會問,你說的這些步驟、工作流程都是怎么來的?不可能是瞎猜的吧?
確實,這個問題很關鍵,所有工作都要有一個明確的工作流程。其實答案還是在手冊里:2c-esp8266_sdk_api_guide_cn_v1.5.4,第216頁:
有了手冊,再參考SDK里面的例程,基本就差不多了。還是那句話,多看手冊。好,這一節說完了,歡迎大家動手嘗試!
-
服務器
+關注
關注
12文章
9017瀏覽量
85182 -
TCP通信
+關注
關注
0文章
146瀏覽量
4216
原文標題:ESP8266_13服務器端模式下的TCP通信
文章出處:【微信號:gh_dae0718828df,微信公眾號:gh_dae0718828df】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論