chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

輕松掌握——LuatOS socket基礎(chǔ)知識(shí)和應(yīng)用開(kāi)發(fā)

合宙LuatOS ? 來(lái)源:合宙LuatOS ? 作者:合宙LuatOS ? 2026-01-28 20:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

對(duì)于剛接觸LuatOS開(kāi)發(fā)的工程師而言,實(shí)現(xiàn)設(shè)備聯(lián)網(wǎng)往往是第一個(gè)重要目標(biāo),而Socket編程正是實(shí)現(xiàn)這一目標(biāo)的核心技術(shù)路徑。本文以循序漸進(jìn)的方式,帶領(lǐng)讀者從最基礎(chǔ)的Socket概念入手,逐步掌握在LuatOS環(huán)境中創(chuàng)建客戶端與服務(wù)器、發(fā)送與接收數(shù)據(jù)等關(guān)鍵技能,為后續(xù)復(fù)雜應(yīng)用打下堅(jiān)實(shí)基礎(chǔ)。

一、主要內(nèi)容

LuatOS socket是LuatOS開(kāi)發(fā)中最常用到的網(wǎng)絡(luò)應(yīng)用之一;

LuatOS socket課程主要包含以下幾個(gè)部分:

1、TCP/IP總體介紹;

2、LuatOS上的4G/WiFi/以太網(wǎng)三種網(wǎng)絡(luò)環(huán)境下的TCP/IP協(xié)議??傮w介紹;

3、TCP/UDP/SSL/證書(shū)以及socket概念;

4、LuatOS socket核心庫(kù)和libnet擴(kuò)展庫(kù)功能介紹;

5、LuatOS socket client應(yīng)用開(kāi)發(fā)框架(TCP,UDP,SSL,網(wǎng)絡(luò)環(huán)境檢測(cè)看門狗);

6、如何分析LuatOS socket日志;

二、TCP/IP總體介紹

今天我們講的LuatOS socket是LuatOS開(kāi)發(fā)中最常用到的網(wǎng)絡(luò)應(yīng)用之一,用戶使用LuatOS socket開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用,會(huì)直接接觸到TCP/UDP/SSL/認(rèn)證等一些網(wǎng)絡(luò)核心概念;

而說(shuō)到網(wǎng)絡(luò)應(yīng)用,就繞不開(kāi)TCP/IP;

2.1 TCP/IP網(wǎng)絡(luò)模型

有網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)的人,應(yīng)該都聽(tīng)說(shuō)過(guò)OSI七層模型、TCP/IP協(xié)議四層模型和TCP/IP協(xié)議五層模型;

這三種網(wǎng)絡(luò)協(xié)議模型的說(shuō)明,參考下表:

wKgZO2l5wtCAVdglAABaszKk-bg452.png

看了這張表之后,我們應(yīng)該有以下幾點(diǎn)認(rèn)識(shí):

  1. 都采用了分層的思想,將復(fù)雜的通信過(guò)程分解為更小、更易于管理的部分;
  2. 每一層都為其上層提供服務(wù),并使用其下層提供的服務(wù);
  3. 這三種網(wǎng)絡(luò)模型,只是分層的顆粒度不一樣,實(shí)際上,這三種網(wǎng)絡(luò)模型的本質(zhì)內(nèi)容都是一樣的;

既然這三種網(wǎng)絡(luò)模型的本質(zhì)內(nèi)容是一樣的,為什么還要存在三種網(wǎng)絡(luò)模型呢?每種網(wǎng)絡(luò)模型又有什么作用呢?

我們簡(jiǎn)單地看一下這三種網(wǎng)絡(luò)模型的歷史:

wKgZPGl5wwyACeN2AAMxMQNVAXE870.png

最終TCP/IP模型在實(shí)踐中得到廣泛應(yīng)用;

至于TCP/IP四層模型和TCP/IP五層模型,二者的差別不大,主要體現(xiàn)在對(duì)最底層的劃分不同:

  1. 四層模型隱藏了底層細(xì)節(jié),將網(wǎng)絡(luò)接入視為一個(gè)黑盒,更關(guān)注對(duì)軟件層面的設(shè)計(jì),不關(guān)心具體的硬件;
  2. 五層模型明確包含了物理硬件層;

四層模型和五層模型本質(zhì)上是同一個(gè)東西的兩種不同表述方式,所以我們接下來(lái)不糾結(jié)四層還是五層模型,而是統(tǒng)稱為TCP/IP模型,下文中會(huì)根據(jù)不同的應(yīng)用場(chǎng)景來(lái)決定選擇四層模型還是五層模型來(lái)講解。

2.2 TCP/IP協(xié)議

在了解了TCP/IP網(wǎng)絡(luò)模型之后,接下來(lái)我們看一下TCP/IP協(xié)議這個(gè)概念;

TCP/IP網(wǎng)絡(luò)模型是理論上的框架和藍(lán)圖,而TCP/IP協(xié)議是這個(gè)框架的具體實(shí)現(xiàn);

我們來(lái)看下面這張表格

wKgZPGl5w8SACH4GAAB2fCy6fGQ717.png

可以看到,每一層都有多個(gè)協(xié)議去實(shí)現(xiàn),在所有的這些協(xié)議中,TCP和IP兩種協(xié)議是其中的核心協(xié)議,所以用TCP/IP協(xié)議代指網(wǎng)絡(luò)模型中的所有協(xié)議;

所以說(shuō),TCP/IP協(xié)議 并不是兩個(gè)單一的協(xié)議,而是一個(gè)協(xié)議家族,包含TCP/IP網(wǎng)絡(luò)模型中的所有協(xié)議;

所有協(xié)議協(xié)同工作,從軟件上完成了互聯(lián)網(wǎng)上的數(shù)據(jù)傳輸任務(wù);

2.3 TCP/IP協(xié)議的核心工作原理

TCP/IP協(xié)議通過(guò)功能分層以及數(shù)據(jù)封裝/解封裝,來(lái)協(xié)同工作完成網(wǎng)絡(luò)數(shù)據(jù)傳輸任務(wù);

2.3.1 功能分層

下層為上層提供服務(wù),上層使用下層提供的服務(wù);

每一層都只專注于自己的任務(wù);

TCP/IP五層模型,從上到下劃分為應(yīng)用層,傳輸層,網(wǎng)絡(luò)層,數(shù)據(jù)鏈路層,物理層;

每一層的主要功能如下:

1.應(yīng)用層:應(yīng)用層的主要工作是定義數(shù)據(jù)格式并按照對(duì)應(yīng)的格式解讀數(shù)據(jù),應(yīng)用層定義了各種各樣的協(xié)議來(lái)規(guī)范數(shù)據(jù)格式,常見(jiàn)的有 HTTP、MQTT、FTP、WebSocket等;

例如常見(jiàn)的HTTP協(xié)議,服務(wù)端收到客戶端的請(qǐng)求以后,就能按照HTTP報(bào)文的格式,正確地解析客戶端發(fā)來(lái)的數(shù)據(jù),當(dāng)請(qǐng)求處理完以后,再按照HTTP報(bào)文的格式返回結(jié)果給客戶端,客戶端收到結(jié)果后,按照HTTP報(bào)文的格式進(jìn)行解析;

2.傳輸層:傳輸層的主要工作是定義端口,標(biāo)識(shí)應(yīng)用程序身份,實(shí)現(xiàn)端到端的通信,為應(yīng)用層的應(yīng)用程序提供可靠的或不可靠的數(shù)據(jù)傳輸服務(wù);

數(shù)據(jù)包是從發(fā)送端設(shè)備的某個(gè)應(yīng)用程序發(fā)出,然后由接收端設(shè)備的某個(gè)應(yīng)用程序接收。而每臺(tái)設(shè)備都有可能同時(shí)運(yùn)行著很多個(gè)應(yīng)用程序,所以要通過(guò)傳輸層定義的端口來(lái)確認(rèn)使用的是設(shè)備上的哪一個(gè)應(yīng)用程序;

例如HTTP應(yīng)用程序的默認(rèn)端口就是80,也可以自定義端口;

3.網(wǎng)絡(luò)層:網(wǎng)絡(luò)層的主要工作是定義網(wǎng)絡(luò)IP地址,區(qū)分網(wǎng)段,邏輯尋址和在不同的公共網(wǎng)絡(luò)之間進(jìn)行路由選擇

網(wǎng)絡(luò)層的通信視野是全局的,它從源IP地址出發(fā),最終要到達(dá)目的IP地址,中間可能經(jīng)過(guò)無(wú)數(shù)個(gè)不同的網(wǎng)絡(luò)(例如以太網(wǎng)、Wi-Fi、4G LTE等),它管的是“全局”的事情;

例如下圖中紅框所標(biāo)注的網(wǎng)絡(luò)單元中的網(wǎng)絡(luò)路由選擇,就是靠網(wǎng)絡(luò)層實(shí)現(xiàn)的:

wKgZPGl5xPmAJk2tAALsx6pVQ7A125.png

4. 數(shù)據(jù)鏈路層:數(shù)據(jù)鏈路層的主要工作是在本地局域網(wǎng)內(nèi)將數(shù)據(jù)發(fā)送給接收方;

可以是帶交換機(jī)功能的WiFi路由器和這個(gè)WiFi下的設(shè)備相互發(fā)送數(shù)據(jù),或者這個(gè)WiFi路由器下的兩個(gè)設(shè)備相互發(fā)送數(shù)據(jù);

也可以是以太網(wǎng)交換機(jī)和這個(gè)交換機(jī)下的設(shè)備相互發(fā)送數(shù)據(jù),或者這個(gè)交換機(jī)下的兩個(gè)設(shè)備相互發(fā)送數(shù)據(jù);

也可以是4G網(wǎng)絡(luò)中,某個(gè)運(yùn)營(yíng)商基站和這個(gè)基站下的設(shè)備(例如手機(jī))相互發(fā)送數(shù)據(jù);

本地局域網(wǎng)的數(shù)據(jù)鏈路層也需要尋址,以太網(wǎng)和WiFi網(wǎng)絡(luò)環(huán)境中,需要用到設(shè)備的MAC地址進(jìn)行尋址;4G網(wǎng)絡(luò)中,需要用到RNTI(無(wú)線網(wǎng)絡(luò)臨時(shí)標(biāo)識(shí)符)進(jìn)行尋址;

數(shù)據(jù)鏈路層的通信視野是局部的,只負(fù)責(zé)局域網(wǎng)內(nèi)將數(shù)據(jù)發(fā)送給接收方,它管的是“局部”的事情;

例如下圖中紅框所標(biāo)注的網(wǎng)絡(luò)單元中的局域網(wǎng)內(nèi)的尋址,就是靠數(shù)據(jù)鏈路層實(shí)現(xiàn)的:

wKgZO2l5xSOANGCKAALwg7FK6gA151.png

5. 物理層:物理層的主要工作是傳輸0和1的電信號(hào),這些電信號(hào)通過(guò)物理傳輸介質(zhì)進(jìn)行傳輸;

常見(jiàn)的物理層傳輸介質(zhì)有:

(1) 光纖(我們?nèi)粘I钪锌梢越佑|到的就是,運(yùn)營(yíng)商將光纖直接從運(yùn)營(yíng)商機(jī)房鋪設(shè)到用戶家中,提供百兆、千兆的高速互聯(lián)網(wǎng)接入。你家辦理的中國(guó)電信、聯(lián)通或移動(dòng)的“千兆光網(wǎng)”。你家的“光貓”就是接收光信號(hào)并將其轉(zhuǎn)換為電信號(hào)的設(shè)備。)

(2) 雙絞線(例如在以太網(wǎng)網(wǎng)絡(luò)環(huán)境中常用的網(wǎng)線就是雙絞線的一種)

(3) 無(wú)線電波(例如Wi-Fi、4G、5G網(wǎng)絡(luò)都必須依賴無(wú)線電波作為載體才能進(jìn)行通信。它們本質(zhì)上都是通過(guò)調(diào)制解調(diào)技術(shù),將數(shù)字信號(hào)(0和1)加載到無(wú)線電波上發(fā)射出去,接收端再解調(diào)回來(lái))

不同的物理層傳輸介質(zhì),決定了電信號(hào)(0和1)的傳輸方式,物理介質(zhì)的不同決定了電信號(hào)的傳輸帶寬、速率、傳輸距離以及抗干擾性等等。

例如下圖中紅框所標(biāo)注的網(wǎng)絡(luò)單元間的數(shù)據(jù)傳輸,就是靠物理層實(shí)現(xiàn)的:

wKgZO2l5xUyAMhm-AALo2sZfs3U023.png

TCP/IP協(xié)議的上面四層(應(yīng)用層,傳輸層,網(wǎng)絡(luò)層,數(shù)據(jù)鏈路層),可以理解為是軟件層面的實(shí)現(xiàn),最終封裝成數(shù)據(jù)包;

而TCP/IP協(xié)議的最下面一層(物理層)將數(shù)據(jù)包轉(zhuǎn)化為 0 和 1 的電信號(hào),通過(guò)物理介質(zhì)進(jìn)行傳輸才能到達(dá)下一個(gè)網(wǎng)絡(luò)單元,因此物理介質(zhì)可以認(rèn)為是網(wǎng)絡(luò)通信的基石。

大家現(xiàn)在對(duì)每一層的功能先有一個(gè)總體認(rèn)識(shí)即可,不用關(guān)注細(xì)節(jié);

后續(xù)會(huì)有各種網(wǎng)絡(luò)環(huán)境下的實(shí)例來(lái)進(jìn)一步說(shuō)明如何工作;

2.3.2 數(shù)據(jù)封裝/解封裝

理解了功能分層的概念之后,我們?cè)賮?lái)看下面這張圖片,了解一下數(shù)據(jù)的封裝和解封裝;

wKgZPGl5xYuAQjcNAAJILH8YQLc550.pngwKgZO2l5xaaAG7kZAAaVfY_FBl4758.png

1、在數(shù)據(jù)發(fā)送端,應(yīng)用層的網(wǎng)絡(luò)協(xié)議生成應(yīng)用數(shù)據(jù);

2、應(yīng)用數(shù)據(jù)向下傳,交給傳輸層,增加了傳輸層的頭部信息,在頭部信息中,有很多字段,其中有兩個(gè)字段分別是源端口號(hào)和目標(biāo)端口號(hào),這兩個(gè)端口號(hào)的作用是:定義了發(fā)送端和接收端的應(yīng)用程序,例如http應(yīng)用的默認(rèn)端口號(hào)是80;可以提供兩個(gè)主機(jī)之上端到端的通信;

3、傳輸層頭部+應(yīng)用數(shù)據(jù)向下傳,交給網(wǎng)絡(luò)層,增加了網(wǎng)絡(luò)層的頭部信息,在頭部信息中,有很多字段,其中有兩個(gè)字段分別是源IP地址和目標(biāo)IP地址,這兩個(gè)IP地址的作用是:定義了發(fā)送端和接收端的網(wǎng)絡(luò)設(shè)備地址;可以提供主機(jī)到主機(jī)的通信;

4、網(wǎng)絡(luò)層頭部+傳輸層頭部+應(yīng)用數(shù)據(jù)向下傳,交給數(shù)據(jù)鏈路層,增加了數(shù)據(jù)鏈路層的頭部信息;

5、最終,數(shù)據(jù)鏈路層頭部+網(wǎng)絡(luò)層頭部+傳輸層頭部+應(yīng)用數(shù)據(jù)的數(shù)據(jù)包,通過(guò)物理層轉(zhuǎn)換為0和1的電信號(hào),然后通過(guò)物理傳輸介質(zhì)發(fā)給了接收端;

6、接收端收到數(shù)據(jù)后,從下到上,依次解析并且剝離出數(shù)據(jù)鏈路層頭部、網(wǎng)絡(luò)層頭部、傳輸層頭部,最終將應(yīng)用數(shù)據(jù)交給應(yīng)用程序去處理;

7、接收端處理完應(yīng)用數(shù)據(jù)后,如果需要返回應(yīng)用數(shù)據(jù)給發(fā)送端;此時(shí)發(fā)送端和接收端的角色互換,再走一遍數(shù)據(jù)分層的封裝和解封裝過(guò)程;

了解了功能分層和數(shù)據(jù)封裝/解封裝的核心工作原理之后,大家可能對(duì)TCP/IP網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)睦斫膺€是比較模糊,因?yàn)閯偛耪f(shuō)的這些都是偏理論的東西,理解起來(lái)不是那么直觀;

接下來(lái)我使用電腦的網(wǎng)絡(luò)瀏覽器訪問(wèn)http://airtest.openluat.com/,抓取一個(gè)完整的數(shù)據(jù)包封裝實(shí)例,再來(lái)加深一下對(duì)功能分層和數(shù)據(jù)封裝/解封裝的理解:

wKgZPGl5xhOAPemfAAJRXeTanx4567.png

接下來(lái)我們打開(kāi)下面這張圖片,實(shí)際分析一下http請(qǐng)求數(shù)據(jù)包

wKgZPGl5xj6AFMJLAAdoxCY2SDs242.png

通過(guò)上面這個(gè)http請(qǐng)求的網(wǎng)絡(luò)數(shù)據(jù)包分析,大家對(duì) TCP/IP的功能分層以及數(shù)據(jù)封裝/解封裝 應(yīng)該有了進(jìn)一步的認(rèn)識(shí);

2.4 不同網(wǎng)絡(luò)環(huán)境下的TCP/IP工作實(shí)例

講到這里,不知道大家有沒(méi)有發(fā)現(xiàn),之前講述的網(wǎng)絡(luò)模型,網(wǎng)絡(luò)數(shù)據(jù)包分析,我使用的都是極度簡(jiǎn)化后的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu),只有一個(gè)網(wǎng)絡(luò)硬件單元或者兩個(gè)網(wǎng)絡(luò)硬件單元;

但是在現(xiàn)實(shí)世界中,網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)不可能如此簡(jiǎn)單,從源設(shè)備到目標(biāo)設(shè)備之間,可能要經(jīng)過(guò)幾十個(gè)網(wǎng)絡(luò)硬件單元;

接下來(lái),我分別以4G網(wǎng)絡(luò)環(huán)境、WiFi網(wǎng)絡(luò)環(huán)境和以太網(wǎng)網(wǎng)絡(luò)環(huán)境為例,來(lái)說(shuō)明一個(gè)實(shí)例:

當(dāng)使用手機(jī)或者電腦訪問(wèn)https://docs.openluat.com/這個(gè)網(wǎng)站時(shí),在整個(gè)TCP/IP網(wǎng)絡(luò)環(huán)境中,有哪些重要的網(wǎng)絡(luò)硬件單元在配合工作?這些網(wǎng)絡(luò)硬件單元之上各自分別實(shí)現(xiàn)了TCP/IP協(xié)議的哪幾層?這些網(wǎng)絡(luò)硬件單元的核心作用分別是什么?

為了方便理解,接下來(lái)的每個(gè)實(shí)例中都會(huì)給出一個(gè)總體的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)圖,此處給出的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)圖和之前的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)圖相比,會(huì)更加詳細(xì),但是所給出的仍然是是簡(jiǎn)化后的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)圖;

雖然也是簡(jiǎn)化后的拓?fù)鋱D,但是這里所描述的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)圖,對(duì)于我們理解整個(gè)網(wǎng)絡(luò)系統(tǒng)的工作流程,也會(huì)提供很大的幫助;可以讓我們從一個(gè)全局的視野,去理解TCP/IP是如何在整個(gè)網(wǎng)絡(luò)系統(tǒng)中配合工作的;

2.4.1 4G網(wǎng)絡(luò)環(huán)境下TCP/IP協(xié)議的工作實(shí)例

第一種實(shí)例:使用中國(guó)移動(dòng)4G手機(jī)卡網(wǎng)絡(luò)的手機(jī)訪問(wèn)托管在中國(guó)電信的服務(wù)器

我們打開(kāi)下面這張圖總體了解一下這個(gè)過(guò)程

wKgZPGl5xziAL-dcAAj63FyzZTI187.png

第二種實(shí)例:使用中國(guó)移動(dòng)4G手機(jī)卡網(wǎng)絡(luò)的手機(jī)訪問(wèn)托管在中國(guó)移動(dòng)的服務(wù)器

和 中國(guó)移動(dòng)4G手機(jī)卡的手機(jī)訪問(wèn)托管在中國(guó)電信的服務(wù)器 相比,中國(guó)移動(dòng)4G手機(jī)卡的手機(jī)訪問(wèn)托管在中國(guó)移動(dòng)的服務(wù)器,不需要經(jīng)過(guò)中國(guó)移動(dòng)和邊界路由器和中國(guó)電信邊界路由器,在中國(guó)移動(dòng)的地市、省干、國(guó)干核心路由器之間進(jìn)行路由轉(zhuǎn)發(fā),如下圖所示(差異部分已通過(guò)淺綠色背景進(jìn)行區(qū)分):

wKgZO2l5x_CAdD88AAdhxn8Nj_Y872.png

2.4.2 WiFi網(wǎng)絡(luò)環(huán)境下TCP/IP協(xié)議的工作實(shí)例

第一種實(shí)例:使用中國(guó)移動(dòng)WIFI網(wǎng)絡(luò)的手機(jī)訪問(wèn)托管在中國(guó)電信的服務(wù)器

wKgZPGl5yF6AAM02AAjKRtN3NP0987.png

第二種實(shí)例:使用中國(guó)移動(dòng)WiFi網(wǎng)絡(luò)的手機(jī)訪問(wèn)托管在中國(guó)移動(dòng)的服務(wù)器

和 中國(guó)移動(dòng)WiFi網(wǎng)絡(luò)的手機(jī)訪問(wèn)托管在中國(guó)電信的服務(wù)器 相比,中國(guó)移動(dòng)4G手機(jī)卡的手機(jī)訪問(wèn)托管在中國(guó)移動(dòng)的服務(wù)器,不需要經(jīng)過(guò)中國(guó)移動(dòng)和邊界路由器和中國(guó)電信邊界路由器,在中國(guó)移動(dòng)的地市、省干、國(guó)干核心路由器之間進(jìn)行路由轉(zhuǎn)發(fā),如下圖所示(差異部分已通過(guò)淺綠色背景進(jìn)行區(qū)分):

wKgZO2l5yKqAFwO_AAeE5U79Rlk493.png

2.4.3 以太網(wǎng)網(wǎng)絡(luò)環(huán)境下TCP/IP協(xié)議的工作實(shí)例

第一種實(shí)例:使用中國(guó)移動(dòng)以太網(wǎng)網(wǎng)絡(luò)的電腦訪問(wèn)托管在中國(guó)電信的服務(wù)器

wKgZO2l5yQmAOTcAAAkei2pd9S8231.png

第二種實(shí)例:使用中國(guó)移動(dòng)以太網(wǎng)網(wǎng)絡(luò)的電腦訪問(wèn)托管在中國(guó)移動(dòng)的服務(wù)器

和 中國(guó)移動(dòng)WiFi網(wǎng)絡(luò)的電腦訪問(wèn)托管在中國(guó)電信的服務(wù)器 相比,中國(guó)移動(dòng)以太網(wǎng)的電腦訪問(wèn)托管在中國(guó)移動(dòng)的服務(wù)器,不需要經(jīng)過(guò)中國(guó)移動(dòng)和邊界路由器和中國(guó)電信邊界路由器,在中國(guó)移動(dòng)的地市、省干、國(guó)干核心路由器之間進(jìn)行路由轉(zhuǎn)發(fā),如下圖所示(差異部分已通過(guò)淺綠色背景進(jìn)行區(qū)分):

wKgZPGl5yVKAcHibAAfEZw3t5Fg849.png

三、LuatOS上的TCP/IP協(xié)議棧總體介紹

在總體了解了TCP/IP的核心理論知識(shí),以及不同網(wǎng)絡(luò)環(huán)境下的TCP/IP工作實(shí)例之后,大家對(duì)TCP/IP應(yīng)該具備了一個(gè)總體的認(rèn)識(shí);

接下來(lái)我們一起看下LuatOS上對(duì)TCP/IP協(xié)議棧的支持情況,以及提供了哪些編程接口給LuatOS項(xiàng)目應(yīng)用腳本來(lái)使用,參考下表:

wKgZPGl5yduAKukKAAINrjmY47s500.png

四、TCP/UDP/SSL/證書(shū)以及socket概念

經(jīng)過(guò)上一節(jié)的學(xué)習(xí),大家對(duì)LuatOS上TCP/IP網(wǎng)絡(luò)應(yīng)用的總體支持情況,應(yīng)該有了一個(gè)總體的認(rèn)識(shí);

因?yàn)槲覀儽局v課程是要講解LuatOS socket,所以從本節(jié)開(kāi)始,我們重點(diǎn)學(xué)習(xí)一下和socket有關(guān)的理論知識(shí)和實(shí)踐方法;

先簡(jiǎn)單地看一下socket的概念:

socket是TCP/IP提供的網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)的編程接口,包含地址、端口、傳輸層/安全層協(xié)議 三部分;

地址比較好理解,可以是域名地址,也可以是ip地址,用來(lái)標(biāo)識(shí)網(wǎng)絡(luò)上的一臺(tái)設(shè)備;

端口也比較好理解,在socket應(yīng)用中,服務(wù)器端的端口一般都是服務(wù)器自定義的,用來(lái)標(biāo)識(shí)自定義的應(yīng)用;

傳輸層/安全層協(xié)議包括TCP/UDP/SSL/證書(shū)的知識(shí),這一部分知識(shí)有點(diǎn)兒復(fù)雜,接下來(lái)我們重點(diǎn)看下TCP/UDP/SSL/證書(shū)的一些理論知識(shí);

4.1 TCP/UDP

先來(lái)看一張TCP/UDP的對(duì)比表格:

wKgZO2l5yliAPLFrAAAiI5_lbM8434.png

TCP 提供了面向連接的、可靠的、支持流量控制的傳輸層服務(wù);

UDP 提供了無(wú)連接的、不可靠的、不支持流量控制的傳輸層服務(wù);

4.1.1 是否面向連接

TCP的“面向連接”不僅僅是一個(gè)形式,而是實(shí)現(xiàn)其所有可靠性保障的基礎(chǔ)。它的作用可以概括為:為后續(xù)可靠、有序的數(shù)據(jù)傳輸做好必要的準(zhǔn)備工作和管理工作。

具體來(lái)說(shuō),它的作用體現(xiàn)在以下兩個(gè)關(guān)鍵階段:

1.建立連接(三次握手)

在發(fā)送任何實(shí)際應(yīng)用數(shù)據(jù)之前,客戶端和服務(wù)器必須通過(guò)三次握手建立一個(gè)雙向的通信通道;

過(guò)程:

  • SYN (Synchronize Sequence Numbers): 客戶端發(fā)送一個(gè)SYN包(一個(gè)特殊的TCP報(bào)文)到服務(wù)器,并帶上自己的初始序列號(hào)(Seq = x)。意思是:“你好,我想和你建立連接。我這邊數(shù)據(jù)的起始編號(hào)是x?!?/li>
  • SYN-ACK: 服務(wù)器收到后,如果同意連接,會(huì)發(fā)送一個(gè)SYN-ACK包。其中包含:
  • ACK = x + 1: “你剛才發(fā)的序列號(hào)x我收到了,我期待你下一個(gè)數(shù)據(jù)包的序列號(hào)是x+1?!保ㄟ@是對(duì)客戶端SYN的確認(rèn))
  • 同時(shí),服務(wù)器也發(fā)送自己的初始序列號(hào)(Seq = y)。意思是:“我也同意建立連接。我這邊數(shù)據(jù)的起始編號(hào)是y?!?/li>
  • ACK: 客戶端收到服務(wù)器的SYN-ACK后,再發(fā)送一個(gè)ACK包(ACK = y + 1)給服務(wù)器。意思是:“你發(fā)的序列號(hào)y我也收到了,我期待你下一個(gè)數(shù)據(jù)包的序列號(hào)是y+1?!?/li>

抓包分析:

  • TCP/UDP web測(cè)試工具:創(chuàng)建TCP Server;
  • SSCOM:使用SSCOM提供的TCP Client工具; 或者 LLCOM:使用LLCOM提供的socket客戶端工具(支持TLS)
  • 網(wǎng)絡(luò)抓包工具:wireshark,這個(gè)工具的用法,在這里就不講了,大家如果有不懂的,上網(wǎng)自行學(xué)習(xí);
  • Client連接Server之后,在wireshark中過(guò)濾搜索 ip.addr == XXX && tcp.port == YYY,XXX為服務(wù)器ip地址,YYY為服務(wù)器端口,例如ip.addr == 112.125.89.8 && tcp.port == 47082

下面我們對(duì)一個(gè)TCP連接成功的網(wǎng)絡(luò)包進(jìn)行分析:

wKgZO2l5y1CAFNoSAAEf_Rn82-8719.pngwKgZO2l5y3iACZYbAAGbGgufWi4126.png

下面我們對(duì)一個(gè)TCP連接失敗的網(wǎng)絡(luò)包進(jìn)行分析,客戶端去連接一個(gè)不存在的服務(wù)器:

wKgZPGl5y6mAY6svAAGJrfKpCXw802.png

作用:

  • 交換初始序列號(hào) (ISN): 這是最核心的作用。序列號(hào)是TCP實(shí)現(xiàn)可靠性(確認(rèn)、重傳、排序)的根基。雙方通過(guò)握手告知對(duì)方自己將從哪個(gè)號(hào)碼開(kāi)始編號(hào)字節(jié)數(shù)據(jù)。
  • 確認(rèn)雙方通信能力: 證明客戶端和服務(wù)器之間的網(wǎng)絡(luò)路徑在兩個(gè)方向上(Client->Server 和 Server->Client)都是通的。如果握手失敗,說(shuō)明根本沒(méi)法通信,應(yīng)用層會(huì)立刻得到錯(cuò)誤信息,而不用等待數(shù)據(jù)傳輸超時(shí)。
  • 分配資源: 在握手成功后,雙方的操作系統(tǒng)都會(huì)為這個(gè)連接分配資源,如創(chuàng)建socket、分配發(fā)送和接收緩沖區(qū)等。如果連接無(wú)法建立,就避免了資源的浪費(fèi)。

2.終止連接(四次揮手)

過(guò)程:

  • 一方發(fā)送FIN包,表示“我數(shù)據(jù)發(fā)完了,要關(guān)閉我到你方向的連接”。
  • 另一方ACK這個(gè)FIN包,表示“我知道你要關(guān)了”。
  • 可能另一方向也還有數(shù)據(jù)要發(fā)送,等發(fā)完后,它再發(fā)送一個(gè)FIN包。
  • 最初的一方再ACK這個(gè)FIN包。

抓包分析:

wKgZO2l5zC-AJzZbAADHmSYMAQ0285.png

作用:

可靠地釋放資源: 確保雙方都知道通信即將結(jié)束,可以安全地釋放為這個(gè)連接分配的所有內(nèi)核資源(TCB、緩沖區(qū)等)。

保證數(shù)據(jù)完整性: 確保在連接關(guān)閉前,所有在途的數(shù)據(jù)包都已經(jīng)被正確處理完畢。防止一方以為連接已斷而另一方還在發(fā)送數(shù)據(jù)的情況。

而UDP呢?提供的是一個(gè)無(wú)連接的傳輸層服務(wù),意思就是在正式發(fā)送應(yīng)用數(shù)據(jù)之前,客戶端和服務(wù)端沒(méi)有三次握手連接,客戶端和服務(wù)器端之間沒(méi)有網(wǎng)絡(luò)數(shù)據(jù)交互,如下圖所示:

wKgZO2l5zGuAIaHbAAJGW-JFi8U948.png

同理,因?yàn)榫蜎](méi)有連接動(dòng)作,所以UDP斷開(kāi)時(shí),也沒(méi)有四次揮手的斷開(kāi)連接動(dòng)作;

4.1.2 是否可靠

TCP 提供的是一種可靠的傳輸層服務(wù);TCP 通過(guò)多種機(jī)制確保數(shù)據(jù)準(zhǔn)確無(wú)誤地送達(dá):

1、確認(rèn)應(yīng)答機(jī)制 (ACK): 接收方收到數(shù)據(jù)后,會(huì)發(fā)送一個(gè)確認(rèn)報(bào)文(ACK)給發(fā)送方。

2、超時(shí)重傳機(jī)制: 發(fā)送方在發(fā)送一個(gè)數(shù)據(jù)段后啟動(dòng)一個(gè)定時(shí)器。如果在規(guī)定時(shí)間內(nèi)沒(méi)有收到對(duì)應(yīng)的ACK,它會(huì)重新發(fā)送該數(shù)據(jù)段。

3、序列號(hào)和確認(rèn)號(hào)機(jī)制: 每個(gè)字節(jié)的數(shù)據(jù)都被分配一個(gè)序列號(hào)(Seq),ACK號(hào)則告訴發(fā)送方“我期望收到的下一個(gè)字節(jié)的序列號(hào)是多少”。這解決了數(shù)據(jù)包亂序和重復(fù)的問(wèn)題。

4、校驗(yàn)和機(jī)制: 每個(gè)數(shù)據(jù)包都包含一個(gè)校驗(yàn)和。接收方會(huì)驗(yàn)證它,如果校驗(yàn)失敗則丟棄該包,從而觸發(fā)發(fā)送方的重傳機(jī)制。

wKgZPGl5zPSAbjayAAGgXJ_IXPE631.pngwKgZO2l5zQuAX5UAAAMiCW9rVFM652.png

而UDP沒(méi)有這些可靠的機(jī)制,我們看一下UDP發(fā)送數(shù)據(jù)的網(wǎng)絡(luò)包:

wKgZPGl5zUWADPmVAAFsLzSF5XA546.pngwKgZPGl5zV2AGJ1gAAKc0SbsDBc150.png

和TCP相比,UDP數(shù)據(jù)發(fā)送出去之后,沒(méi)有機(jī)制確認(rèn)數(shù)據(jù)是否發(fā)送成功;在網(wǎng)絡(luò)不穩(wěn)定的情況下,會(huì)出現(xiàn)丟失數(shù)據(jù)的問(wèn)題;

4.1.3 是否支持流量控制

TCP 提供的是一種支持流量控制的傳輸層服務(wù);TCP 通過(guò)滑動(dòng)窗口協(xié)議確保數(shù)據(jù)準(zhǔn)確無(wú)誤地送達(dá):

使用滑動(dòng)窗口協(xié)議來(lái)防止發(fā)送方發(fā)送數(shù)據(jù)過(guò)快,導(dǎo)致接收方緩沖區(qū)溢出。

接收方在ACK中會(huì)告知發(fā)送方自己當(dāng)前剩余的緩沖區(qū)大?。ù翱诖笮。l(fā)送方根據(jù)這個(gè)窗口大小調(diào)整發(fā)送速率。

wKgZPGl5zY6ACdFCAAWHyrh95Nw120.pngwKgZO2l5zaaASYSsAAf02kX3ILY954.png

下面的例子是一個(gè)出現(xiàn)0窗口的網(wǎng)絡(luò)包,因?yàn)槲疫@邊沒(méi)有環(huán)境復(fù)現(xiàn)這個(gè)問(wèn)題,所以從網(wǎng)上找了一張圖片,給大家看一下:

wKgZPGl5zcaAKBmRAAMiQdOx7_E996.png

而UDP是沒(méi)有ACK機(jī)制的,所以也沒(méi)有窗口控制協(xié)議;

4.2 數(shù)字證書(shū)

4.2.1 數(shù)字證書(shū)是什么?

數(shù)字證書(shū),是一種數(shù)字文件,其核心作用類似于現(xiàn)實(shí)世界中的身份證或營(yíng)業(yè)執(zhí)照。

它的根本目的是:將一個(gè)數(shù)字證書(shū)中的公鑰與一個(gè)實(shí)體(個(gè)人、設(shè)備、組織、域名)的身份信息進(jìn)行強(qiáng)綁定,并由一個(gè)受信任的第三方進(jìn)行擔(dān)保。

簡(jiǎn)單來(lái)說(shuō),數(shù)字證書(shū)就是證明“這個(gè)公鑰確實(shí)屬于某某某” 的電子憑證。

4.2.2 為什么需要數(shù)字證書(shū)?

要理解證書(shū)的價(jià)值,必須先理解它要解決的問(wèn)題:中間人攻擊。

  • 當(dāng)客戶端(如瀏覽器)訪問(wèn)一個(gè)服務(wù)器時(shí),如果一個(gè)攻擊者攔截了通信,他可以將自己的數(shù)字證書(shū)(包含公鑰)發(fā)送給客戶端,并冒充服務(wù)器。
  • 客戶端用攻擊者的公鑰加密數(shù)據(jù)。
  • 攻擊者截獲數(shù)據(jù),用自己的私鑰解密,竊取信息。
  • 攻擊者再用服務(wù)器的真實(shí)公鑰加密數(shù)據(jù),轉(zhuǎn)發(fā)給服務(wù)器。整個(gè)過(guò)程神不知鬼不覺(jué)。

核心問(wèn)題:如何確保你拿到的服務(wù)器的證書(shū)公鑰,確實(shí)來(lái)自你真正想通信的一方,而不是攻擊者?

數(shù)字證書(shū)就是答案。它由一個(gè)受信任的第三方機(jī)構(gòu)(Certificate Authority, CA)對(duì)公鑰和身份信息進(jìn)行簽名,任何信任該CA的人都可以驗(yàn)證這張證書(shū)的真?zhèn)危瑥亩湃纹渲械墓€。

4.2.3 數(shù)字證書(shū)里包含什么?(X.509標(biāo)準(zhǔn))

數(shù)字證書(shū)遵循X.509標(biāo)準(zhǔn)格式。它包含以下核心信息:

  • 基本身份信息(證書(shū)主體)
  • 版本號(hào):使用的X.509版本(如v3)。
  • 序列號(hào):由CA分配的唯一標(biāo)識(shí)符,用于吊銷查詢。
  • 簽名算法:CA簽發(fā)此證書(shū)時(shí)使用的算法(如SHA256withRSA)。
  • 頒發(fā)者:簽發(fā)此證書(shū)的證書(shū)頒發(fā)機(jī)構(gòu)(CA) 的名稱。
  • 有效期:證書(shū)有效的起止日期和時(shí)間。證書(shū)在此時(shí)間窗口外無(wú)效。
  • 主題:證書(shū)持有者的身份信息。最重要的是通用名稱(Common Name, CN),通常是域名(如 docs.openluat.com)。
  • 核心密碼學(xué)材料
  • 公鑰本身(一串很長(zhǎng)的數(shù)字)。
  • 該公鑰所使用的算法(如RSA 2048位、ECC)。
  • 信任的證明(CA的簽名)
  • 數(shù)字簽名:這是最關(guān)鍵的部分。首先對(duì)上述所有信息(除了簽名本身)計(jì)算一個(gè)哈希摘要,然后對(duì)這個(gè)摘要使用CA自己的私鑰進(jìn)行加密,得到的結(jié)果就是數(shù)字簽名。

我們現(xiàn)在訪問(wèn)docs.openluat.com,看下docs網(wǎng)站的數(shù)字證書(shū):

wKgZO2l5zr-AHVa4AAERZSbuFbE039.pngwKgZO2l5ztGAVFfPAACCm6Ow0yk308.png

點(diǎn)擊docs.openluat.com的證書(shū)文件的每個(gè)字段,我們來(lái)對(duì)照說(shuō)明一下;

4.2.4 數(shù)字證書(shū)的工作原理:信任鏈(Chain of Trust)

數(shù)字證書(shū)的信任并非憑空產(chǎn)生,它依賴于一個(gè)層級(jí)化的信任模型,稱為公鑰基礎(chǔ)設(shè)施(Public Key Infrastructure, PKI)。

4.2.4.1 信任鏈的組成:

  1. 根證書(shū)(Root CA Certificate)
  2. 位于信任鏈頂端的、自簽名的證書(shū)。
  3. 它們的公鑰被預(yù)先內(nèi)置在操作系統(tǒng)(如Windows、macOS)和瀏覽器(如Chrome、Firefox)的信任根證書(shū)存儲(chǔ)區(qū)中。這是所有信任的起點(diǎn)。
  4. 根CA的私鑰被極其嚴(yán)格地離線保管,幾乎不直接用于簽發(fā)服務(wù)器證書(shū)。
  5. 中間證書(shū)
  6. 由根CA簽發(fā),用于代表根CA去實(shí)際簽發(fā)最終的用戶證書(shū)。
  7. 這種層級(jí)結(jié)構(gòu)增加了安全性:即使中間CA的私鑰被泄露,可以迅速吊銷該中間證書(shū),而根CA依然安全,無(wú)需重建整個(gè)信任體系。
  8. 一個(gè)服務(wù)器證書(shū)通常伴隨著一個(gè)或多個(gè)中間證書(shū)。
  9. 終端實(shí)體證書(shū)
  10. 也就是我們通常為網(wǎng)站、服務(wù)申請(qǐng)和使用的證書(shū)。

如下圖所示,docs.openluat.com服務(wù)器使用就是一個(gè)三層證書(shū)結(jié)構(gòu):

wKgZPGl5z2-AEO2BAADldhS1SpY249.png

4.2.4.2 證書(shū)驗(yàn)證過(guò)程(以瀏覽器訪問(wèn)https://docs.openluat.com網(wǎng)站為例):

當(dāng)瀏覽器收到網(wǎng)站的證書(shū)時(shí),它會(huì)執(zhí)行以下驗(yàn)證步驟:

1. 驗(yàn)證基本信息:檢查證書(shū)的有效期是否當(dāng)前時(shí)間在內(nèi),檢查證書(shū)的“主題”或“SAN”字段是否包含正

wKgZPGl5z56AGzIlAAJfEhoxk3I061.png

2. 驗(yàn)證簽名(構(gòu)建信任鏈):

  • 瀏覽器使用中間證書(shū)A里的公鑰,去解密網(wǎng)站證書(shū)的數(shù)字簽名,得到一個(gè)哈希值H1。
  • 瀏覽器對(duì)網(wǎng)站證書(shū)的內(nèi)容(除簽名外)用相同的哈希算法計(jì)算,得到另一個(gè)哈希值H2。
  • 如果H1 == H2,則說(shuō)明:
  • 網(wǎng)站證書(shū)的內(nèi)容完整,未被篡改。
  • 該證書(shū)確實(shí)是由中間證書(shū)A對(duì)應(yīng)的CA簽發(fā)的(因?yàn)橹挥杏弥虚gCA的私鑰才能生成能用其公鑰解開(kāi)的簽名)。

wKgZO2l5z_SAc8vRAADbSiE1vLs228.png


3. 遞歸驗(yàn)證:

  • 瀏覽器接著發(fā)現(xiàn),它可能不直接信任中間證書(shū)A。于是它繼續(xù)向上驗(yàn)證:使用根證書(shū)的公鑰,去驗(yàn)證中間證書(shū)A的簽名。
  • 因?yàn)楦C書(shū)的公鑰已經(jīng)內(nèi)置在瀏覽器的信任存儲(chǔ)中,且是自簽名的,驗(yàn)證到此結(jié)束。
wKgZO2l50DOALWwaAADWJ9afdDw540.png

4. 吊銷檢查:瀏覽器還會(huì)通過(guò)證書(shū)吊銷列表(CRL) 或在線證書(shū)狀態(tài)協(xié)議(OCSP) 查詢?cè)撟C書(shū)是否已被CA提前吊銷(例如因?yàn)樗借€泄露)。

5. 最終信任:所有步驟都通過(guò)后,瀏覽器才最終信任該網(wǎng)站證書(shū),并使用證書(shū)中的公鑰與服務(wù)器進(jìn)行加密通信;

數(shù)字證書(shū)的知識(shí),理解起來(lái)可能有點(diǎn)兒復(fù)雜,即使大家不了解關(guān)系也不大,最終在LuatOS socket編程中,如果用到證書(shū),使用起來(lái)會(huì)非常簡(jiǎn)單,在下文中我們會(huì)重點(diǎn)說(shuō)明如何使用;

4.3 SSL/TLS

4.3.1 什么是 SSL/TLS?

SSL(Secure Sockets Layer,安全套接層) 和 TLS(Transport Layer Security,傳輸層安全) 是加密協(xié)議,旨在為計(jì)算機(jī)網(wǎng)絡(luò)通信提供安全性和數(shù)據(jù)完整性。它們的核心目標(biāo)是建立一個(gè)安全的通信通道,防止竊聽(tīng)、篡改和消息偽造。

關(guān)系: TLS 是 SSL 的繼任者。由于歷史原因,兩者名稱經(jīng)?;煊?,但現(xiàn)在所有現(xiàn)代應(yīng)用都使用 TLS。SSL 3.0 及其早期版本已被發(fā)現(xiàn)存在嚴(yán)重漏洞(如 POODLE 攻擊)并被完全廢棄?,F(xiàn)在當(dāng)我們說(shuō)“SSL”時(shí),通常指的是 TLS。

主要目標(biāo):

1、加密(Encryption): 混淆傳輸?shù)臄?shù)據(jù),防止第三方竊聽(tīng)。

2、認(rèn)證(Authentication): 驗(yàn)證通信方的身份(通常是驗(yàn)證服務(wù)器的身份,也可選擇驗(yàn)證客戶端身份),防止中間人攻擊。

3、完整性(Integrity): 檢測(cè)數(shù)據(jù)在傳輸過(guò)程中是否被篡改或損壞。

4.3.2 為什么需要 SSL/TLS?

在沒(méi)有 SSL/TLS 的情況下,網(wǎng)絡(luò)通信(如 HTTP、FTP、SMTP)以純文本形式傳輸。這意味著在你和服務(wù)器之間的任何節(jié)點(diǎn)(如你的路由器、ISP、公共Wi-Fi熱點(diǎn))都可以看到你發(fā)送的所有內(nèi)容,包括密碼、信用卡號(hào)、私人消息等。SSL/TLS 通過(guò)在傳輸層之上建立一個(gè)加密層來(lái)解決這個(gè)問(wèn)題,從而保護(hù)上層應(yīng)用協(xié)議(如 HTTP→HTTPS)。

例如,如果一個(gè)TCP Client連接上一個(gè)TCP Server之后,如果TCP Client給Server發(fā)送數(shù)據(jù)LuatOS,在整個(gè)網(wǎng)絡(luò)傳輸過(guò)程中的任何節(jié)點(diǎn)(局域網(wǎng)的交換機(jī)和路由器,基站,服務(wù)網(wǎng)關(guān),數(shù)據(jù)網(wǎng)關(guān),核心路由器,邊界路由器)都能看到明文數(shù)據(jù)LuatOS,如下圖所示:

wKgZO2l50U6AUOP8AAPxb53k1MA266.png


如果在TCP之上支持了TLS,在傳輸數(shù)據(jù)之前,Client和Server會(huì)動(dòng)態(tài)協(xié)商一個(gè)密鑰,密鑰協(xié)商成功后,后續(xù)發(fā)送方傳輸?shù)膽?yīng)用數(shù)據(jù)都會(huì)通過(guò)密鑰加密,然后再傳輸?shù)浇邮辗?,接收方使用密鑰進(jìn)行解密;只有發(fā)送端和接收端的應(yīng)用程序才能加密數(shù)據(jù)以及解密為原始明文數(shù)據(jù),在網(wǎng)絡(luò)傳輸過(guò)程中,網(wǎng)絡(luò)中間節(jié)點(diǎn)因?yàn)椴恢烂荑€,即使截獲了數(shù)據(jù),因?yàn)闆](méi)有密鑰,也無(wú)法解密數(shù)據(jù),如下圖所示:

wKgZPGl50X6ACvoGAAK_h03M-7Q495.pngwKgZPGl50ZGAZQ-AAAZ_7CEFrh0375.png

4.3.3 SSL/TLS 如何工作?—— 握手過(guò)程詳解

SSL/TLS 的核心是其握手過(guò)程。這個(gè)過(guò)程在雙方開(kāi)始傳輸實(shí)際應(yīng)用數(shù)據(jù)之前進(jìn)行,目的是協(xié)商連接參數(shù)、驗(yàn)證身份并生成會(huì)話密鑰。以下是TLS 1.2 握手流程:

整個(gè)過(guò)程的目標(biāo)是在客戶端和服務(wù)器之間安全地協(xié)商出兩樣?xùn)|西:

1、會(huì)話密鑰(Session Keys):用于后續(xù)通信使用的對(duì)稱加密密鑰。

2、加密參數(shù):使用哪種對(duì)稱加密算法(如 AES)、哪種哈希算法(如 SHA256)等。

整個(gè)握手過(guò)程在 TCP 連接建立之后進(jìn)行,可以概括為以下四個(gè)主要階段和 10 個(gè)步驟:

wKgZO2l50eSAAD7LAAf-k3QVxgU919.png

第一階段:Hello 消息交換(協(xié)商安全參數(shù))

步驟 1: Client Hello

客戶端向服務(wù)器發(fā)起握手,發(fā)送一個(gè)Client Hello消息,包含以下關(guān)鍵信息:

  • 客戶端隨機(jī)數(shù)(Client Random):一個(gè)由客戶端生成的 32 字節(jié)隨機(jī)數(shù),用于后續(xù)生成主密鑰。
  • 支持的協(xié)議版本:例如TLS 1.2。
  • 支持的密碼套件列表(Cipher Suites):客戶端支持的所有加密算法組合的列表,按優(yōu)先級(jí)排序。例如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。
wKgZPGl50lWASZreAAf_Qp9dMRk001.png

步驟 2: Server Hello

服務(wù)器響應(yīng)客戶端的Hello消息,發(fā)送一個(gè)Server Hello消息,包含以下關(guān)鍵信息:

  • 服務(wù)器隨機(jī)數(shù)(Server Random):一個(gè)由服務(wù)器生成的 32 字節(jié)隨機(jī)數(shù),同樣用于生成主密鑰。
  • 選擇的協(xié)議版本:通常是雙方都支持的最高版本,例如TLS 1.2。
  • 選擇的密碼套件:從客戶端提供的列表中選出一個(gè)服務(wù)器也支持的套件,例如TLS_RSA_WITH_AES_128_CBC_SHA。
  • 會(huì)話ID(Session ID):服務(wù)器為本次會(huì)話生成的一個(gè)唯一ID,用于后續(xù)會(huì)話恢復(fù)。
  • 選擇的擴(kuò)展。

至此,雙方就使用哪種加密算法進(jìn)行通信達(dá)成了一致。

wKgZPGl50zGAeCulAAmO2UCABAQ360.png

第二階段:服務(wù)器認(rèn)證與密鑰交換(Server Key Exchange)

步驟 3: Server Certificate

服務(wù)器將自己的數(shù)字證書(shū)發(fā)送給客戶端。這個(gè)證書(shū)包含了服務(wù)器的公鑰、域名、頒發(fā)機(jī)構(gòu)(CA)等信息,并由CA的私鑰簽名。客戶端會(huì)驗(yàn)證該證書(shū)的有效性(是否過(guò)期、域名是否匹配、簽發(fā)者是否可信等),以確認(rèn)正在通信的確實(shí)是目標(biāo)服務(wù)器,而不是中間人。

步驟 4: Server Key Exchange Message(可選)

注意:此步驟僅在選擇的密碼套件不是RSA密鑰交換時(shí)才需要(例如使用DHE或ECDHE時(shí))。如果使用RSA套件(如本例),服務(wù)器會(huì)跳過(guò)這一步。 對(duì)于DHE/ECDHE套件,服務(wù)器會(huì)在此消息中發(fā)送其臨時(shí)密鑰交換參數(shù)(如迪菲-赫爾曼參數(shù)),并用證書(shū)對(duì)應(yīng)的私鑰簽名,以供客戶端驗(yàn)證。

步驟 5: Server Hello Done

服務(wù)器發(fā)送一個(gè)Server Hello Done消息,表示它已經(jīng)將所有初始協(xié)商信息發(fā)送完畢。

wKgZPGl505aAbrzHAAnHtr7QtlY637.png

第三階段:客戶端認(rèn)證與密鑰交換(Client Key Exchange)

步驟 6: Client Certificate(可選)

注意:此步驟僅在服務(wù)器要求對(duì)客戶端進(jìn)行認(rèn)證(例如銀行系統(tǒng)、API網(wǎng)關(guān)等場(chǎng)景)時(shí)才發(fā)生。絕大多數(shù) HTTPS 網(wǎng)站訪問(wèn)不需要這一步。 如果需要,服務(wù)器會(huì)在之前發(fā)送Certificate Request消息(本例未列出),然后客戶端在此步驟發(fā)送自己的證書(shū)。

步驟 7: Client Key Exchange Message

這是客戶端密鑰交換的核心步驟。客戶端會(huì)生成一個(gè) Pre-Master Secret(預(yù)主密鑰),這是一個(gè) 48 字節(jié)的隨機(jī)數(shù)。

  • 對(duì)于 RSA 套件:客戶端會(huì)用步驟 3 中收到的服務(wù)器證書(shū)里的公鑰加密這個(gè)Pre-Master Secret,然后將加密后的結(jié)果發(fā)送給服務(wù)器。
  • 對(duì)于 DHE/ECDHE 套件:客戶端會(huì)基于服務(wù)器的參數(shù),計(jì)算并發(fā)送自己的臨時(shí)密鑰交換參數(shù)。

至此,只有擁有對(duì)應(yīng)私鑰的服務(wù)器才能解密出Pre-Master Secret。

wKgZO2l50_aAXgA3AAaIiszgLO0745.png

步驟 8: Certificate Verify(可選)

如果客戶端發(fā)送了證書(shū)(步驟6),它還需要用其私鑰對(duì)之前所有握手消息的哈希值進(jìn)行簽名,并發(fā)送給服務(wù)器。服務(wù)器用客戶端證書(shū)中的公鑰驗(yàn)證這個(gè)簽名,以證明客戶端確實(shí)擁有該證書(shū)對(duì)應(yīng)的私鑰,完成了客戶端認(rèn)證。

第四階段:完成握手(Switch to Encryption)

此時(shí),客戶端和服務(wù)器已經(jīng)擁有了生成會(huì)話密鑰的所有材料:

  • Client Random
  • Server Random
  • Pre-Master Secret

雙方使用相同的偽隨機(jī)函數(shù)(PRF),根據(jù)這三個(gè)參數(shù)獨(dú)立計(jì)算出相同的:

  1. Master Secret(主密鑰)
  2. 最終用于加密和完整性驗(yàn)證的會(huì)話密鑰塊(Key Block),其中包含:
  3. 客戶端到服務(wù)器的對(duì)稱加密密鑰
  4. 服務(wù)器到客戶端的對(duì)稱加密密鑰
  5. 客戶端到服務(wù)器的MAC驗(yàn)證密鑰
  6. 服務(wù)器到客戶端的MAC驗(yàn)證密鑰

步驟 9: Change Cipher Spec

客戶端發(fā)送一個(gè)Change Cipher Spec消息。這是一個(gè)簡(jiǎn)單的信號(hào),通知服務(wù)器:“從現(xiàn)在開(kāi)始,我發(fā)送的所有消息都將使用我們剛剛協(xié)商好的加密算法和密鑰進(jìn)行加密。”

緊接著,客戶端發(fā)送Finished消息。這條消息本身已經(jīng)是加密狀態(tài),它包含之前所有握手消息的哈希值的MAC(消息認(rèn)證碼)。服務(wù)器收到后,會(huì)解密并驗(yàn)證這個(gè)MAC。如果驗(yàn)證成功,說(shuō)明:

  1. 客戶端計(jì)算出的密鑰與服務(wù)器的一致。
  2. 握手過(guò)程沒(méi)有被篡改。
wKgZPGl51PyAUKM4AAdCEzcR8YM359.png

步驟 10: Change Cipher Spec & Finished

服務(wù)器同樣發(fā)送Change Cipher Spec消息,通知客戶端:“我也準(zhǔn)備好了,后續(xù)消息將加密?!?/p>

緊接著,服務(wù)器發(fā)送加密后的Finished消息??蛻舳送瑯舆M(jìn)行解密和驗(yàn)證。

wKgZPGl51SaAHO7FAAVfL_wC4cE164.png

握手完成

至此,TLS 1.2 握手全部完成。一個(gè)安全的加密通道已經(jīng)建立。之后所有的應(yīng)用數(shù)據(jù)(HTTP請(qǐng)求/響應(yīng)等)都將使用協(xié)商出的對(duì)稱會(huì)話密鑰進(jìn)行加密和完整性保護(hù)。

4.3.4 TLS和TCP/UDP是什么關(guān)系?

TLS 運(yùn)行在 TCP 之上,為基于 TCP 的應(yīng)用提供安全;

而 TLS 本身不能直接運(yùn)行在 UDP 之上,但有其對(duì)應(yīng)的安全版本 DTLS;DTLS應(yīng)用沒(méi)有TLS廣泛,所以本講課程不再講述DTLS,大家有興趣可以自行上網(wǎng)學(xué)習(xí)了解;

我們?cè)賮?lái)看一下這張OSI七層模型 和 TCP/IP五層模型表格:

wKgZO2l51XCAWSWQAACvrByoYFs197.png

從這張表可以清晰地看到:

TCP/UDP 屬于傳輸層。它們的主要職責(zé)是建立主機(jī)到主機(jī)的連接,解決數(shù)據(jù)如何可靠(TCP)或高效(UDP)地送達(dá)的問(wèn)題。

TLS 大致對(duì)應(yīng)于表示層。它不關(guān)心數(shù)據(jù)如何送達(dá),它的職責(zé)是解決數(shù)據(jù)在送達(dá)后內(nèi)容是否安全的問(wèn)題,即加密、身份認(rèn)證和完整性驗(yàn)證。

一個(gè)非常恰當(dāng)?shù)谋扔鳎?/strong>

TCP 像是一個(gè)可靠的郵政服務(wù)。它確保你的信件(數(shù)據(jù)包)不丟失、不損壞、按順序投遞。

TLS 則像是給這封信件加上了一個(gè)防彈、防窺視、防篡改的保險(xiǎn)箱。郵政服務(wù)(TCP)只負(fù)責(zé)運(yùn)送保險(xiǎn)箱,并不關(guān)心也不知曉保險(xiǎn)箱里裝的是什么。只有擁有密鑰的收件人才能打開(kāi)保險(xiǎn)箱讀取里面的原始信件。

因此,TLS 強(qiáng)烈依賴于 TCP 的可靠性。TLS 握手本身包含多條消息交換,需要嚴(yán)格按順序到達(dá),任何丟包或亂序都會(huì)導(dǎo)致握手失敗,而這正是 TCP 所擅長(zhǎng)的。

4.4 socket概念

在了解了TCP/UDP/TLS/證書(shū)知識(shí)之后,大家可能覺(jué)得這些內(nèi)容太復(fù)雜了,如果在編程過(guò)程中,直接操作這么復(fù)雜的接口,簡(jiǎn)直是一個(gè)災(zāi)難!

這時(shí)socket就出現(xiàn)了,socket的中文名稱是套接字;

socket是TCP/IP提供的網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)的編程接口,包含地址、端口、傳輸層/安全層協(xié)議 三部分;

socket 是網(wǎng)絡(luò)應(yīng)用程序與網(wǎng)絡(luò)協(xié)議棧(TCP/IP棧)之間的橋梁,用戶可以直接使用socket api,而socket內(nèi)部設(shè)計(jì)會(huì)根據(jù)用戶的api配置選擇對(duì)應(yīng)的傳輸層和安全層協(xié)議,可以大大簡(jiǎn)化網(wǎng)絡(luò)編程工作量。

LuatOS上也支持socket編程接口,提供了socket核心庫(kù)和libnet擴(kuò)展庫(kù)兩個(gè)庫(kù)文件;


接下來(lái)我們重點(diǎn)看下這兩個(gè)庫(kù)的使用方法;

五、LuatOS上的socket核心庫(kù)

5.1 常量詳解

核心庫(kù)常量,顧名思義是由 LuatOS 內(nèi)核固件中定義的、不可重新賦值或修改的固定值,在腳本代碼中不需要聲明,可直接調(diào)用;

5.1.1 網(wǎng)絡(luò)適配器編號(hào):

注意:

1. 網(wǎng)絡(luò)適配器,它的一個(gè)更廣為人知的名字是——網(wǎng)卡,后續(xù)我們會(huì)使用網(wǎng)卡和網(wǎng)絡(luò)適配器這兩種名稱,大家只要知道這兩種名稱表示同一個(gè)概念就行了;

2. LuatOS上的網(wǎng)絡(luò)適配器和電腦上的網(wǎng)絡(luò)適配器的作用是完全一樣的,我們先來(lái)看一張電腦上的網(wǎng)絡(luò)適配器圖片

wKgZO2l51ySACAE4AADg8-g5sHk760.png

在上面這張圖片中,有WiFi網(wǎng)卡、標(biāo)準(zhǔn)的物理以太網(wǎng)卡、虛擬的USB RNDIS以太網(wǎng)卡三種網(wǎng)卡;

3. 從下面這張TCP/IP五層模型圖中,我們?cè)龠M(jìn)一步理解下網(wǎng)卡這個(gè)概念

wKgZO2l5126AUHRAAACKNkdo-Uk497.png

網(wǎng)卡主要實(shí)現(xiàn)的是 物理層 和 數(shù)據(jù)鏈路層 的功能;

物理層的主要功能包括:

  • 信號(hào)轉(zhuǎn)換:將數(shù)字比特流(0和1)和 能夠在物理傳輸介質(zhì)(網(wǎng)線、光纖、無(wú)線電波)上傳輸?shù)奈锢硇盘?hào)(如電信號(hào)、光信號(hào)、無(wú)線電波) 之間轉(zhuǎn)換;
  • 信號(hào)發(fā)送與接收:通過(guò)接口(RJ-45水晶頭、天線)向傳輸介質(zhì)上發(fā)送和接收這些物理信號(hào);

數(shù)據(jù)鏈路層的主要功能包括

  • MAC地址控制:

使用唯一的MAC地址或者RNTI標(biāo)識(shí)(4G網(wǎng)絡(luò)中使用)來(lái)標(biāo)識(shí)網(wǎng)卡,并處理幀的尋址問(wèn)題。網(wǎng)卡會(huì)檢查所有流過(guò)網(wǎng)絡(luò)的幀,只接收目標(biāo)MAC地址與自己地址匹配或?yàn)閺V播地址的幀,丟棄其他所有幀;

  • 數(shù)據(jù)幀的封裝與解封裝:

發(fā)送時(shí),將從上層(網(wǎng)絡(luò)層)接收到的數(shù)據(jù)包,加上幀頭(包含目標(biāo)MAC地址、源MAC地址等信息)和幀尾封裝成幀;

接收時(shí),檢查接收到的幀,去掉幀頭和幀尾,將里面的數(shù)據(jù)包提取出來(lái)交給上層的網(wǎng)絡(luò)層處理;

4. 可以這樣理解,從本質(zhì)上說(shuō),網(wǎng)卡建立了一條支持發(fā)送和接收的雙向通信的數(shù)據(jù)鏈路網(wǎng)絡(luò)承載,網(wǎng)絡(luò)承載類型可以是以太網(wǎng),WiFi網(wǎng)絡(luò),4G網(wǎng)絡(luò)等;

對(duì)于應(yīng)用層,傳輸層,網(wǎng)絡(luò)層來(lái)說(shuō),不需要關(guān)心下面的網(wǎng)絡(luò)承載類型,一旦網(wǎng)絡(luò)承載建立之后,可以使用DHCP應(yīng)用層協(xié)議動(dòng)態(tài)獲取ip地址或者直接配置靜態(tài)ip地址,ip地址成功獲取之后,整個(gè)網(wǎng)絡(luò)環(huán)境就算準(zhǔn)備就緒,就可以使用應(yīng)用層協(xié)議的接口或者使用socket接口開(kāi)發(fā)具體的網(wǎng)絡(luò)應(yīng)用了;

5. LuatOS上支持4G,WiFi,以太網(wǎng),自定義虛擬等多種類型的網(wǎng)卡;目前Air6101/Air8101系列默認(rèn)使用的是WiFi網(wǎng)卡,默認(rèn)編號(hào)為 socket.LWIP_STA;其他Air8000/Air780系列等默認(rèn)使用的是4G網(wǎng)卡,默認(rèn)編號(hào)為socket.LWIP_GP;

6. LuatOS上只需要直接使用默認(rèn)的網(wǎng)卡,或者根據(jù)自己的需求調(diào)用API配置使用的某一種或者多種網(wǎng)卡即可,至于數(shù)據(jù)鏈路網(wǎng)絡(luò)承載的建立,ip地址的分配,完全由核心庫(kù)或者擴(kuò)展庫(kù)自動(dòng)實(shí)現(xiàn),使用起來(lái)非常簡(jiǎn)單;

7. 下面所列舉的網(wǎng)卡編號(hào)常量,僅僅是一個(gè)編號(hào),關(guān)于這個(gè)編號(hào)的理解,分為以下兩種情況:

  • 第一種是,AirXXXX設(shè)備(Air8000/Air780/Air6101系列)內(nèi)自帶的網(wǎng)卡,這種網(wǎng)卡的編號(hào)是固定的,不允許配置修改;例如socket.LWIP_GP的編號(hào)為1,從LWIP_GP的字面意思來(lái)看,這個(gè)是蜂窩數(shù)據(jù)網(wǎng)絡(luò)網(wǎng)卡,所以使用蜂窩數(shù)據(jù)網(wǎng)絡(luò)(例如4G網(wǎng)絡(luò))上網(wǎng)時(shí),LuatOS內(nèi)核固件中默認(rèn)就使用了這個(gè)編號(hào),而且LuatOS內(nèi)核固件沒(méi)有開(kāi)放接口允許把蜂窩數(shù)據(jù)網(wǎng)絡(luò)的網(wǎng)卡配置為其他編號(hào);這種類型的網(wǎng)卡編號(hào)有socket.LWIP_GP,socket.LWIP_STA,socket.LWIP_AP;
  • 第二種是,AirXXXX設(shè)備(Air8000/Air780/Air6101系列)需要外掛的網(wǎng)卡,這種網(wǎng)卡的編號(hào),可以使用我們推薦的編號(hào)值,也可以使用自定義類型的編號(hào)值;例如通過(guò)SPI外掛CH390以太網(wǎng)卡時(shí),這種網(wǎng)卡的編號(hào)可以使用推薦的socket.LWIP_ETH,也可以使用自定義的socket.LWIP_USER0/1/2/3/4/5/6/7中的任何一個(gè);如果通過(guò)SPI外掛了5塊CH390以太網(wǎng)卡,這5塊以太網(wǎng)卡的編號(hào)可以從socket.LWIP_ETH、socket.LWIP_USER0/1/2/3/4/5/6/7,這9個(gè)網(wǎng)卡編號(hào)中選擇任意5個(gè);

socket.LWIP_GP

wKgZO2l53iyAc38fAADnSDEq0oc330.png

socket.LWIP_STA

wKgZO2l53mCAP1RQAADchWtrOJA916.png

socket.LWIP_AP

wKgZPGl53ouAfsHxAADnzU_KJow799.png

socket.LWIP_ETH

wKgZPGl53rGAFnT4AAED4hOAutk544.png

socket.ETH0

wKgZO2l53uSAVgVwAAGG_hRvgmo257.png

socket.USB

wKgZPGl53xqAJJFOAAHtQThxCX8488.png

socket.LWIP_USER0

wKgZPGl530yAcy4zAAFmYrFmvEc289.png

socket.LWIP_USER1

wKgZO2l533mADlRYAAFl09P7J6k274.png

socket.LWIP_USER2

wKgZO2l536GAVE7XAAFmzOWFEpU595.png

socket.LWIP_USER3

wKgZO2l539yAW7Y1AAFm-p3iYqw317.png

socket.LWIP_USER4

wKgZPGl54AmAfyERAAFmFWXb3Xs538.png

socket.LWIP_USER5

wKgZPGl54EGALEJOAAFmzlk4Um0603.png

socket.LWIP_USER6

wKgZPGl54G2ACUG9AAFnM8p7kXg076.png

socket.LWIP_USER7

wKgZO2l54JiAfBz2AAFmX7CaUFg912.png

5.1.2 網(wǎng)絡(luò)事件:

"IP_RAEDY"

常量含義

表示某一個(gè)網(wǎng)絡(luò)適配器編號(hào)對(duì)應(yīng)的網(wǎng)卡準(zhǔn)備就緒,string類型; 此處的“準(zhǔn)備就緒”是指:AirXXX硬件(例如Air780EPM)的某一個(gè)網(wǎng)卡在狹義或者廣義的內(nèi)網(wǎng)內(nèi),和路由設(shè)備之間雙向通信的數(shù)據(jù)鏈路已經(jīng)建立,并且已經(jīng)獲取到了本地的ip地址; 4G網(wǎng)絡(luò)環(huán)境下,是指AirXXX硬件和4G運(yùn)營(yíng)商的分組數(shù)據(jù)網(wǎng)關(guān)之間的數(shù)據(jù)鏈路已經(jīng)建立,并且分組數(shù)據(jù)網(wǎng)關(guān)已經(jīng)給AirXXX硬件分配了運(yùn)營(yíng)商內(nèi)部的私有ip地址;

如下圖紅框所示(手機(jī)相當(dāng)于AirXXX硬件,例如Air780EPM):

wKgZO2l54OKAVUCQAANRbBlR3c0973.png

一般來(lái)說(shuō),只要使用的sim卡沒(méi)有欠費(fèi),AirXXX硬件開(kāi)機(jī)之后,3秒左右就可以產(chǎn)生4G網(wǎng)卡的"IP_READY"消息;

? 以太網(wǎng)網(wǎng)絡(luò)環(huán)境下,是指AirXXX硬件(例如Air8000)通過(guò)網(wǎng)線和內(nèi)網(wǎng)內(nèi)的路由器之間的數(shù)據(jù)鏈路已經(jīng)建立,并且路由器已經(jīng)給AirXXX硬件分配了內(nèi)網(wǎng)內(nèi)部的內(nèi)網(wǎng)ip地址或者AirXXX硬件主動(dòng)設(shè)置了內(nèi)網(wǎng)靜態(tài)ip地址;

如下圖紅框所示(電腦相當(dāng)于AirXXX硬件,例如Air8000):

wKgZPGl54RGALB4XAAMDHXLE7j4714.png

一般來(lái)說(shuō),只要通過(guò)網(wǎng)線和路由器之間的連接正常,2秒左右就可以產(chǎn)生以太網(wǎng)網(wǎng)卡的"IP_READY"消息; WiFi網(wǎng)絡(luò)環(huán)境下,是指AirXXX硬件(例如Air6101)通過(guò)WiFi連接上了內(nèi)網(wǎng)的無(wú)線路由器,并且路由器已經(jīng)給AirXXX硬件分配了內(nèi)網(wǎng)的ip地址或者AirXXX硬件主動(dòng)設(shè)置了內(nèi)網(wǎng)靜態(tài)ip地址;

如下圖紅框所示(手機(jī)相當(dāng)于AirXXX硬件,例如Air6101);

wKgZPGl54TKAKpSEAALHY7K_kx4330.png

一般來(lái)說(shuō),只要輸入正確的密碼去連接WiFi路由器,2秒左右就可以產(chǎn)生WiFi網(wǎng)卡的"IP_READY"消息;

wKgZPGl54VKAHfy9AAXaHnaExNM244.png

發(fā)布并且處理"IP_RAEDY"消息的完整周期如下:

1、初始化配置某一種網(wǎng)卡(4G網(wǎng)卡不需要主動(dòng)配置,WiFi和以太網(wǎng)需要調(diào)用exnetif的接口主動(dòng)配置);

2、配置成功之后,LuatOS內(nèi)核固件會(huì)自動(dòng)執(zhí)行數(shù)據(jù)鏈路的建立以及ip地址的獲取動(dòng)作;

3、準(zhǔn)備就緒后,LuatOS內(nèi)核固件中會(huì)執(zhí)行sys.publish("IP_RAEDY", ip, adapter)發(fā)布全局消息;"IP_RAEDY"為消息名稱,string類型;ip為本地ip地址,string類型;adapter為網(wǎng)卡編號(hào),number類型,和本文5.1.1章節(jié)所描述的網(wǎng)絡(luò)適配器編號(hào)常量對(duì)應(yīng);

4、LuatOS應(yīng)用腳本中通過(guò)sys.subscribe或者sys.waitUntil訂閱處理"IP_RAEDY"這個(gè)消息; 如果使用sys.subscribe,要在第1步之前就要訂閱,否則會(huì)有遺漏"IP_RAEDY"消息的風(fēng)險(xiǎn); 如果使用sys.waitUntil,在sys.waitUntil之前使用socket.adapter接口主動(dòng)查詢下網(wǎng)卡狀態(tài), 如果查詢結(jié)果是已經(jīng)準(zhǔn)備就緒,則不再需要sys.waitUntil,否則再使用sys.waitUntil;

對(duì)某一種網(wǎng)卡來(lái)說(shuō),以下兩種情況會(huì)產(chǎn)生"IP_READY"消息:

1、初始化配置網(wǎng)卡之后,網(wǎng)卡準(zhǔn)備就緒后,會(huì)產(chǎn)生"IP_READY"消息;

2、如果網(wǎng)卡發(fā)生掉線產(chǎn)生了"IP_LOSE"消息,再次準(zhǔn)備就緒后,會(huì)產(chǎn)生"IP_READY"消息;

再來(lái)看另外一個(gè)問(wèn)題,如果某個(gè)網(wǎng)卡產(chǎn)生了"IP_READY"消息,是不是意味著使用這個(gè)網(wǎng)卡,肯定可以正常訪問(wèn)外網(wǎng)了?這個(gè)是不一定的,以下圖中的WiFi網(wǎng)絡(luò)為例來(lái)說(shuō)明一下:

wKgZO2l54cGAbEtOAALG_Fl_uDI244.png

如果無(wú)線路由器已經(jīng)正常上電,處于運(yùn)行狀態(tài),但是路由器并沒(méi)有連接外網(wǎng)(例如和ISP接入網(wǎng)的CGANT設(shè)備之間的光纖沒(méi)有連接);

這種狀態(tài)下,紅框內(nèi)的數(shù)據(jù)鏈路可以正常建立,并且無(wú)線路由器也可以給手機(jī)(類似于Air8000)分配內(nèi)網(wǎng)ip地址,Air8000就能產(chǎn)生"IP_READY"消息,但是Air8000并不能訪問(wèn)外網(wǎng),因?yàn)闊o(wú)線路由器無(wú)法訪問(wèn)外網(wǎng);

同理,4G網(wǎng)絡(luò)環(huán)境下,以太網(wǎng)環(huán)境下的"IP_READY"消息都是表示一個(gè)廣義或者狹義的內(nèi)網(wǎng)網(wǎng)絡(luò)環(huán)境準(zhǔn)備就緒,能否訪問(wèn)外網(wǎng),取決于內(nèi)網(wǎng)到外網(wǎng)以及整個(gè)外網(wǎng)的網(wǎng)絡(luò)環(huán)境是否正常;

也就是說(shuō):

沒(méi)有"IP_READY"是不能訪問(wèn)外網(wǎng)的;

有"IP_READY",大概率是可以訪問(wèn)外網(wǎng)的,但是也存在一些極低極低的概率不能訪問(wèn)外網(wǎng);

即使如此,用戶在編程時(shí),還是要以"IP_READY"來(lái)作為判斷可以連接外網(wǎng)的第一個(gè)條件,然后在應(yīng)用層,使用socket,http,mqtt等網(wǎng)絡(luò)應(yīng)用接口去實(shí)現(xiàn)自己的業(yè)務(wù)邏輯,如果socket,http,mqtt連接不成功,就有可能是外網(wǎng)不通,遇到這種情況,在socket,http,mqtt執(zhí)行重連就行了,用戶不用關(guān)系鏈路層的異常的原因,只關(guān)于自己的應(yīng)用層異常應(yīng)該怎么處理就行了;

應(yīng)用層的網(wǎng)絡(luò)業(yè)務(wù)的核心代碼邏輯如下所示:

wKgZPGl57OqAJ1htAAPuL7RuJts339.png

使用示例

使用sys.subscribe處理的方式:

wKgZPGl57T6AFVEZAAF7wqGKAZs268.png

使用sys.waitUntil處理的方式:

wKgZO2l57WeAfmJjAAHC2HgbS3A684.png

"IP_LOSE"

常量含義

表示某一個(gè)網(wǎng)絡(luò)適配器編號(hào)對(duì)應(yīng)的網(wǎng)卡從正常狀態(tài)下發(fā)生掉線,string類型;

發(fā)生掉線的原因包含但不僅僅包含以下幾種:

1、4G網(wǎng)絡(luò)環(huán)境下,sim卡不識(shí)別、sim卡欠費(fèi)、沒(méi)有4G網(wǎng)絡(luò)信號(hào)等;

2、WiFi網(wǎng)絡(luò)環(huán)境下,WiFi路由器關(guān)閉、WiFi路由器做了限制、離開(kāi)WiFi路由器有效信號(hào)范圍等;

3、以太網(wǎng)網(wǎng)絡(luò)環(huán)境下,以太網(wǎng)路由器關(guān)閉、以太網(wǎng)路由器做了限制、網(wǎng)線斷開(kāi)等;

發(fā)生掉線后,LuatOS內(nèi)核固件中會(huì)執(zhí)行sys.publish("IP_LOSE", adapter)發(fā)布全局消息;"IP_LOSE"為消息名稱,string類型;adapter為網(wǎng)卡編號(hào),number類型,和本文5.1.1章節(jié)所描述的網(wǎng)絡(luò)適配器編號(hào)常量對(duì)應(yīng);

使用示例

一般情況下,推薦使用sys.subscribe處理的方式來(lái)監(jiān)控"IP_LOSE"消息,監(jiān)控到這個(gè)消息之后,可以根據(jù)自己的項(xiàng)目需求走一些具體項(xiàng)目業(yè)務(wù)邏輯的顯示,例如通知已斷網(wǎng),但是不需要手動(dòng)寫(xiě)代碼再去控制網(wǎng)卡重試連網(wǎng),因?yàn)樵趦?nèi)核固件中,會(huì)自動(dòng)重試連網(wǎng)動(dòng)作;

wKgZO2l57fOAGMzIAACO3FEctl4395.png

socket.LINK(了解即可)

關(guān)于這個(gè)常量,了解即可,LuatOS項(xiàng)目應(yīng)用腳本程序中不推薦使用

wKgZO2l57keAXiU2AAcpyXePyP8013.pngwKgZPGl57ouAJUhCAAXKS6vqPyU368.png

socket.ON_LINE(了解即可)

關(guān)于這個(gè)常量,了解即可,LuatOS項(xiàng)目應(yīng)用腳本程序中不推薦使用

wKgZO2l57xOALKqLAAZHrTDU1fU090.png

socket.EVENT

wKgZPGl571WAQyFrAATBRCtDGYM218.png

socket.TX_OK(了解即可)

關(guān)于這個(gè)常量,了解即可,LuatOS項(xiàng)目應(yīng)用腳本程序中不推薦使用

wKgZO2l575aAEhLEAAYmlzYsp4c356.png

socket.CLOSED(了解即可)

關(guān)于這個(gè)常量,了解即可,LuatOS項(xiàng)目應(yīng)用腳本程序中不推薦使用

wKgZPGl579GAPHqJAAOU7R4O6Oo817.png

5.2 函數(shù)詳解

socket核心庫(kù)提供的api比較多,有一部分api是異步操作,使用起來(lái)比較復(fù)雜,已經(jīng)不推薦使用,在此處就不再講解;如果大家還需要了解這些已經(jīng)不推薦的異步api的使用方法

這些不推薦的異步api,在libnet擴(kuò)展庫(kù)中已經(jīng)被封裝成了同步api,使用起來(lái)更加方便,在下一章節(jié),我們會(huì)詳細(xì)講解這些libnet擴(kuò)展庫(kù)中的同步api接口;

除此之外,socket核心庫(kù)還有一些同步api接口,這些api主要涉及到網(wǎng)卡操作,socket的創(chuàng)建、配置、讀取、銷毀等功能,本章節(jié),我們先詳細(xì)學(xué)習(xí)一下這些同步api接口;

socket.adapter(adapter_id)

功能

查看網(wǎng)卡的聯(lián)網(wǎng)狀態(tài)

參數(shù)

adapter_id

wKgZO2l58JeAaKSmAAE_wLDx64k364.png

返回值

local is_ready, index = socket.adapter(adapter_id)

is_ready

wKgZPGl58keAHtqDAADKJduL2Jg234.png

index

wKgZPGl58nCAPEWeAACtvwLo0n8954.png

示例

wKgZO2l58qqAN1KXAAIwTi9bpu8134.png

socket.dft(adapter_id)

功能

讀取或者設(shè)置當(dāng)前使用的默認(rèn)網(wǎng)卡;

默認(rèn)網(wǎng)卡的作用如下:

創(chuàng)建socket,mqtt,http等網(wǎng)絡(luò)應(yīng)用對(duì)象時(shí),可以通過(guò)參數(shù)主動(dòng)指定要使用的網(wǎng)卡;

如果沒(méi)有制定,就會(huì)使用系統(tǒng)中的默認(rèn)網(wǎng)卡;

例如:

socket.create(socket.LWIP_GP, "tcp_task") 表示使用socket.LWIP_GP網(wǎng)卡創(chuàng)建一個(gè)socket對(duì)象,后續(xù)這個(gè)socket對(duì)象的所有數(shù)據(jù)通信都會(huì)基于socket.LWIP_GP網(wǎng)卡進(jìn)行;

socket.create(nil, "tcp_task") 表示使用當(dāng)前時(shí)刻的默認(rèn)網(wǎng)卡創(chuàng)建一個(gè)socket對(duì)象,后續(xù)這個(gè)socket對(duì)象的所有數(shù)據(jù)通信都會(huì)基于當(dāng)前時(shí)刻的默認(rèn)網(wǎng)卡進(jìn)行;

socket.create(nil, "tcp_task")等價(jià)于socket.create(socket.dft(), "tcp_task");

默認(rèn)網(wǎng)卡的設(shè)置有以下三種方式:

1、LuatOS內(nèi)核固件運(yùn)行起來(lái)之后,已經(jīng)初始化設(shè)置了默認(rèn)網(wǎng)卡;目前Air8000/Air780系列等默認(rèn)使用的是4G網(wǎng)卡,編號(hào)為socket.LWIP_GP;Air6101/Air8101系列默認(rèn)使用的是WiFi設(shè)備模式網(wǎng)卡,編號(hào)為 socket.LWIP_STA;

2、使用擴(kuò)展庫(kù)exnetif中的接口exnetif.set_priority_order配置單網(wǎng)卡或者多網(wǎng)卡時(shí),set_priority_order接口內(nèi)部會(huì)根據(jù)配置自動(dòng)設(shè)置默認(rèn)網(wǎng)卡;

3、LuatOS項(xiàng)目的用戶應(yīng)用腳本運(yùn)行起來(lái)之后,在腳本中可以調(diào)用接口socket.dft(adapter_id)主動(dòng)設(shè)置新的默認(rèn)網(wǎng)卡adapter_id;

在這三種設(shè)置默認(rèn)網(wǎng)卡的方式中:

第1種設(shè)置方式,用戶無(wú)法參與設(shè)置;

第2種設(shè)置方式,用戶可以參與設(shè)置,如果需要更改設(shè)置默認(rèn)網(wǎng)卡,推薦使用這一種方式;這樣設(shè)置有兩個(gè)好處:

1、exnetif擴(kuò)展庫(kù)已經(jīng)高度集成,使用這個(gè)擴(kuò)展庫(kù)提供的接口,無(wú)論是單網(wǎng)卡設(shè)置還是多網(wǎng)卡設(shè)置,使用起來(lái)非常方便;

2、默認(rèn)網(wǎng)卡設(shè)置和具體的socket,mqtt,http網(wǎng)絡(luò)應(yīng)用解耦,用戶只需要在初始化時(shí)配置一次,所有的網(wǎng)絡(luò)應(yīng)用中不要再指定具體的網(wǎng)卡,就可以使用初始化配置的優(yōu)先級(jí)使用默認(rèn)網(wǎng)卡;

我們結(jié)合實(shí)際代碼看一下exnetif擴(kuò)展庫(kù)接口的使用方式;

第3種設(shè)置方式,用戶可以參與設(shè)置,如果需要更改設(shè)置默認(rèn)網(wǎng)卡,不推薦使用這一種方式;因?yàn)楹偷?種方式相比,使用起來(lái)會(huì)復(fù)雜;

參數(shù)

adapter_id

wKgZO2l584uAQdYYAAF0WkWoPVA081.png

返回值

查詢默認(rèn)網(wǎng)卡時(shí):

local adapter_id, last_reg_adapter_id = socket.dft()

adapter_id

wKgZPGl587OAOAxoAADSkE8BKNg338.png

last_reg_adapter_id

wKgZO2l589mAC5zOAAD4YHNcBRA959.png

設(shè)置默認(rèn)網(wǎng)卡時(shí):

local new_adapter_id, last_reg_adapter_id = socket.dft(adapter_id)

new_adapter_id

wKgZPGl59AmAL4tEAADcSCPaqII938.png

last_reg_adapter_id

wKgZO2l589mAC5zOAAD4YHNcBRA959.png

示例

不推薦直接使用socket.dft來(lái)設(shè)置默認(rèn)網(wǎng)卡,所有此處不再列舉設(shè)置功能的示例,僅列舉查詢功能的示例

wKgZO2l59FKAY2gGAAJa_JwU_6k844.png

socket.localIP(adapter_id)

功能

獲取某個(gè)網(wǎng)卡上的本地 ip地址、網(wǎng)絡(luò)掩碼和網(wǎng)關(guān)地址;

只有網(wǎng)卡準(zhǔn)備就緒后,才能讀取到這三個(gè)值;

參數(shù)

adapter_id

wKgZPGl59IOABBC4AAES9TLO5Qg179.png

返回值

local ip, netmask, gateway = socket.localIP(adapter_id)

有三個(gè)返回值 ip, netmask, gateway

192.168.31.156 255.255.255.0 192.168.31.1 nil

ip

wKgZO2l59K-AeqHpAAESb_WCJc0702.png

netmask

wKgZPGl59NGAW4h0AACk25H4JnA251.png

gateway

wKgZO2l59POAV44MAAEHMDwbysY787.png

示例

wKgZO2l59ReASj19AAL_Oa_iq_U360.png

socket.setDNS(adapter_id, dns_index, ip)

功能

設(shè)置某個(gè)網(wǎng)卡使用的DNS服務(wù)器IP地址;

內(nèi)核固件中有4個(gè)位置可以存儲(chǔ)DNS服務(wù)器IP地址;

對(duì)應(yīng)的位置索引為本接口的dns_index參數(shù),取值范圍為1到4;

所以最多同時(shí)存在4個(gè)DNS服務(wù)器IP地址;

DNS服務(wù)器IP地址有兩大類:

1、第一類是:網(wǎng)卡初始化過(guò)程中,自動(dòng)從網(wǎng)絡(luò)運(yùn)營(yíng)商獲取到默認(rèn)的DNS服務(wù)器IP地址;

? 這一類DNS服務(wù)器IP地址通常由2個(gè)或者1個(gè),這一類DNS服務(wù)器IP地址存儲(chǔ)在dns_index為3和4的位置;

2、第二類是:在應(yīng)用腳本程序中調(diào)用socket.setDNS接口手動(dòng)設(shè)置的自定義的DNS服務(wù)器IP地址;例如:

socket.setDNS(socket.LWIP_GP, 1, "223.5.5.5")表示為4G網(wǎng)卡在位置1設(shè)置自定義的DNS服務(wù)器IP地址"223.5.5.5",這個(gè)DNS服務(wù)器IP地址是阿里云提供的DNS服務(wù)器IP地址;

socket.setDNS(socket.LWIP_GP, 2, "114.114.114.114")表示為4G網(wǎng)卡在位置2設(shè)置自定義的DNS服務(wù)器IP地址"114.114.114.114",這個(gè)DNS服務(wù)器IP地址是國(guó)內(nèi)通用的DNS服務(wù)器IP地址;

DNS解析服務(wù)的邏輯是:

遍歷位置1到4的DNS服務(wù)器IP地址;

如果當(dāng)前位置存在DNS服務(wù)器IP地址,則解析域名,每個(gè)DNS服務(wù)器IP地址嘗試3次,每次超時(shí)分別是1秒鐘、2秒鐘、3秒鐘;

如果當(dāng)前位置不存在DNS服務(wù)器IP地址,則直接跳過(guò);

也就是說(shuō),如果4個(gè)位置上都有DNS服務(wù)器IP地址,則最多嘗試12次,最長(zhǎng)超時(shí)24秒可以返回解析結(jié)果;

為了防止出現(xiàn)默認(rèn)的DNS服務(wù)器IP地址解析服務(wù)器不穩(wěn)定的問(wèn)題,把位置3和4用來(lái)存儲(chǔ)默認(rèn)的DNS服務(wù)器IP地址,同時(shí),可以在位置1和2設(shè)置為自定義的DNS服務(wù)器IP地址,如下所示,為了方便用戶參考使用,我們?cè)诿總€(gè)網(wǎng)絡(luò)應(yīng)用demo中,已經(jīng)為所有使用到的網(wǎng)卡增加了如下配置:

wKgZPGl59XiADvCAAAGUGmGbVSo774.png

參數(shù)

adapter_id

wKgZPGl59IOABBC4AAES9TLO5Qg179.png

dns_index

wKgZPGl59c2AdQfcAADRrkkAr3o256.png

ip

wKgZPGl59fiARMSYAAC30FJNfHU214.png


返回值

local result = socket.setDNS(adapter_id, dns_index, ip)

result

wKgZPGl59hiAXk7eAACssy_IP1I568.png

示例

wKgZO2l59j-AP_LaAAKN2la6UlM147.png

socket.sslLog(log_level)

功能

設(shè)置內(nèi)核固件中ssl功能的log等級(jí);

一般來(lái)說(shuō),當(dāng)需要抓取更多的日志給我們技術(shù)人員分析時(shí),可以使用此接口,設(shè)置輸出更多日志信息的等級(jí);

如果打開(kāi)debug開(kāi)關(guān),使用Luatools抓日志時(shí),在主界面窗口會(huì)出現(xiàn)類似于下面的日志信息(出現(xiàn)很多mbedtls開(kāi)頭的日志):

wKgZPGl59n6AdaXKAAqRZTqEy6A044.png

參數(shù)

log_level

wKgZO2l59qqAMm0MAAHT7L2OAyg700.png

返回值

nil

示例

wKgZO2l59taAJdc6AABR7JJiknY029.png

socket.create(adapter_id, task_name)

功能

在指定網(wǎng)卡上創(chuàng)建一個(gè)socket對(duì)象;

ram資源足夠的情況下:

1、Air780系列/Air8000系列的模組,允許創(chuàng)建的同時(shí)存在的socket對(duì)象數(shù)量為64個(gè);

2、Air6101系列/Air8101系列的模組,允許創(chuàng)建的同時(shí)存在的socket對(duì)象數(shù)量為32個(gè);

參數(shù)

adapter_id

wKgZPGl59xyAA9h5AAOJMKmzxds261.png

task_name

wKgZPGl590GAEcuMAAD-L3Vl6hI481.png

返回值

local socket_ctrl = socket.create(nil, "socket_client_task")

socket_ctrl

wKgZO2l593aAJZm7AAG0IaV4HZU664.pngwKgZO2l5946AFu2tAAA3g6Q7tGU554.pngwKgZPGl596WAPdPTAADQnIjSsdY690.png

socket.debug(socket_ctrl, onoff)

功能

配置是否打開(kāi)內(nèi)核固件中network的debug日志信息;

一般來(lái)說(shuō),當(dāng)需要抓取更多的日志給我們技術(shù)人員分析時(shí),可以打開(kāi)此開(kāi)關(guān);

如果打開(kāi)debug開(kāi)關(guān),使用Luatools抓日志時(shí),在主界面窗口會(huì)出現(xiàn)類似于下面的日志信息(出現(xiàn)很多network開(kāi)頭的日志):

wKgZO2l59_2ARaUIAAkKL6IPRBg312.png

參數(shù)

socket_ctrl

wKgZO2l5-DqAZURoAAD0mTDZrxY363.png

onoff

wKgZPGl5-F-AS5MYAAD38Dcv9xg521.png

返回值

nil

示例

wKgZPGl5-IOAZZFKAAEyTCBe72k859.png

socket.config(socket_ctrl, local_port, is_udp, is_tls, keep_idle, keep_interval, keep_cnt, server_cert, client_cert, client_key, client_password)

功能

配置socket對(duì)象的參數(shù)(本地端口號(hào),TCP/UDP/TLS協(xié)議,TCP keep alive心跳參數(shù),證書(shū)認(rèn)證信息)

本地端口號(hào),TCP/UDP/TLS協(xié)議,證書(shū)認(rèn)證信息,這三部分的知識(shí),我們?cè)诶碚撝R(shí)章節(jié),已經(jīng)介紹過(guò),此處就不再重復(fù)介紹了

TCP keep alive心跳參數(shù),之前還沒(méi)有介紹過(guò),我們先看一下TCP keep alive心跳;

TCP Keepalive 是一種用于檢測(cè) TCP 連接另一端是否仍然存活和可達(dá)的機(jī)制。它通過(guò)在一條空閑的連接上定期發(fā)送特殊的探測(cè)報(bào)文(Keepalive 探針)來(lái)實(shí)現(xiàn);

例如客戶端和服務(wù)器建立了 TCP 連接之后,雙方再也沒(méi)有應(yīng)用數(shù)據(jù)要發(fā)送。此時(shí),連接處于空閑狀態(tài);

但是客戶端又想一直維持這個(gè)連接,否則有可能空閑超時(shí)被網(wǎng)絡(luò)服務(wù)商給斷開(kāi)(例如4G網(wǎng)絡(luò)服務(wù)商發(fā)現(xiàn)某個(gè)連接長(zhǎng)時(shí)間沒(méi)有數(shù)據(jù)通信,可能是幾分鐘,也能更長(zhǎng)時(shí)間,時(shí)間不確定,就會(huì)主動(dòng)的斷開(kāi)這個(gè)連接);

TCP Keepalive機(jī)制可以定時(shí)發(fā)送Keepalive 探針報(bào)文,防止連接空閑時(shí)間太長(zhǎng),導(dǎo)致連接被異常斷開(kāi);

在TCP協(xié)議的規(guī)范中,TCP Keepalive機(jī)制的數(shù)據(jù)交互過(guò)程受三個(gè)核心參數(shù)控制:

keep_idle(默認(rèn)值7200秒,也就是2小時(shí)):連接空閑多長(zhǎng)時(shí)間后,開(kāi)始發(fā)送第一個(gè) Keepalive 探針報(bào)文;

keep_interval(默認(rèn)值75秒):發(fā)送第一個(gè)探針后,如果沒(méi)收到ACK回復(fù),間隔多久再發(fā)送下一個(gè)探針;

keep_cnt(默認(rèn)值9次):總共發(fā)送多少次探針后,如果依然沒(méi)有回復(fù),則判定連接已斷開(kāi);

假設(shè)這三個(gè)參數(shù)都使用默認(rèn)值,TCP Keepalive機(jī)制的工作流程如下:

連接建立后,空閑了 7200 秒(2小時(shí));

客戶端 發(fā)送第一個(gè) Keepalive 探針報(bào)文到服務(wù)器;

可能出現(xiàn)三種結(jié)果:

成功:服務(wù)器回復(fù) ACK,客戶端知道和服務(wù)器之間的連接還存在;定時(shí)器重置,再等待2小時(shí)的空閑時(shí)間;

超時(shí):客戶端等待 75 秒,沒(méi)收到ACK,則重試發(fā)送第二個(gè)探針;

錯(cuò)誤:服務(wù)器回復(fù)異常報(bào)文,并且斷開(kāi)連接;

如果客戶端連續(xù)發(fā)送9個(gè)探針(每?jī)蓚€(gè)探針之間間隔75秒)后都超時(shí)無(wú)任何響應(yīng),客戶端就判斷連接已斷開(kāi);

連接已經(jīng)斷開(kāi)的情況下,從開(kāi)始探測(cè)到最終檢測(cè)到已經(jīng)斷開(kāi)的結(jié)果,最長(zhǎng)需要:7200 + 75 * 9 ≈ 7875秒,約 2 小時(shí) 11 分鐘;

而4G網(wǎng)絡(luò)環(huán)境下,最長(zhǎng)空閑十幾分鐘,大概率就被網(wǎng)絡(luò)服務(wù)商給異常中斷了,所以說(shuō),這三個(gè)核心參數(shù)如果使用默認(rèn)值,TCP keepalive心跳沒(méi)有任何作用,根本起不到保持長(zhǎng)連接的作用;

所以我們?cè)贚uatOS的socket核心庫(kù)中,提供了一個(gè)接口socket.config,可以配置這三個(gè)參數(shù)的值,讓TCP keepalive真正能夠起到保持長(zhǎng)連接的作用; 例如keep_idle可以設(shè)置為300秒,keep_interval可以設(shè)置為10秒,keep_cnt可以設(shè)置為3次;

如果使用了TCP keepalive心跳機(jī)制,并且三個(gè)核心參數(shù)配置合適,就可以不再使用應(yīng)用心跳機(jī)制來(lái)保持長(zhǎng)連接;

如果項(xiàng)目中定義了應(yīng)用心跳機(jī)制,并且應(yīng)用心跳間隔合適,就可以不啟用TCP keepalive機(jī)制,keep_idle參數(shù)為空或者傳入nil即可;

參數(shù)

socket_ctrl

wKgZO2l5-XKANocqAADtgn1tBog929.png

local_port

wKgZPGl5-aOAXgtXAADqd6OUNNQ569.png

is_udp

wKgZO2l5-cSAId8IAADcPodzOLM266.png

is_tls

wKgZO2l5-fyAeIMOAAHDVQ_HzJo660.png

keep_idle

wKgZO2l5-hqAMTNrAAFyteugT_k285.png

keep_interval

wKgZPGl5-jiAdccsAAEJpWcEGOk388.png

keep_cnt

wKgZO2l5-lOAHUo_AAD7wqQeqk0706.png

server_cert

wKgZPGl5-nKAP8JFAAGLTwfgX_s266.png

client_cert

wKgZPGl5-pOARNaHAAGEp670OHQ518.png

client_key

wKgZO2l5-rKADLzzAAFY65nDYA8076.png

client_password

wKgZO2l5-tKAYvnKAAFr21U3rDA218.png

返回值

local result = socket.config(socket_ctrl, local_port, is_udp, is_tls, keep_idle, keep_interval, keep_cnt, server_cert, client_cert, client_key, client_password)

result

wKgZPGl5-v2AWKNvAACE6rwvlyk576.png

示例

配置為普通的tcp socket client

wKgZPGl5-yuActWbAAF0MHZSVbQ731.png

配置為不做證書(shū)校驗(yàn)的tcp ssl socket client

wKgZPGl5-0yACIfoAAG33i_eZZU244.png

配置為單向證書(shū)校驗(yàn)的tcp ssl socket client

wKgZO2l5-2qARTSsAAGuc_PzJv4459.png

配置為普通的udp socket client

wKgZPGl5-5uAcbKlAAF8MDxZbzk595.png

socket.rx(socket_ctrl, buff, flag, limit)

功能

接收對(duì)端發(fā)送過(guò)來(lái)的數(shù)據(jù),注意數(shù)據(jù)已經(jīng)緩存在內(nèi)核固件底層,使用本函數(shù)只是讀取出來(lái);

TCP模式下,對(duì)端發(fā)送過(guò)來(lái)的一包應(yīng)用數(shù)據(jù)長(zhǎng)度,沒(méi)有特別限制;

UDP模式下,對(duì)端發(fā)送過(guò)來(lái)的一包應(yīng)用數(shù)據(jù)長(zhǎng)度,不要超過(guò)1460字節(jié)數(shù)據(jù);

對(duì)于tcp來(lái)說(shuō),數(shù)據(jù)已經(jīng)緩存到內(nèi)核固件底層的數(shù)據(jù)接收緩沖區(qū),這個(gè)數(shù)據(jù)接收緩沖區(qū)就是滑動(dòng)窗口,滑動(dòng)窗口的理論知識(shí)

LuatOS tcp socket本地的窗口初始大小為8040字節(jié),在接收數(shù)據(jù)過(guò)程中,會(huì)將窗口的動(dòng)態(tài)大小通知給發(fā)送方,發(fā)送方必須遵守這個(gè)窗口的限制;

例如 tcp client和server建立連接后,server應(yīng)用層輸入了34560字節(jié)的數(shù)據(jù)要發(fā)送過(guò)來(lái),點(diǎn)擊發(fā)送按鈕,在tcp層傳輸數(shù)據(jù)時(shí),server會(huì)根據(jù)client這邊的動(dòng)態(tài)窗口大小,動(dòng)態(tài)調(diào)整發(fā)送數(shù)據(jù)的速度;先看下Luatools抓取到的Air8000的應(yīng)用日志:

wKgZPGl5-_GADdUEAASsPiYUtSQ355.png

一共收到34560字節(jié)的數(shù)據(jù),沒(méi)有丟失;

我們?cè)倏纯催@個(gè)數(shù)據(jù)接收過(guò)程中網(wǎng)絡(luò)數(shù)據(jù)交互,滑動(dòng)窗口機(jī)制是如何工作的;

下面這張截圖是從Air8000的運(yùn)行日志中導(dǎo)出的網(wǎng)絡(luò)數(shù)據(jù)包:

wKgZPGl6zgKAOK3yAAlfmFbwpNY508.png

所以說(shuō),tcp socket,不用關(guān)心內(nèi)核固件底層的接收緩沖區(qū)有多大,也不用關(guān)心對(duì)端發(fā)送過(guò)來(lái)的數(shù)據(jù)有多少,tcp的滑動(dòng)窗口機(jī)制、序列號(hào)和確認(rèn)號(hào)機(jī)制、超時(shí)重傳機(jī)制,保證了數(shù)據(jù)接收的完整性;

在編程時(shí),唯一需要注意的就是,當(dāng)內(nèi)核固件接收到數(shù)據(jù)時(shí),在應(yīng)用腳本中及時(shí)讀出來(lái)數(shù)據(jù)即可,這樣內(nèi)核固件的窗口大小就會(huì)動(dòng)態(tài)變化;

對(duì)于udp來(lái)說(shuō),雖然udp協(xié)議規(guī)范應(yīng)用數(shù)據(jù)一包的最大長(zhǎng)度為65535字節(jié),但是由于udp數(shù)據(jù)傳輸不可靠,另外收到大數(shù)據(jù)時(shí),LuatOS內(nèi)核分配連續(xù)的內(nèi)存空間也存在失敗的概率,雙重失敗概率疊加,會(huì)導(dǎo)致udp大數(shù)據(jù)接收存在失敗的概率增高;

從傳輸可靠性說(shuō),整個(gè)udp應(yīng)用數(shù)據(jù)包含在單個(gè)mtu內(nèi)最佳,最常見(jiàn)的mtu是1500字節(jié),減去網(wǎng)絡(luò)層和傳輸層的頭部,剩余1460字節(jié)的長(zhǎng)度給應(yīng)用數(shù)據(jù),所以所以LuatOS上的udp socket,限制可以接收的一包udp應(yīng)用數(shù)據(jù)長(zhǎng)度為1460字節(jié);這是一個(gè)推薦值,目前實(shí)際使用時(shí),可能可以接收到更長(zhǎng)的數(shù)據(jù),但是為了可靠性,盡量將一包應(yīng)用數(shù)據(jù)的長(zhǎng)度控制在1460字節(jié);

參數(shù)

socket_ctrl

wKgZPGl6zkKAcFI2AADiY2I96go280.png

buff

wKgZPGl60OuADD2BAADZBedxJaU921.png

flag

wKgZPGl60SyAAg_tAAC0Zf8dmGE916.png

limit

wKgZPGl60UqAfdO6AADeAeAnCOM334.png

返回值

local succ, data_len, remote_ip, remote_port = socket.rx(socket_ctrl, buff, flag, limit)

succ

wKgZO2l60WuATjIfAAEgkSTdGeQ400.png

data_len

wKgZPGl60Y6Aaay9AADQKcxVD-4623.png

remote_ip

wKgZO2l60b-AJ_-6AAGrSs0Gpuk397.png

remote_port

wKgZPGl60eOAKEkeAADTNeTEK80302.png

示例

wKgZPGl60hSAbEs6AAPGYrQS9A0534.png

socket.state(socket_ctrl)

功能

獲取 socket 當(dāng)前狀態(tài);

參數(shù)

socket_ctrl

wKgZPGl6_JOAWH5fAADwoeK0FnU682.png

返回值

local state, str = socket.state(socket_ctrl)

state

wKgZO2l6_LyAOT1gAAFnp3XBf5Q148.png

str

wKgZO2l6_NyATxvHAAFFgNN4F-o797.png

示例

wKgZO2l6_RqALlA_AAFN052_-r4291.png

socket.release(socket_ctrl)

功能

主動(dòng)釋放掉 socket對(duì)象,此接口和socket.create接口是一對(duì)逆操作;

使用socket.release之后,如果要發(fā)起重連,需要重新從socket.create開(kāi)始;

參數(shù)

socket_ctrl

wKgZPGl6_JOAWH5fAADwoeK0FnU682.png

返回值

nil

示例

wKgZPGl6_c-AF9syAAErdL8TEWU144.png

六、LuatOS上的libnet擴(kuò)展庫(kù)

剛才我們已經(jīng)在上一章節(jié)學(xué)習(xí)了socket核心庫(kù)中的同步api接口,這些api主要涉及到網(wǎng)卡操作,socket的創(chuàng)建、配置、讀取、銷毀等功能;

在本章節(jié),我們先詳細(xì)學(xué)習(xí)一下libnet擴(kuò)展庫(kù)的api接口;

socket核心庫(kù)和libnet擴(kuò)展庫(kù)的主要區(qū)別是:

1、socket核心庫(kù)提供了完整的api,可以實(shí)現(xiàn)socket的完整業(yè)務(wù)邏輯,但是部分api是異步接口,使用起來(lái)復(fù)雜;

2、所以我們開(kāi)發(fā)一套libnet擴(kuò)展庫(kù)api接口,將socket核心庫(kù)中的異步接口,封裝成同步接口,放到libnet擴(kuò)展庫(kù)中,使用起來(lái)會(huì)更加方便;

最終,我們推薦使用socket核心庫(kù)中的同步api接口+libnet擴(kuò)展庫(kù)中的同步api接口的方式,來(lái)開(kāi)發(fā)完整的socket業(yè)務(wù)邏輯;這兩部分如何組合使用,在本文有一個(gè)詳細(xì)的socket client應(yīng)用開(kāi)發(fā)框架來(lái)演示;

libnet.connect(task_name, timeout, socket_ctrl, remote_addr, remote_port, need_ipv6_dns)

功能

連接對(duì)端,阻塞等待連接結(jié)果的返回;

只能在sys.taskInitEx創(chuàng)建的task的任務(wù)處理函數(shù)中使用,因?yàn)橐枞却⑶医邮斩ㄏ蛳ⅲ?/p>

以下三種情況會(huì)返回:

1、連接成功;

2、連接失??;

3、連接超時(shí)(超時(shí)時(shí)長(zhǎng)受timeout參數(shù)控制);

參數(shù)

task_name

wKgZO2l6_viAYuYPAAEBIsPgLYc511.png

timeout

wKgZPGl6_zCARMTWAAMLV0tv56E643.png

socket_ctrl

wKgZPGl6_8uAVw4rAADNFV_OGe8778.png

remote_address

wKgZPGl6__aAa9p8AAC9iJIo_dU456.png

remote_port

wKgZO2l7ABmAGNHAAACvxjdShfg447.png

need_ipv6_dns

wKgZO2l7ADmAFXUzAAEEhMY-OTY743.png

返回值

local result = libnet.connect(task_name, timeout, socket_ctrl, remote_addr, remote_port, need_ipv6_dns)

result

wKgZO2l7AFyAezzoAAClI6SzzFI707.png

示例

wKgZPGl7AH-AVM23AAKCEQpRrZc822.png

libnet.tx(task_name, timeout, socket_ctrl, data, ip, port, flag)

功能

發(fā)送數(shù)據(jù)到對(duì)端,阻塞等待發(fā)送結(jié)果的返回;

只能在sys.taskInitEx創(chuàng)建的task的任務(wù)處理函數(shù)中使用,因?yàn)橐枞却⑶医邮斩ㄏ蛳ⅲ?/p>

以下三種情況會(huì)返回:

1、發(fā)送成功;

2、發(fā)送失??;

3、發(fā)送超時(shí)(超時(shí)時(shí)長(zhǎng)受timeout參數(shù)控制);

參數(shù)

task_name

wKgZPGl7AMGAHXNcAAD4WZdJhx0927.png

timeout

wKgZPGl7APSAeXlAAAHGjQm3S2w298.png

socket_ctrl

wKgZPGl7ARWAL-qtAADUkuvk96U924.png

data

wKgZO2l7ATKABv7cAADxmwUNsaw760.png

ip

wKgZO2l7AWKAdHOBAAG59UDh-A0885.png

port

wKgZPGl7AYqAPOOmAAGw3UorZMM678.png

flag

wKgZO2l7Aa2AI6R2AAC2FM0RH5E948.png

返回值

local result, buff_full = libnet.tx(task_name, timeout, socket_ctrl, data, ip, port, flag)

result

wKgZPGl7AdqARtLDAAC1URnMtz8172.png

buff_full

wKgZO2l7AiKAXmuwAAHQ9O1A37M448.png

示例

wKgZO2l7AkKARxjNAAEKN9eNYYE076.png

libnet.wait(task_name,timeout, socket_ctrl)

功能

socket連接已經(jīng)成功后,阻塞等待socket對(duì)象上新的網(wǎng)絡(luò)事件消息socket.EVENT;

只能在sys.taskInitEx創(chuàng)建的task的任務(wù)處理函數(shù)中使用,因?yàn)橐枞却⑶医邮斩ㄏ蛳ⅲ?/p>

以下三種情況會(huì)退出阻塞等待狀態(tài):

1、socket對(duì)象和對(duì)端之間的連接出現(xiàn)異常(例如對(duì)端主動(dòng)斷開(kāi),網(wǎng)絡(luò)環(huán)境出現(xiàn)異常等),此時(shí)在內(nèi)核固件中會(huì)發(fā)送消息socket.EVENT;

2、socket對(duì)象接收到對(duì)端發(fā)送過(guò)來(lái)的數(shù)據(jù),此時(shí)在內(nèi)核固件中會(huì)發(fā)送消息socket.EVENT;

3、在應(yīng)用腳本中需要的位置,主動(dòng)調(diào)用sys.sendMsg(task_name, socket.EVENT, 0)發(fā)送消息socket.EVENT給task_name對(duì)應(yīng)的task;

參數(shù)

task_name

wKgZPGl7Ao6AO7NfAAD6HjHWXdk591.png

timeout

wKgZPGl7AruAZG9FAAFnu8qBnuU468.png

socket_ctrl

wKgZO2l7AtyANHv-AADSoNPO3Hg888.png

返回值

local result, param = libnet.wait(task_name, timeout, socket_ctrl)

result

wKgZPGl7Av6ALkYWAADVdY_4UmI056.png

param

wKgZPGl7AyKAZRcXAAC6vT4FL3Y369.png

示例

wKgZPGl7A0WATL6rAAFzwd97z3M764.png

libnet.close(task_name, timeout, socket_ctrl)

功能

主動(dòng)斷開(kāi)socket連接;

TCP模式下,先四次揮手?jǐn)嚅_(kāi)連接(超時(shí)時(shí)長(zhǎng)為timeout),再直接強(qiáng)制斷開(kāi);

UDP模式下,直接強(qiáng)制斷開(kāi);

只能在sys.taskInitEx創(chuàng)建的task的任務(wù)處理函數(shù)中使用,因?yàn)橐枞却⑶医邮斩ㄏ蛳ⅲ?/p>

參數(shù)

task_name

wKgZPGl7A32AdqGsAADcESlaMS0025.png

timeout

wKgZPGl7A56AS2LkAAFB1qNezNw512.png

socket_ctrl

wKgZPGl7A7qAJWb1AADSnwakK_o172.png

返回值

nil

示例

wKgZPGl7A96AZ1DwAAA53SdN-Q0768.png

七、LuatOS上的socke client 應(yīng)用開(kāi)發(fā)框架

現(xiàn)在,LuatOS socket和libnet的兩個(gè)重要的庫(kù)文件,基本上講完了,接下來(lái),我們來(lái)實(shí)際看一個(gè)完整的socket client長(zhǎng)連接的demo項(xiàng)目代碼,重點(diǎn)分析下如何在項(xiàng)目中使用LuatOS socket核心庫(kù)和libnet擴(kuò)展庫(kù);

7.1 總體設(shè)計(jì)框圖

demo項(xiàng)目的總體設(shè)計(jì)框圖如下:

wKgZO2l7BFOASgrAAAIkhJAUUxk405.png

7.2 模擬器上運(yùn)行這個(gè)項(xiàng)目(使用模擬器單網(wǎng)卡演示項(xiàng)目完整的業(yè)務(wù)邏輯)

首先我們?cè)贚uatOS模擬器上運(yùn)行一下這個(gè)demo項(xiàng)目,讓大家對(duì)實(shí)現(xiàn)的功能有一個(gè)直觀的認(rèn)識(shí)

如果要在LuatOS模擬器上運(yùn)行這個(gè)項(xiàng)目,代碼需要做以下幾點(diǎn)修改:

1、netdrv_device.lua中打開(kāi)pc模擬器的網(wǎng)卡驅(qū)動(dòng)文件require "netdrv_pc",注釋掉其他其他網(wǎng)卡文件;

2、 因?yàn)檫@個(gè)demo項(xiàng)目需要用到uart功能,要在pc上模擬uart收發(fā)功能,需要在pc上安裝一個(gè)虛擬串口工具,生成一組串口,例如串口1和串口2,如果這兩個(gè)串口id在你的pc上已經(jīng)被占用,可以自定義生成任意兩個(gè)id的串口就行;


生成的這一對(duì)串口可以互相給對(duì)方發(fā)數(shù)據(jù),也能互相接收對(duì)方發(fā)送過(guò)來(lái)的數(shù)據(jù);

如果生成的是串口1和串口2,這個(gè)demo項(xiàng)目中的uart_app.lua中使用的uart1,不用修改uart_app.lua的代碼,此時(shí)在pc上使用sscom或者llcom串口工具打開(kāi)串口2即可,這樣的話,模擬器中的uart1就可以和sscom或者llcom打開(kāi)的uart2進(jìn)行收發(fā)數(shù)據(jù);

如果生成的一對(duì)串口沒(méi)有串口1,假設(shè)是串口11和串口12,則需要修改uart_app.lua中的代碼,串口id修改為11,pc上使用sscom或者llcom串口工具打開(kāi)串口12即可,這樣的話,模擬器中的uart11就可以和sscom或者llcom打開(kāi)的uart12進(jìn)行收發(fā)數(shù)據(jù);

3、創(chuàng)建一個(gè)TCP server、一個(gè)UDP server,一個(gè)TCP SSL server,根據(jù)創(chuàng)建的服務(wù)器地址和端口,修改代碼中對(duì)應(yīng)的地址和端口;

軟件環(huán)境準(zhǔn)備好之后,接下來(lái)我們?cè)谀M器上實(shí)際運(yùn)行一下這個(gè)項(xiàng)目看看效果;

雙擊 cmd 命令行窗口,然后輸入下面一行命令,運(yùn)行 luatos 批處理文件,同時(shí)輸入要運(yùn)行的 luatos 項(xiàng)目配置文件

luatos --llt=H:LuatoolsprojectAir8000_socket_client_long_connection.ini

然后按回車鍵,就可以運(yùn)行 socket_client_long_connection 項(xiàng)目軟件;

7.3 分析項(xiàng)目代碼

這個(gè)socket demo中的readme文件,以及代碼中的注釋都比較詳細(xì),接下來(lái)我用vscode直接打開(kāi)這份demo項(xiàng)目代碼,和大家一起分析下項(xiàng)目代碼;

7.4 Air8000開(kāi)發(fā)板上運(yùn)行演示這個(gè)項(xiàng)目(重點(diǎn)演示單網(wǎng)卡和多網(wǎng)卡的使用)

準(zhǔn)備硬件環(huán)境:

1、Air8000開(kāi)發(fā)板一塊+可上網(wǎng)的sim卡一張+4g天線一根+wifi天線一根+網(wǎng)線一根:

sim卡插入開(kāi)發(fā)板的sim卡槽

天線裝到開(kāi)發(fā)板上

網(wǎng)線一端插入開(kāi)發(fā)板網(wǎng)口,另外一端連接可以上外網(wǎng)的路由器網(wǎng)口或者交換機(jī)網(wǎng)口;

2、TYPE-C USB數(shù)據(jù)線一根 + USB轉(zhuǎn)串口數(shù)據(jù)線一根,Air8000開(kāi)發(fā)板和數(shù)據(jù)線的硬件接線方式為:

Air8000開(kāi)發(fā)板通過(guò)TYPE-C USB口供電;(外部供電/USB供電 撥動(dòng)開(kāi)關(guān) 撥到 USB供電一端)

TYPE-C USB數(shù)據(jù)線直接插到核心板的TYPE-C USB座子,另外一端連接電腦USB口;

準(zhǔn)備軟件環(huán)境:

1、手機(jī)打開(kāi)WiFi熱點(diǎn)zhutianhua 123qweasd,修改netdrv_wifi.lua和netdrv_multiple.lua中的WiFi信息;

2、打開(kāi)TCP/UDP web工具,創(chuàng)建一個(gè)TCP server、一個(gè)UDP server,一個(gè)TCP SSL server,根據(jù)創(chuàng)建的服務(wù)器地址和端口,修改代碼中對(duì)應(yīng)的地址和端口;

3、netdrv_device.lua分別打開(kāi)單網(wǎng)卡和多網(wǎng)卡驅(qū)動(dòng)單獨(dú)演示;

4、Luatools燒錄內(nèi)核固件以及修改后的demo腳本;

多網(wǎng)卡演示:

開(kāi)機(jī)后,在Luatools運(yùn)行日志中搜索 new adapter,如下圖所示,按照紅色文字操作演示

wKgZO2l7Bt-ASwDgAADvtPIyp20075.png

單網(wǎng)卡演示:

直接運(yùn)行日志即可;

八、如何分析LuatOS socket日志

在socket開(kāi)發(fā)使用過(guò)程中,或多或少,我們都會(huì)遇到一些問(wèn)題,遇到問(wèn)題時(shí),如果我們自己可以根據(jù)日志進(jìn)行初步分析,可能會(huì)大大提高解決問(wèn)題的效率;在本章節(jié)我們提供三種日志分析方法;

8.1 三種日志分析方法

8.1.1 Luatools抓取的應(yīng)用日志分析

這部分是Luatools抓取的應(yīng)用日志,在Luatools的主窗口可以實(shí)時(shí)顯示,如下圖所示:

wKgZPGl7B0WAa-6uAARX1OvCEvs507.png

應(yīng)用日志分為兩種類型:

1、一部分是Lua腳本中輸出的日志,有D/、I/、W/、E/幾種前綴,這部分日志,大家根據(jù)自己編寫(xiě)的Lua腳本邏輯自行分析即可;

2、另一部分是內(nèi)核固件中輸出的一些關(guān)鍵日志,沒(méi)有D/、I/、W/、E/幾種前綴,這部分日志,大家不知道所表示的意義,我們會(huì)在本章節(jié)的以下內(nèi)容中針對(duì)一些常見(jiàn)的日志進(jìn)行逐一分析;

8.1.2 抓取LuatOS模擬器上的網(wǎng)絡(luò)交互包進(jìn)行分析

socket應(yīng)用完全可以在LuatOS模擬器上運(yùn)行,所以我們可以使用LuatOS模擬器來(lái)運(yùn)行自己的程序;

在運(yùn)行過(guò)程中使用wireshark抓取網(wǎng)絡(luò)交互包,進(jìn)行詳細(xì)分析,例如下圖是在LuatOS模擬器運(yùn)行過(guò)程中,tls+單向認(rèn)證連接服務(wù)器失敗的網(wǎng)絡(luò)交互包,從交互包中可以準(zhǔn)確的得知,失敗原因是Unknown CA,未識(shí)別的CA證書(shū)

wKgZPGl7B5KAKJ9eAAak63jhrR8737.png

這種分析方法對(duì)于解決socket,http,mqtt,ftp等網(wǎng)絡(luò)應(yīng)用的問(wèn)題,幫助很大!

8.1.3 Luatools抓取的底層日志網(wǎng)絡(luò)交互包分析

這里所說(shuō)的抓取底層日志網(wǎng)絡(luò)交互包分析,和 8.1.2 抓取LuatOS模擬器上的網(wǎng)絡(luò)交互包進(jìn)行分析 相比,一個(gè)是在真實(shí)的硬件板上(例如Air8000)運(yùn)行抓日志,一個(gè)是在LuatOS模擬器上運(yùn)行抓網(wǎng)絡(luò)交互包;

在真實(shí)的硬件板上抓到日志后,然后再使用底層日志分析工具提取出來(lái)網(wǎng)絡(luò)交互包,然后再使用wireshark對(duì)提取出來(lái)的網(wǎng)絡(luò)交互包進(jìn)行分析;

和模擬器運(yùn)行直接抓網(wǎng)絡(luò)交互包相比,這種方式有以下幾種明顯的缺點(diǎn):

1、抓取日志以及分析操作繁瑣;

2、硬件板內(nèi)存資源有限,抓到的網(wǎng)絡(luò)日志會(huì)丟包,特別是網(wǎng)絡(luò)數(shù)據(jù)交互頻繁的時(shí)候,丟包問(wèn)題嚴(yán)重;

雖然有以上兩項(xiàng)缺點(diǎn),但是因?yàn)槭钦鎸?shí)的運(yùn)行環(huán)境,對(duì)于LuatOS模擬器運(yùn)行無(wú)法分析解決的問(wèn)題,最終還是要通過(guò)這種方式解決;

如果需要用到這種方式來(lái)分析解決問(wèn)題,當(dāng)前階段,只需要提交Luatools抓到的日志給我們技術(shù)人員即可,由技術(shù)人員進(jìn)行分析;

后續(xù)我們也會(huì)在docs.openluat.com寫(xiě)一篇文章,單獨(dú)講解如何使用這種方法分析問(wèn)題;大家如果有興趣,可自行查看文檔學(xué)習(xí)。

所以,在本章節(jié)接下來(lái)的內(nèi)容中,我會(huì)針對(duì)一些常見(jiàn)的問(wèn)題,分別使用Luatools應(yīng)用日志分析和LuatOS模擬器上的網(wǎng)絡(luò)交互包分析這兩種方法來(lái)講述;

8.2 socket創(chuàng)建

8.2.1 創(chuàng)建失敗

Luatools應(yīng)用日志分析

使用socket.create(adapter_id, task_name)接口創(chuàng)建socket時(shí),常見(jiàn)的錯(cuò)誤日志,如下圖所示:

wKgZO2l7CDWAPCg2AAA432sqPUY709.png

這種異常日志的意思是:無(wú)法為socket對(duì)象分配資源;

出現(xiàn)這種異常,通常是因?yàn)橥瑫r(shí)存在的socket數(shù)量超過(guò)了內(nèi)核固件限制的最大數(shù)量:

Air780系列/Air8000系列的模組,允許同時(shí)存在的socket對(duì)象數(shù)量為64個(gè);

Air6101系列/Air8101系列的模組,允許同時(shí)存在的socket對(duì)象數(shù)量為32個(gè);

通常是以下兩種原因造成的:

項(xiàng)目中開(kāi)發(fā)業(yè)務(wù)代碼時(shí),socket.create和socket.release是一對(duì)逆操作,如果不斷的create,但是沒(méi)有release,就會(huì)出現(xiàn)這種問(wèn)題,這種錯(cuò)誤的使用方式比較常見(jiàn);

例如在一個(gè)實(shí)際項(xiàng)目中,創(chuàng)建socket,socket連接,socket收發(fā)業(yè)務(wù)邏輯處理,如果業(yè)務(wù)邏輯處理過(guò)程中出現(xiàn)異常,就會(huì)斷開(kāi)socket,然后再銷毀socket;這是一套完整的操作,出現(xiàn)異常后,會(huì)從socket創(chuàng)建開(kāi)始重試;在實(shí)際代碼開(kāi)發(fā)過(guò)程中,有可能會(huì)忘記銷毀socket;這樣的話,每次重試都會(huì)創(chuàng)建一個(gè)新的socket;隨著重試的次數(shù)增多,最終同時(shí)存在的socket對(duì)象就會(huì)超過(guò)上限而出現(xiàn)錯(cuò)誤;例如下圖中,如果漏寫(xiě)了紅框內(nèi)的代碼,隨著時(shí)間的推移,最終就會(huì)出現(xiàn)問(wèn)題

wKgZPGl7CMmAXfuQAAGPj0AkFNg137.png

項(xiàng)目中正常業(yè)務(wù)邏輯,同時(shí)使用的socket數(shù)量超過(guò)了限制,這種情況下,只能簡(jiǎn)化業(yè)務(wù)邏輯,減少對(duì)socket的使用;不過(guò)這種情況幾乎不會(huì)出現(xiàn),因?yàn)橐粋€(gè)項(xiàng)目的正常業(yè)務(wù)邏輯,幾乎不會(huì)出現(xiàn)同時(shí)使用幾十個(gè)socket的情況;

LuatOS模擬器上的網(wǎng)絡(luò)交互包分析

socket創(chuàng)建失敗,不涉及網(wǎng)絡(luò)交互包,所以不適用于此方法進(jìn)行分析;

8.2 socket連接

8.2.1 dns解析失敗

Luatools應(yīng)用日志分析

如下圖所示

一共四個(gè)DNS服務(wù)器,每個(gè)服務(wù)器嘗試解析3次,最終沒(méi)有解析成功,提示:dns_run 649:no ipv6, no ipv4

wKgZPGl7CUOAb0kOAAPfpdyDer0679.png

出現(xiàn)此種錯(cuò)誤,可以通過(guò)以下幾步嘗試分析解決:

1、確認(rèn)下域名輸入是否正確;

2、參考socket.setDNS(adapter_id, dns_index, ip)的說(shuō)明配置自定義的DNS服務(wù)器;

LuatOS模擬器上的網(wǎng)絡(luò)交互包分析

wKgZPGl7CWmAVEXyAAiGIFMF_js370.png

8.2.2 tcp握手連接失敗

Luatools應(yīng)用日志分析

當(dāng)對(duì)端ip地址存在,端口不存在時(shí),例如:連接netlab tcp服務(wù)器,ip地址為:112.125.89.8,端口42145(不存在)

會(huì)有以下異常日志:net_lwip_tcp_err_cb 662:adapter 1 socket 24 not closing, but error -14

wKgZO2l7CaKAF2Z4AACVWVv_sWI004.png

這里有一個(gè)錯(cuò)誤值:-14,表示:

ERR_RST = -14

  • 含義:連接被重置;
  • 場(chǎng)景:TCP 連接收到對(duì)端發(fā)送的 RST(重置)報(bào)文,導(dǎo)致連接強(qiáng)制關(guān)閉;

意味著,tcp連接已經(jīng)發(fā)到了對(duì)端ip地址,但是被對(duì)端直接給rst了;

還有一種常見(jiàn)的錯(cuò)誤是對(duì)端IP不存在,此時(shí)在異常日志中的錯(cuò)誤值很可能是:-13;

如下圖所示,連接一個(gè)不存在IP地址:113.126.89.86

net_lwip_tcp_err_cb 662:adapter 1 socket 5 not closing, but error -13

這里有一個(gè)錯(cuò)誤值:-13,表示:

ERR_ABRT = -13

  • 含義:連接被中止。
  • 場(chǎng)景:TCP 連接被本地或?qū)Χ水惓V兄梗ㄈ缡盏?RST 包,或本地主動(dòng)調(diào)用tcp_abort)。

具體到本日志,因?yàn)閷?duì)端ip不存在,所以應(yīng)該是tcp三次握手過(guò)程中,超時(shí),內(nèi)核固件主動(dòng)斷開(kāi)了連接;

在LuatOS內(nèi)核固件中,使用的是LwIP協(xié)議棧,此處的錯(cuò)誤值的完整的取值范圍如下所述(大家在平時(shí)開(kāi)發(fā)過(guò)程中,如果遇到異常,根據(jù)日志中的錯(cuò)誤值,可以參考這部分說(shuō)明自行簡(jiǎn)單分析下是什么原因):

1、ERR_OK = 0:無(wú)錯(cuò)誤,操作成功;

2、ERR_MEM = -1:內(nèi)存分配失?。?/p>

3、ERR_BUF = -2:

含義:緩沖區(qū)錯(cuò)誤(不足或大小不匹配)。

場(chǎng)景:發(fā)送數(shù)據(jù)時(shí)緩沖區(qū)空間不足(如pbuf大小不夠存放待發(fā)送數(shù)據(jù)),或接收時(shí)緩沖區(qū)溢出。

4、ERR_TIMEOUT = -3

含義:操作超時(shí)。

場(chǎng)景:TCP 連接超時(shí)(未收到 SYN-ACK)、ARP 請(qǐng)求超時(shí)(未收到目標(biāo) MAC 地址應(yīng)答)、netconn_recv等待數(shù)據(jù)超時(shí)等。

5、ERR_RTE = -4

含義:路由錯(cuò)誤(無(wú)可用路由)。

場(chǎng)景:發(fā)送 IP 數(shù)據(jù)包時(shí),lwip 路由表中找不到目標(biāo) IP 地址的有效路由(如未配置默認(rèn)網(wǎng)關(guān)且無(wú)直連路由)。

6、ERR_INPROGRESS = -5

含義:操作正在進(jìn)行中。

場(chǎng)景:非阻塞模式下的操作(如tcp_connect)尚未完成,需等待后續(xù)回調(diào)通知結(jié)果。

7、ERR_VAL = -6

含義:無(wú)效值(參數(shù)值非法)。

場(chǎng)景:傳入 API 的參數(shù)值超出合法范圍(如端口號(hào)為 0 或大于 65535,IP 地址格式錯(cuò)誤等)。

8、ERR_WOULDBLOCK = -7

含義:操作會(huì)阻塞(非阻塞模式下)。

場(chǎng)景:非阻塞模式下調(diào)用netconn_recv時(shí)暫無(wú)數(shù)據(jù)可接收,或tcp_send時(shí)發(fā)送窗口未滿導(dǎo)致無(wú)法立即發(fā)送。

9、ERR_USE = -8

含義:地址已被使用。

場(chǎng)景:綁定端口時(shí)(udp_bind、tcp_bind),指定的端口已被其他連接占用。

10、ERR_ALREADY = -9

含義:已在連接中。

場(chǎng)景:對(duì)已處于連接過(guò)程中的 TCP 控制塊再次調(diào)用tcp_connect。

11、ERR_ISCONN = -10

含義:連接已建立。

場(chǎng)景:對(duì)已連接的 TCP 連接再次調(diào)用tcp_connect,或?qū)σ堰B接的netconn執(zhí)行不需要連接的操作(如bind)。

12、ERR_CONN = -11

含義:未連接狀態(tài)。

場(chǎng)景:對(duì)未建立連接的netconn調(diào)用send,或關(guān)閉未連接的連接。

13、ERR_IF = -12

含義:底層網(wǎng)絡(luò)接口(netif)錯(cuò)誤。

場(chǎng)景:網(wǎng)絡(luò)接口未初始化、鏈路斷開(kāi)(如以太網(wǎng)物理層未連接),導(dǎo)致數(shù)據(jù)包無(wú)法發(fā)送。

14、ERR_ABRT = -13

含義:連接被中止。

場(chǎng)景:TCP 連接被本地或?qū)Χ水惓V兄梗ㄈ缡盏?RST 包,或本地主動(dòng)調(diào)用tcp_abort)。

15、ERR_RST = -14

含義:連接被重置。

場(chǎng)景:TCP 連接收到對(duì)端發(fā)送的 RST(重置)報(bào)文,導(dǎo)致連接強(qiáng)制關(guān)閉。

16、ERR_CLSD = -15

含義:連接已關(guān)閉。

場(chǎng)景:對(duì)已正常關(guān)閉的連接執(zhí)行讀寫(xiě)操作(如tcp_send在連接關(guān)閉后調(diào)用)。

17、ERR_ARG = -16

含義:非法參數(shù)(參數(shù)類型或指針無(wú)效)。

場(chǎng)景:傳入 API 的參數(shù)為NULL(如netconn_new傳入無(wú)效的協(xié)議類型,tcp_send傳入NULL緩沖區(qū))。

18、ERR_IF_HIGH_WATER = -17

含義:底層網(wǎng)絡(luò)接口達(dá)到高水位線(緩沖區(qū)滿)。

場(chǎng)景:網(wǎng)絡(luò)接口發(fā)送緩沖區(qū)已滿,暫時(shí)無(wú)法接收新的發(fā)送請(qǐng)求(通常用于流量控制)。

19、ERR_IF_SUSPEND = -18

含義:底層網(wǎng)絡(luò)接口被掛起。

場(chǎng)景:網(wǎng)絡(luò)接口因某種原因(如手動(dòng)暫停、錯(cuò)誤恢復(fù)中)暫時(shí)不可用。

20、ERR_IF_OOS = -19

含義:底層網(wǎng)絡(luò)接口處于 “OutOfService”(服務(wù)中斷)狀態(tài)。

場(chǎng)景:網(wǎng)絡(luò)接口硬件故障、驅(qū)動(dòng)錯(cuò)誤等導(dǎo)致完全無(wú)法提供服務(wù)。

LuatOS模擬器上的網(wǎng)絡(luò)交互包分析

wKgZPGl7CmWAbfT6AArLXYpnXH8311.png

8.2.3 tls握手連接失敗

Luatools應(yīng)用日志分析

在tls連接+僅支持單向認(rèn)證的場(chǎng)景中,如果我們?cè)诳蛻舳伺渲昧隋e(cuò)誤的CA證書(shū),本來(lái)應(yīng)該是baidu_parent_ca.crt文件中的內(nèi)容,現(xiàn)在配置為了錯(cuò)誤的內(nèi)容"123",如下圖所示:

wKgZPGl7CruAQKTnAAR399LM8yo762.png

在連接過(guò)程中,會(huì)有以下異常日志:network_state_shakehand 807:0x2700, 3

wKgZO2l7CtiAPPfhAACqCVohxxM042.png

這里有一個(gè)錯(cuò)誤值:0x2700,MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,表示證書(shū)驗(yàn)證失??;

在LuatOS內(nèi)核固件中,使用的是MbedTLS開(kāi)源庫(kù),TLS握手連接過(guò)程中,MbedTLS中有以下常見(jiàn)的錯(cuò)誤值(大家在平時(shí)開(kāi)發(fā)過(guò)程中,如果遇到異常,根據(jù)日志中的錯(cuò)誤值,可以參考這部分說(shuō)明自行簡(jiǎn)單分析下是什么原因,如果這里沒(méi)有覆蓋出現(xiàn)的錯(cuò)誤值,可以使用AI工具提問(wèn),例如錯(cuò)誤值為0x2700,可以提問(wèn):tls握手連接過(guò)程中,0x2700表示什么錯(cuò)誤):

1、基礎(chǔ)加密 / 解密錯(cuò)誤

MBEDTLS_ERR_SSL_DECRYPTION_FAILED(0x7080):解密失敗(如對(duì)稱加密密鑰錯(cuò)誤、密文損壞)。

MBEDTLS_ERR_SSL_BAD_HMAC(0x7082):HMAC 驗(yàn)證失?。ㄏ⑼暾孕r?yàn)不通過(guò),可能被篡改)。

MBEDTLS_ERR_SSL_BAD_RECORD_MAC(0x7084):記錄層 MAC 校驗(yàn)失?。ㄅc HMAC 類似,針對(duì) TLS 記錄的完整性)。

2、協(xié)議版本與協(xié)商錯(cuò)誤

MBEDTLS_ERR_SSL_UNSUPPORTED_VERSION(0x7000):不支持對(duì)方的 TLS 版本(如客戶端要求 TLS 1.0,服務(wù)器僅支持 TLS 1.2+)。

MBEDTLS_ERR_SSL_VERSION_MISMATCH(0x7002):版本協(xié)商不匹配(如客戶端和服務(wù)器協(xié)商的版本不一致)。

3、密碼套件與算法錯(cuò)誤

MBEDTLS_ERR_SSL_NO_SHARED_CIPHER(0x7004):無(wú)共同支持的密碼套件(客戶端與服務(wù)器的密碼套件列表無(wú)交集)。

MBEDTLS_ERR_SSL_UNSUPPORTED_CIPHERSUITE(0x7006):對(duì)方選擇的密碼套件本地不支持。

MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION(0x7008):不支持對(duì)方發(fā)送的 TLS 擴(kuò)展(如 ALPN、SNI 擴(kuò)展不被認(rèn)可)。

4、證書(shū)驗(yàn)證錯(cuò)誤

MBEDTLS_ERR_X509_CERT_VERIFY_FAILED(0x2700):證書(shū)驗(yàn)證失?。ㄈ绾灻麩o(wú)效、過(guò)期、吊銷)。

MBEDTLS_ERR_X509_UNKNOWN_CA(0x2702):證書(shū)鏈中存在未知 CA(根證書(shū)不被信任)。

MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED(0x7040):服務(wù)器要求客戶端證書(shū),但客戶端未提供。

MBEDTLS_ERR_SSL_BAD_CERTIFICATE(0x7042):證書(shū)格式錯(cuò)誤或內(nèi)容無(wú)效(如解析失敗、字段不合法)。

5、密鑰交換與認(rèn)證錯(cuò)誤

MBEDTLS_ERR_SSL_KEY_EXCHANGE_FAILED(0x7020):密鑰交換過(guò)程失?。ㄈ?RSA 密鑰解密失敗、ECDH 密鑰協(xié)商錯(cuò)誤)。

MBEDTLS_ERR_SSL_BAD_CLIENT_KEY_EXCHANGE(0x7022):客戶端密鑰交換消息格式錯(cuò)誤或內(nèi)容無(wú)效。

MBEDTLS_ERR_SSL_BAD_CERTIFICATE_VERIFY(0x7044):客戶端證書(shū)驗(yàn)證消息(CertificateVerify)無(wú)效(如簽名不匹配)。

6、握手流程與消息錯(cuò)誤

MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE(0x7060):收到意外的握手消息(如流程順序錯(cuò)誤,如先收到 Finished 再收到 Certificate)。

MBEDTLS_ERR_SSL_INVALID_HANDSHAKE_MESSAGE(0x7062):握手消息格式無(wú)效(如長(zhǎng)度錯(cuò)誤、字段缺失)。

MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE(0x7064):握手失?。ㄍㄓ缅e(cuò)誤,可能因上述多種原因?qū)е?,如服?wù)器拒絕客戶端配置)。

MBEDTLS_ERR_SSL_HANDSHAKE_TIMEOUT(0x7066):握手超時(shí)(未在規(guī)定時(shí)間內(nèi)收到對(duì)方響應(yīng))。

7、連接與狀態(tài)錯(cuò)誤

MBEDTLS_ERR_SSL_CONN_EOF(0x70a0):握手過(guò)程中連接被關(guān)閉(對(duì)方發(fā)送了關(guān)閉通知)。

MBEDTLS_ERR_SSL_CONNECTION_RESET(0x70a2):連接被重置(如底層 TCP 連接斷開(kāi))。

MBEDTLS_ERR_SSL_WANT_READ / MBEDTLS_ERR_SSL_WANT_WRITE(0x70c0 / 0x70c2):非阻塞模式下需要繼續(xù)讀寫(xiě)數(shù)據(jù)(非錯(cuò)誤,需重試)。

LuatOS模擬器上的網(wǎng)絡(luò)交互包分析

wKgZO2l7CyKAePSMAAag0U7OtqA842.png

8.2 socket收發(fā)數(shù)據(jù)和斷開(kāi)

這些業(yè)務(wù)邏輯的異常情況,就不再一一分析了,大家遇到問(wèn)題后,可以參考上面幾種異常的分析方法,自行分析;

九、課后作業(yè)

實(shí)現(xiàn)一個(gè)TCP短連接項(xiàng)目(LuatOS模擬器上或者AirXXXX硬件板上開(kāi)發(fā)調(diào)試,二選一);

項(xiàng)目需求:

1、啟動(dòng)一個(gè)tcp server;

2、開(kāi)發(fā)LuatOS項(xiàng)目,實(shí)現(xiàn)一個(gè)tcp client,每隔5分鐘循環(huán)執(zhí)行一次以下業(yè)務(wù)邏輯:

連接tcp server;如果連接失敗,退出本次循環(huán);如果連接成功,繼續(xù)向下執(zhí)行;

發(fā)送任意一包數(shù)據(jù)到server,如果發(fā)送失敗,立即斷開(kāi)連接,退出本次循環(huán);

server收到數(shù)據(jù)后,回復(fù)任意數(shù)據(jù)到client;

client等待接收數(shù)據(jù),超時(shí)時(shí)間20秒;

在20秒內(nèi),如果收到數(shù)據(jù),立即斷開(kāi)連接,退出本次循環(huán);

20秒超時(shí)沒(méi)有收到數(shù)據(jù),立即斷開(kāi)連接,退出本次循環(huán);

在以上業(yè)務(wù)邏輯過(guò)程中,如果出現(xiàn)異常,立即斷開(kāi)連接,退出本次循環(huán);

作業(yè)提交內(nèi)容:

1、2個(gè)Lua文件:main.lua,tcp_client_main.lua;

2、1個(gè)運(yùn)行日志文件


今天的內(nèi)容就分享到這里了~

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Socket
    +關(guān)注

    關(guān)注

    1

    文章

    214

    瀏覽量

    37017
  • LuatOS
    +關(guān)注

    關(guān)注

    0

    文章

    169

    瀏覽量

    2745
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    阻燃系列基礎(chǔ)知識(shí)

    我很榮幸有機(jī)會(huì)在這里與大家分享我對(duì)阻燃系列基礎(chǔ)知識(shí)的研究。今天,我們將探討的主題是“阻燃系列基礎(chǔ)知識(shí)”。在我們?nèi)粘I钪?,火?zāi)事故頻發(fā),造成巨大的財(cái)產(chǎn)損失和人員傷亡。因此,了解阻燃材料的基礎(chǔ)知識(shí)對(duì)于
    的頭像 發(fā)表于 02-06 08:07 ?548次閱讀
    阻燃系列<b class='flag-5'>基礎(chǔ)知識(shí)</b>

    LuatOS平臺(tái)下BLE藍(lán)牙開(kāi)發(fā)從入門到實(shí)踐

    者,全面介紹LuatOS中BLE模塊的基礎(chǔ)知識(shí),涵蓋角色定義(主機(jī)/從機(jī))、服務(wù)配置、特征值操作與事件回調(diào)機(jī)制,并通過(guò)一個(gè)完整的溫濕度數(shù)據(jù)上報(bào)案例,逐步演示應(yīng)用開(kāi)發(fā)全過(guò)程。 一、BLE總體介紹 ? 1.1 什么是BLE(Blue
    的頭像 發(fā)表于 02-02 16:32 ?7490次閱讀
    <b class='flag-5'>LuatOS</b>平臺(tái)下BLE藍(lán)牙<b class='flag-5'>開(kāi)發(fā)</b>從入門到實(shí)踐

    LuatOS框架的使用(上)

    在資源受限的物聯(lián)網(wǎng)終端設(shè)備中,如何實(shí)現(xiàn)快速開(kāi)發(fā)與穩(wěn)定運(yùn)行是關(guān)鍵挑戰(zhàn)。LuatOS框架通過(guò)將Lua語(yǔ)言與底層硬件抽象層深度融合,提供了一套簡(jiǎn)潔高效的開(kāi)發(fā)范式。本文將圍繞LuatOS框架的
    的頭像 發(fā)表于 01-27 19:38 ?319次閱讀
    <b class='flag-5'>LuatOS</b>框架的使用(上)

    掌握LuatOS系統(tǒng)消息:新手也能看懂的列表詳解

    你是否在LuatOS開(kāi)發(fā)中遇到過(guò)事件不響應(yīng)、回調(diào)未觸發(fā)的問(wèn)題?這很可能與系統(tǒng)消息列表的配置或使用不當(dāng)有關(guān)。作為LuatOS事件驅(qū)動(dòng)模型的核心組件,消息列表管理著所有異步消息的排隊(duì)與分發(fā)。本文以新手
    的頭像 發(fā)表于 01-13 18:12 ?214次閱讀
    <b class='flag-5'>掌握</b><b class='flag-5'>LuatOS</b>系統(tǒng)消息:新手也能看懂的列表詳解

    嵌入式應(yīng)掌握的幾種能力

    中,也會(huì)選擇使用C++來(lái)進(jìn)行開(kāi)發(fā)。 補(bǔ)充編程語(yǔ)言的知識(shí)時(shí),除了掌握語(yǔ)言本身的知識(shí)之外。還需要同時(shí)學(xué)習(xí):編譯、構(gòu)建、調(diào)試等方面的相關(guān)知識(shí)。這
    發(fā)表于 12-08 06:05

    Linux驅(qū)動(dòng)開(kāi)發(fā)的必備知識(shí)

    內(nèi)核基礎(chǔ)知識(shí): 1、熟悉 Linux 內(nèi)核的架構(gòu)、模塊系統(tǒng)、進(jìn)程管理、內(nèi)存管理等。 了解內(nèi)核的編譯和加載過(guò)程。 2、C編程技能: 精通 C 語(yǔ)言編程,包括指針操作、內(nèi)存管理、結(jié)構(gòu)體等
    發(fā)表于 12-04 07:58

    RK?平臺(tái)?Vendor Storage?開(kāi)發(fā)指南:基礎(chǔ)知識(shí)、流程與實(shí)用技巧

    備可靠性校驗(yàn)、掉電恢復(fù)等關(guān)鍵特性,是保障設(shè)備身份標(biāo)識(shí)、功能授權(quán)等核心信息安全的重要組件。本文將從基礎(chǔ)知識(shí)、開(kāi)發(fā)流程、使用途徑三方面,為開(kāi)發(fā)者梳理完整的開(kāi)發(fā)邏輯。 一、核心
    的頭像 發(fā)表于 11-22 07:11 ?1111次閱讀
    RK?平臺(tái)?Vendor Storage?<b class='flag-5'>開(kāi)發(fā)</b>指南:<b class='flag-5'>基礎(chǔ)知識(shí)</b>、流程與實(shí)用技巧

    LuatOS MCU核心庫(kù)全接觸:新手操作與功能測(cè)試攻略!

    ?MCU芯片級(jí)開(kāi)發(fā)新手如何快速掌握核心技能?本文圍繞LuatOS的MCU核心庫(kù),系統(tǒng)演示時(shí)鐘頻率獲取、唯一ID讀取、高精度計(jì)時(shí)、IO復(fù)用配置等核心功能測(cè)試,并通過(guò)豐富示例,幫助開(kāi)發(fā)
    的頭像 發(fā)表于 11-12 14:30 ?377次閱讀
    <b class='flag-5'>LuatOS</b> MCU核心庫(kù)全接觸:新手操作與功能測(cè)試攻略!

    新手必備:LuatOS MCU核心庫(kù)功能測(cè)試與實(shí)踐指南

    新手如何快速掌握MCU芯片級(jí)開(kāi)發(fā)?本文通過(guò)LuatOS的MCU核心庫(kù),全面演示時(shí)鐘頻率獲取、唯一ID讀取、高精度計(jì)時(shí)、IO復(fù)用配置等核心功能的測(cè)試流程,并提供實(shí)用示例,幫助開(kāi)發(fā)者高效入
    的頭像 發(fā)表于 11-12 14:26 ?442次閱讀
    新手必備:<b class='flag-5'>LuatOS</b> MCU核心庫(kù)功能測(cè)試與實(shí)踐指南

    LuatOS AGPS 輔助定位開(kāi)發(fā)實(shí)戰(zhàn)教程

    為解決傳統(tǒng) GPS 定位慢、功耗高的痛點(diǎn),AGPS 技術(shù)通過(guò)輔助數(shù)據(jù)注入提升效率。本教程以 LuatOS 開(kāi)發(fā)環(huán)境為基礎(chǔ),循序漸進(jìn)地講解 AGPS 輔助定位的開(kāi)發(fā)流程,包括 AGPS 服務(wù)器對(duì)接
    的頭像 發(fā)表于 10-31 17:34 ?1324次閱讀
    <b class='flag-5'>LuatOS</b> AGPS 輔助定位<b class='flag-5'>開(kāi)發(fā)</b>實(shí)戰(zhàn)教程

    零基礎(chǔ)也能玩轉(zhuǎn)TCP/IP?LuatOS上手全攻略

    TCP/IP看似復(fù)雜,但借助LuatOS的簡(jiǎn)化開(kāi)發(fā)模式,即使沒(méi)有網(wǎng)絡(luò)編程經(jīng)驗(yàn),也能在短時(shí)間內(nèi)輕松實(shí)現(xiàn)通信功能。本指南將帶你一步步用LuatOS快速入門,真正實(shí)現(xiàn)“
    的頭像 發(fā)表于 10-15 17:28 ?694次閱讀
    零基礎(chǔ)也能玩轉(zhuǎn)TCP/IP?<b class='flag-5'>LuatOS</b>上手全攻略

    快速掌握TCP/IP?LuatOS新手入門指南

    想快速上手TCP/IP通信卻不知從何開(kāi)始?LuatOS開(kāi)發(fā)者提供了簡(jiǎn)潔高效的開(kāi)發(fā)路徑。通過(guò)本指南的實(shí)操步驟,你將發(fā)現(xiàn),實(shí)現(xiàn)網(wǎng)絡(luò)連接其實(shí)比想象中更簡(jiǎn)單。 提到網(wǎng)絡(luò)應(yīng)用,就繞不開(kāi)TCP/IP ——它不
    的頭像 發(fā)表于 10-15 17:27 ?787次閱讀
    快速<b class='flag-5'>掌握</b>TCP/IP?<b class='flag-5'>LuatOS</b>新手入門指南

    突破LuatOS開(kāi)發(fā)瓶頸:三個(gè)二次開(kāi)發(fā)必備知識(shí)揭秘!

    遇到LuatOS開(kāi)發(fā)難題?或許你忽略了這三個(gè)關(guān)鍵常識(shí)。它們看似簡(jiǎn)單,卻能破解資源管理、效率提升等瓶頸問(wèn)題,為你的項(xiàng)目注入新活力,實(shí)現(xiàn)技術(shù)躍遷。 本期一起來(lái)了解LuatOS開(kāi)發(fā)需要熟悉的
    的頭像 發(fā)表于 06-23 15:05 ?503次閱讀
    突破<b class='flag-5'>LuatOS</b><b class='flag-5'>開(kāi)發(fā)</b>瓶頸:三個(gè)二次<b class='flag-5'>開(kāi)發(fā)</b>必備<b class='flag-5'>知識(shí)</b>揭秘!

    LuatOS編程基礎(chǔ)教程:手把手帶你入門物聯(lián)網(wǎng)開(kāi)發(fā)!

    對(duì)于渴望進(jìn)入物聯(lián)網(wǎng)開(kāi)發(fā)領(lǐng)域的初學(xué)者來(lái)說(shuō),LuatOS是一個(gè)理想的起點(diǎn)。本教程將通過(guò)由淺入深的教學(xué)方式,從搭建開(kāi)發(fā)環(huán)境、理解核心API到編寫(xiě)簡(jiǎn)單應(yīng)用,逐步引導(dǎo)你掌握
    的頭像 發(fā)表于 06-11 13:03 ?841次閱讀
    <b class='flag-5'>LuatOS</b>編程基礎(chǔ)教程:手把手帶你入門物聯(lián)網(wǎng)<b class='flag-5'>開(kāi)發(fā)</b>!

    快速入門——LuatOS:sys庫(kù)多任務(wù)管理實(shí)戰(zhàn)攻略!

    開(kāi)發(fā)者,這里將用最簡(jiǎn)明的步驟,助你輕松實(shí)現(xiàn)多任務(wù)應(yīng)用開(kāi)發(fā)! sys庫(kù)是LuatOS的核心系統(tǒng)調(diào)度庫(kù),它基于Lua協(xié)程機(jī)制實(shí)現(xiàn)了實(shí)時(shí)多任務(wù)調(diào)度、定時(shí)器管理以及消息通信等功能。 在詳細(xì)介
    的頭像 發(fā)表于 05-29 14:36 ?980次閱讀
    快速入門——<b class='flag-5'>LuatOS</b>:sys庫(kù)多任務(wù)管理實(shí)戰(zhàn)攻略!