国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

輕松掌握——LuatOS socket基礎知識和應用開發

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

掃碼添加小助手

加入工程師交流群

對于剛接觸LuatOS開發的工程師而言,實現設備聯網往往是第一個重要目標,而Socket編程正是實現這一目標的核心技術路徑。本文以循序漸進的方式,帶領讀者從最基礎的Socket概念入手,逐步掌握在LuatOS環境中創建客戶端與服務器、發送與接收數據等關鍵技能,為后續復雜應用打下堅實基礎。

一、主要內容

LuatOS socket是LuatOS開發中最常用到的網絡應用之一;

LuatOS socket課程主要包含以下幾個部分:

1、TCP/IP總體介紹;

2、LuatOS上的4G/WiFi/以太網三種網絡環境下的TCP/IP協議棧總體介紹;

3、TCP/UDP/SSL/證書以及socket概念;

4、LuatOS socket核心庫和libnet擴展庫功能介紹;

5、LuatOS socket client應用開發框架(TCP,UDP,SSL,網絡環境檢測看門狗);

6、如何分析LuatOS socket日志;

二、TCP/IP總體介紹

今天我們講的LuatOS socket是LuatOS開發中最常用到的網絡應用之一,用戶使用LuatOS socket開發網絡應用,會直接接觸到TCP/UDP/SSL/認證等一些網絡核心概念;

而說到網絡應用,就繞不開TCP/IP;

2.1 TCP/IP網絡模型

有網絡應用開發經驗的人,應該都聽說過OSI七層模型、TCP/IP協議四層模型和TCP/IP協議五層模型;

這三種網絡協議模型的說明,參考下表:

wKgZO2l5wtCAVdglAABaszKk-bg452.png

看了這張表之后,我們應該有以下幾點認識:

  1. 都采用了分層的思想,將復雜的通信過程分解為更小、更易于管理的部分;
  2. 每一層都為其上層提供服務,并使用其下層提供的服務;
  3. 這三種網絡模型,只是分層的顆粒度不一樣,實際上,這三種網絡模型的本質內容都是一樣的;

既然這三種網絡模型的本質內容是一樣的,為什么還要存在三種網絡模型呢?每種網絡模型又有什么作用呢?

我們簡單地看一下這三種網絡模型的歷史:

wKgZPGl5wwyACeN2AAMxMQNVAXE870.png

最終TCP/IP模型在實踐中得到廣泛應用;

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

  1. 四層模型隱藏了底層細節,將網絡接入視為一個黑盒,更關注對軟件層面的設計,不關心具體的硬件;
  2. 五層模型明確包含了物理硬件層;

四層模型和五層模型本質上是同一個東西的兩種不同表述方式,所以我們接下來不糾結四層還是五層模型,而是統稱為TCP/IP模型,下文中會根據不同的應用場景來決定選擇四層模型還是五層模型來講解。

2.2 TCP/IP協議

在了解了TCP/IP網絡模型之后,接下來我們看一下TCP/IP協議這個概念;

TCP/IP網絡模型是理論上的框架和藍圖,而TCP/IP協議是這個框架的具體實現;

我們來看下面這張表格

wKgZPGl5w8SACH4GAAB2fCy6fGQ717.png

可以看到,每一層都有多個協議去實現,在所有的這些協議中,TCP和IP兩種協議是其中的核心協議,所以用TCP/IP協議代指網絡模型中的所有協議;

所以說,TCP/IP協議 并不是兩個單一的協議,而是一個協議家族,包含TCP/IP網絡模型中的所有協議;

所有協議協同工作,從軟件上完成了互聯網上的數據傳輸任務;

2.3 TCP/IP協議的核心工作原理

TCP/IP協議通過功能分層以及數據封裝/解封裝,來協同工作完成網絡數據傳輸任務;

2.3.1 功能分層

下層為上層提供服務,上層使用下層提供的服務;

每一層都只專注于自己的任務;

TCP/IP五層模型,從上到下劃分為應用層,傳輸層,網絡層,數據鏈路層,物理層;

每一層的主要功能如下:

1.應用層:應用層的主要工作是定義數據格式并按照對應的格式解讀數據,應用層定義了各種各樣的協議來規范數據格式,常見的有 HTTP、MQTT、FTP、WebSocket等;

例如常見的HTTP協議,服務端收到客戶端的請求以后,就能按照HTTP報文的格式,正確地解析客戶端發來的數據,當請求處理完以后,再按照HTTP報文的格式返回結果給客戶端,客戶端收到結果后,按照HTTP報文的格式進行解析;

2.傳輸層:傳輸層的主要工作是定義端口,標識應用程序身份,實現端到端的通信,為應用層的應用程序提供可靠的或不可靠的數據傳輸服務;

數據包是從發送端設備的某個應用程序發出,然后由接收端設備的某個應用程序接收。而每臺設備都有可能同時運行著很多個應用程序,所以要通過傳輸層定義的端口來確認使用的是設備上的哪一個應用程序;

例如HTTP應用程序的默認端口就是80,也可以自定義端口;

3.網絡層:網絡層的主要工作是定義網絡IP地址,區分網段,邏輯尋址和在不同的公共網絡之間進行路由選擇;

網絡層的通信視野是全局的,它從源IP地址出發,最終要到達目的IP地址,中間可能經過無數個不同的網絡(例如以太網、Wi-Fi、4G LTE等),它管的是“全局”的事情;

例如下圖中紅框所標注的網絡單元中的網絡路由選擇,就是靠網絡層實現的:

wKgZPGl5xPmAJk2tAALsx6pVQ7A125.png

4. 數據鏈路層:數據鏈路層的主要工作是在本地局域網內將數據發送給接收方;

可以是帶交換機功能的WiFi路由器和這個WiFi下的設備相互發送數據,或者這個WiFi路由器下的兩個設備相互發送數據;

也可以是以太網交換機和這個交換機下的設備相互發送數據,或者這個交換機下的兩個設備相互發送數據;

也可以是4G網絡中,某個運營商基站和這個基站下的設備(例如手機)相互發送數據;

本地局域網的數據鏈路層也需要尋址,以太網和WiFi網絡環境中,需要用到設備的MAC地址進行尋址;4G網絡中,需要用到RNTI(無線網絡臨時標識符)進行尋址;

數據鏈路層的通信視野是局部的,只負責局域網內將數據發送給接收方,它管的是“局部”的事情;

例如下圖中紅框所標注的網絡單元中的局域網內的尋址,就是靠數據鏈路層實現的:

wKgZO2l5xSOANGCKAALwg7FK6gA151.png

5. 物理層:物理層的主要工作是傳輸0和1的電信號,這些電信號通過物理傳輸介質進行傳輸;

常見的物理層傳輸介質有:

(1) 光纖(我們日常生活中可以接觸到的就是,運營商將光纖直接從運營商機房鋪設到用戶家中,提供百兆、千兆的高速互聯網接入。你家辦理的中國電信、聯通或移動的“千兆光網”。你家的“光貓”就是接收光信號并將其轉換為電信號的設備。)

(2) 雙絞線(例如在以太網網絡環境中常用的網線就是雙絞線的一種)

(3) 無線電波(例如Wi-Fi、4G、5G網絡都必須依賴無線電波作為載體才能進行通信。它們本質上都是通過調制解調技術,將數字信號(0和1)加載到無線電波上發射出去,接收端再解調回來)

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

例如下圖中紅框所標注的網絡單元間的數據傳輸,就是靠物理層實現的:

wKgZO2l5xUyAMhm-AALo2sZfs3U023.png

TCP/IP協議的上面四層(應用層,傳輸層,網絡層,數據鏈路層),可以理解為是軟件層面的實現,最終封裝成數據包;

而TCP/IP協議的最下面一層(物理層)將數據包轉化為 0 和 1 的電信號,通過物理介質進行傳輸才能到達下一個網絡單元,因此物理介質可以認為是網絡通信的基石。

大家現在對每一層的功能先有一個總體認識即可,不用關注細節;

后續會有各種網絡環境下的實例來進一步說明如何工作;

2.3.2 數據封裝/解封裝

理解了功能分層的概念之后,我們再來看下面這張圖片,了解一下數據的封裝和解封裝;

wKgZPGl5xYuAQjcNAAJILH8YQLc550.pngwKgZO2l5xaaAG7kZAAaVfY_FBl4758.png

1、在數據發送端,應用層的網絡協議生成應用數據;

2、應用數據向下傳,交給傳輸層,增加了傳輸層的頭部信息,在頭部信息中,有很多字段,其中有兩個字段分別是源端口號和目標端口號,這兩個端口號的作用是:定義了發送端和接收端的應用程序,例如http應用的默認端口號是80;可以提供兩個主機之上端到端的通信;

3、傳輸層頭部+應用數據向下傳,交給網絡層,增加了網絡層的頭部信息,在頭部信息中,有很多字段,其中有兩個字段分別是源IP地址和目標IP地址,這兩個IP地址的作用是:定義了發送端和接收端的網絡設備地址;可以提供主機到主機的通信;

4、網絡層頭部+傳輸層頭部+應用數據向下傳,交給數據鏈路層,增加了數據鏈路層的頭部信息;

5、最終,數據鏈路層頭部+網絡層頭部+傳輸層頭部+應用數據的數據包,通過物理層轉換為0和1的電信號,然后通過物理傳輸介質發給了接收端;

6、接收端收到數據后,從下到上,依次解析并且剝離出數據鏈路層頭部、網絡層頭部、傳輸層頭部,最終將應用數據交給應用程序去處理;

7、接收端處理完應用數據后,如果需要返回應用數據給發送端;此時發送端和接收端的角色互換,再走一遍數據分層的封裝和解封裝過程;

了解了功能分層和數據封裝/解封裝的核心工作原理之后,大家可能對TCP/IP網絡數據傳輸的理解還是比較模糊,因為剛才說的這些都是偏理論的東西,理解起來不是那么直觀;

接下來我使用電腦的網絡瀏覽器訪問http://airtest.openluat.com/,抓取一個完整的數據包封裝實例,再來加深一下對功能分層和數據封裝/解封裝的理解:

wKgZPGl5xhOAPemfAAJRXeTanx4567.png

接下來我們打開下面這張圖片,實際分析一下http請求數據包

wKgZPGl5xj6AFMJLAAdoxCY2SDs242.png

通過上面這個http請求的網絡數據包分析,大家對 TCP/IP的功能分層以及數據封裝/解封裝 應該有了進一步的認識;

2.4 不同網絡環境下的TCP/IP工作實例

講到這里,不知道大家有沒有發現,之前講述的網絡模型,網絡數據包分析,我使用的都是極度簡化后的網絡拓撲結構,只有一個網絡硬件單元或者兩個網絡硬件單元;

但是在現實世界中,網絡拓撲結構不可能如此簡單,從源設備到目標設備之間,可能要經過幾十個網絡硬件單元;

接下來,我分別以4G網絡環境、WiFi網絡環境和以太網網絡環境為例,來說明一個實例:

當使用手機或者電腦訪問https://docs.openluat.com/這個網站時,在整個TCP/IP網絡環境中,有哪些重要的網絡硬件單元在配合工作?這些網絡硬件單元之上各自分別實現了TCP/IP協議的哪幾層?這些網絡硬件單元的核心作用分別是什么?

為了方便理解,接下來的每個實例中都會給出一個總體的網絡拓撲結構圖,此處給出的網絡拓撲結構圖和之前的網絡拓撲結構圖相比,會更加詳細,但是所給出的仍然是是簡化后的網絡拓撲結構圖;

雖然也是簡化后的拓撲圖,但是這里所描述的網絡拓撲結構圖,對于我們理解整個網絡系統的工作流程,也會提供很大的幫助;可以讓我們從一個全局的視野,去理解TCP/IP是如何在整個網絡系統中配合工作的;

2.4.1 4G網絡環境下TCP/IP協議的工作實例

第一種實例:使用中國移動4G手機卡網絡的手機訪問托管在中國電信的服務器

我們打開下面這張圖總體了解一下這個過程

wKgZPGl5xziAL-dcAAj63FyzZTI187.png

第二種實例:使用中國移動4G手機卡網絡的手機訪問托管在中國移動的服務器

和 中國移動4G手機卡的手機訪問托管在中國電信的服務器 相比,中國移動4G手機卡的手機訪問托管在中國移動的服務器,不需要經過中國移動和邊界路由器和中國電信邊界路由器,在中國移動的地市、省干、國干核心路由器之間進行路由轉發,如下圖所示(差異部分已通過淺綠色背景進行區分):

wKgZO2l5x_CAdD88AAdhxn8Nj_Y872.png

2.4.2 WiFi網絡環境下TCP/IP協議的工作實例

第一種實例:使用中國移動WIFI網絡的手機訪問托管在中國電信的服務器

wKgZPGl5yF6AAM02AAjKRtN3NP0987.png

第二種實例:使用中國移動WiFi網絡的手機訪問托管在中國移動的服務器

和 中國移動WiFi網絡的手機訪問托管在中國電信的服務器 相比,中國移動4G手機卡的手機訪問托管在中國移動的服務器,不需要經過中國移動和邊界路由器和中國電信邊界路由器,在中國移動的地市、省干、國干核心路由器之間進行路由轉發,如下圖所示(差異部分已通過淺綠色背景進行區分):

wKgZO2l5yKqAFwO_AAeE5U79Rlk493.png

2.4.3 以太網網絡環境下TCP/IP協議的工作實例

第一種實例:使用中國移動以太網網絡的電腦訪問托管在中國電信的服務器

wKgZO2l5yQmAOTcAAAkei2pd9S8231.png

第二種實例:使用中國移動以太網網絡的電腦訪問托管在中國移動的服務器

和 中國移動WiFi網絡的電腦訪問托管在中國電信的服務器 相比,中國移動以太網的電腦訪問托管在中國移動的服務器,不需要經過中國移動和邊界路由器和中國電信邊界路由器,在中國移動的地市、省干、國干核心路由器之間進行路由轉發,如下圖所示(差異部分已通過淺綠色背景進行區分):

wKgZPGl5yVKAcHibAAfEZw3t5Fg849.png

三、LuatOS上的TCP/IP協議棧總體介紹

在總體了解了TCP/IP的核心理論知識,以及不同網絡環境下的TCP/IP工作實例之后,大家對TCP/IP應該具備了一個總體的認識;

接下來我們一起看下LuatOS上對TCP/IP協議棧的支持情況,以及提供了哪些編程接口給LuatOS項目應用腳本來使用,參考下表:

wKgZPGl5yduAKukKAAINrjmY47s500.png

四、TCP/UDP/SSL/證書以及socket概念

經過上一節的學習,大家對LuatOS上TCP/IP網絡應用的總體支持情況,應該有了一個總體的認識;

因為我們本講課程是要講解LuatOS socket,所以從本節開始,我們重點學習一下和socket有關的理論知識和實踐方法;

先簡單地看一下socket的概念:

socket是TCP/IP提供的網絡應用開發的編程接口,包含地址、端口、傳輸層/安全層協議 三部分;

地址比較好理解,可以是域名地址,也可以是ip地址,用來標識網絡上的一臺設備;

端口也比較好理解,在socket應用中,服務器端的端口一般都是服務器自定義的,用來標識自定義的應用;

傳輸層/安全層協議包括TCP/UDP/SSL/證書的知識,這一部分知識有點兒復雜,接下來我們重點看下TCP/UDP/SSL/證書的一些理論知識;

4.1 TCP/UDP

先來看一張TCP/UDP的對比表格:

wKgZO2l5yliAPLFrAAAiI5_lbM8434.png

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

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

4.1.1 是否面向連接

TCP的“面向連接”不僅僅是一個形式,而是實現其所有可靠性保障的基礎。它的作用可以概括為:為后續可靠、有序的數據傳輸做好必要的準備工作和管理工作。

具體來說,它的作用體現在以下兩個關鍵階段:

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

在發送任何實際應用數據之前,客戶端和服務器必須通過三次握手建立一個雙向的通信通道;

過程:

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

抓包分析:

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

下面我們對一個TCP連接成功的網絡包進行分析:

wKgZO2l5y1CAFNoSAAEf_Rn82-8719.pngwKgZO2l5y3iACZYbAAGbGgufWi4126.png

下面我們對一個TCP連接失敗的網絡包進行分析,客戶端去連接一個不存在的服務器:

wKgZPGl5y6mAY6svAAGJrfKpCXw802.png

作用:

  • 交換初始序列號 (ISN): 這是最核心的作用。序列號是TCP實現可靠性(確認、重傳、排序)的根基。雙方通過握手告知對方自己將從哪個號碼開始編號字節數據。
  • 確認雙方通信能力: 證明客戶端和服務器之間的網絡路徑在兩個方向上(Client->Server 和 Server->Client)都是通的。如果握手失敗,說明根本沒法通信,應用層會立刻得到錯誤信息,而不用等待數據傳輸超時。
  • 分配資源: 在握手成功后,雙方的操作系統都會為這個連接分配資源,如創建socket、分配發送和接收緩沖區等。如果連接無法建立,就避免了資源的浪費。

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

過程:

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

抓包分析:

wKgZO2l5zC-AJzZbAADHmSYMAQ0285.png

作用:

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

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

而UDP呢?提供的是一個無連接的傳輸層服務,意思就是在正式發送應用數據之前,客戶端和服務端沒有三次握手連接,客戶端和服務器端之間沒有網絡數據交互,如下圖所示:

wKgZO2l5zGuAIaHbAAJGW-JFi8U948.png

同理,因為就沒有連接動作,所以UDP斷開時,也沒有四次揮手的斷開連接動作;

4.1.2 是否可靠

TCP 提供的是一種可靠的傳輸層服務;TCP 通過多種機制確保數據準確無誤地送達:

1、確認應答機制 (ACK): 接收方收到數據后,會發送一個確認報文(ACK)給發送方。

2、超時重傳機制: 發送方在發送一個數據段后啟動一個定時器。如果在規定時間內沒有收到對應的ACK,它會重新發送該數據段。

3、序列號和確認號機制: 每個字節的數據都被分配一個序列號(Seq),ACK號則告訴發送方“我期望收到的下一個字節的序列號是多少”。這解決了數據包亂序和重復的問題。

4、校驗和機制: 每個數據包都包含一個校驗和。接收方會驗證它,如果校驗失敗則丟棄該包,從而觸發發送方的重傳機制。

wKgZPGl5zPSAbjayAAGgXJ_IXPE631.pngwKgZO2l5zQuAX5UAAAMiCW9rVFM652.png

而UDP沒有這些可靠的機制,我們看一下UDP發送數據的網絡包:

wKgZPGl5zUWADPmVAAFsLzSF5XA546.pngwKgZPGl5zV2AGJ1gAAKc0SbsDBc150.png

和TCP相比,UDP數據發送出去之后,沒有機制確認數據是否發送成功;在網絡不穩定的情況下,會出現丟失數據的問題;

4.1.3 是否支持流量控制

TCP 提供的是一種支持流量控制的傳輸層服務;TCP 通過滑動窗口協議確保數據準確無誤地送達:

使用滑動窗口協議來防止發送方發送數據過快,導致接收方緩沖區溢出。

接收方在ACK中會告知發送方自己當前剩余的緩沖區大?。ù翱诖笮。?,發送方根據這個窗口大小調整發送速率。

wKgZPGl5zY6ACdFCAAWHyrh95Nw120.pngwKgZO2l5zaaASYSsAAf02kX3ILY954.png

下面的例子是一個出現0窗口的網絡包,因為我這邊沒有環境復現這個問題,所以從網上找了一張圖片,給大家看一下:

wKgZPGl5zcaAKBmRAAMiQdOx7_E996.png

而UDP是沒有ACK機制的,所以也沒有窗口控制協議;

4.2 數字證書

4.2.1 數字證書是什么?

數字證書,是一種數字文件,其核心作用類似于現實世界中的身份證或營業執照。

它的根本目的是:將一個數字證書中的公鑰與一個實體(個人、設備、組織、域名)的身份信息進行強綁定,并由一個受信任的第三方進行擔保。

簡單來說,數字證書就是證明“這個公鑰確實屬于某某某” 的電子憑證。

4.2.2 為什么需要數字證書?

要理解證書的價值,必須先理解它要解決的問題:中間人攻擊。

  • 當客戶端(如瀏覽器)訪問一個服務器時,如果一個攻擊者攔截了通信,他可以將自己的數字證書(包含公鑰)發送給客戶端,并冒充服務器。
  • 客戶端用攻擊者的公鑰加密數據。
  • 攻擊者截獲數據,用自己的私鑰解密,竊取信息。
  • 攻擊者再用服務器的真實公鑰加密數據,轉發給服務器。整個過程神不知鬼不覺。

核心問題:如何確保你拿到的服務器的證書公鑰,確實來自你真正想通信的一方,而不是攻擊者?

數字證書就是答案。它由一個受信任的第三方機構(Certificate Authority, CA)對公鑰和身份信息進行簽名,任何信任該CA的人都可以驗證這張證書的真偽,從而信任其中的公鑰。

4.2.3 數字證書里包含什么?(X.509標準)

數字證書遵循X.509標準格式。它包含以下核心信息:

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

我們現在訪問docs.openluat.com,看下docs網站的數字證書:

wKgZO2l5zr-AHVa4AAERZSbuFbE039.pngwKgZO2l5ztGAVFfPAACCm6Ow0yk308.png

點擊docs.openluat.com的證書文件的每個字段,我們來對照說明一下;

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

數字證書的信任并非憑空產生,它依賴于一個層級化的信任模型,稱為公鑰基礎設施(Public Key Infrastructure, PKI)。

4.2.4.1 信任鏈的組成:

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

如下圖所示,docs.openluat.com服務器使用就是一個三層證書結構:

wKgZPGl5z2-AEO2BAADldhS1SpY249.png

4.2.4.2 證書驗證過程(以瀏覽器訪問https://docs.openluat.com網站為例):

當瀏覽器收到網站的證書時,它會執行以下驗證步驟:

1. 驗證基本信息:檢查證書的有效期是否當前時間在內,檢查證書的“主題”或“SAN”字段是否包含正

wKgZPGl5z56AGzIlAAJfEhoxk3I061.png

2. 驗證簽名(構建信任鏈):

  • 瀏覽器使用中間證書A里的公鑰,去解密網站證書的數字簽名,得到一個哈希值H1。
  • 瀏覽器對網站證書的內容(除簽名外)用相同的哈希算法計算,得到另一個哈希值H2。
  • 如果H1 == H2,則說明:
  • 網站證書的內容完整,未被篡改。
  • 該證書確實是由中間證書A對應的CA簽發的(因為只有用中間CA的私鑰才能生成能用其公鑰解開的簽名)。

wKgZO2l5z_SAc8vRAADbSiE1vLs228.png


3. 遞歸驗證:

  • 瀏覽器接著發現,它可能不直接信任中間證書A。于是它繼續向上驗證:使用根證書的公鑰,去驗證中間證書A的簽名。
  • 因為根證書的公鑰已經內置在瀏覽器的信任存儲中,且是自簽名的,驗證到此結束。
wKgZO2l50DOALWwaAADWJ9afdDw540.png

4. 吊銷檢查:瀏覽器還會通過證書吊銷列表(CRL) 或在線證書狀態協議(OCSP) 查詢該證書是否已被CA提前吊銷(例如因為私鑰泄露)。

5. 最終信任:所有步驟都通過后,瀏覽器才最終信任該網站證書,并使用證書中的公鑰與服務器進行加密通信;

數字證書的知識,理解起來可能有點兒復雜,即使大家不了解關系也不大,最終在LuatOS socket編程中,如果用到證書,使用起來會非常簡單,在下文中我們會重點說明如何使用;

4.3 SSL/TLS

4.3.1 什么是 SSL/TLS?

SSL(Secure Sockets Layer,安全套接層) 和 TLS(Transport Layer Security,傳輸層安全) 是加密協議,旨在為計算機網絡通信提供安全性和數據完整性。它們的核心目標是建立一個安全的通信通道,防止竊聽、篡改和消息偽造。

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

主要目標:

1、加密(Encryption): 混淆傳輸的數據,防止第三方竊聽。

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

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

4.3.2 為什么需要 SSL/TLS?

在沒有 SSL/TLS 的情況下,網絡通信(如 HTTP、FTP、SMTP)以純文本形式傳輸。這意味著在你和服務器之間的任何節點(如你的路由器、ISP、公共Wi-Fi熱點)都可以看到你發送的所有內容,包括密碼、信用卡號、私人消息等。SSL/TLS 通過在傳輸層之上建立一個加密層來解決這個問題,從而保護上層應用協議(如 HTTP→HTTPS)。

例如,如果一個TCP Client連接上一個TCP Server之后,如果TCP Client給Server發送數據LuatOS,在整個網絡傳輸過程中的任何節點(局域網的交換機和路由器,基站,服務網關,數據網關,核心路由器,邊界路由器)都能看到明文數據LuatOS,如下圖所示:

wKgZO2l50U6AUOP8AAPxb53k1MA266.png


如果在TCP之上支持了TLS,在傳輸數據之前,Client和Server會動態協商一個密鑰,密鑰協商成功后,后續發送方傳輸的應用數據都會通過密鑰加密,然后再傳輸到接收方,接收方使用密鑰進行解密;只有發送端和接收端的應用程序才能加密數據以及解密為原始明文數據,在網絡傳輸過程中,網絡中間節點因為不知道密鑰,即使截獲了數據,因為沒有密鑰,也無法解密數據,如下圖所示:

wKgZPGl50X6ACvoGAAK_h03M-7Q495.pngwKgZPGl50ZGAZQ-AAAZ_7CEFrh0375.png

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

SSL/TLS 的核心是其握手過程。這個過程在雙方開始傳輸實際應用數據之前進行,目的是協商連接參數、驗證身份并生成會話密鑰。以下是TLS 1.2 握手流程:

整個過程的目標是在客戶端和服務器之間安全地協商出兩樣東西:

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

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

整個握手過程在 TCP 連接建立之后進行,可以概括為以下四個主要階段和 10 個步驟:

wKgZO2l50eSAAD7LAAf-k3QVxgU919.png

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

步驟 1: Client Hello

客戶端向服務器發起握手,發送一個Client Hello消息,包含以下關鍵信息:

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

步驟 2: Server Hello

服務器響應客戶端的Hello消息,發送一個Server Hello消息,包含以下關鍵信息:

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

至此,雙方就使用哪種加密算法進行通信達成了一致。

wKgZPGl50zGAeCulAAmO2UCABAQ360.png

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

步驟 3: Server Certificate

服務器將自己的數字證書發送給客戶端。這個證書包含了服務器的公鑰、域名、頒發機構(CA)等信息,并由CA的私鑰簽名??蛻舳藭炞C該證書的有效性(是否過期、域名是否匹配、簽發者是否可信等),以確認正在通信的確實是目標服務器,而不是中間人。

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

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

步驟 5: Server Hello Done

服務器發送一個Server Hello Done消息,表示它已經將所有初始協商信息發送完畢。

wKgZPGl505aAbrzHAAnHtr7QtlY637.png

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

步驟 6: Client Certificate(可選)

注意:此步驟僅在服務器要求對客戶端進行認證(例如銀行系統、API網關等場景)時才發生。絕大多數 HTTPS 網站訪問不需要這一步。 如果需要,服務器會在之前發送Certificate Request消息(本例未列出),然后客戶端在此步驟發送自己的證書。

步驟 7: Client Key Exchange Message

這是客戶端密鑰交換的核心步驟??蛻舳藭梢粋€ Pre-Master Secret(預主密鑰),這是一個 48 字節的隨機數。

  • 對于 RSA 套件:客戶端會用步驟 3 中收到的服務器證書里的公鑰加密這個Pre-Master Secret,然后將加密后的結果發送給服務器。
  • 對于 DHE/ECDHE 套件:客戶端會基于服務器的參數,計算并發送自己的臨時密鑰交換參數。

至此,只有擁有對應私鑰的服務器才能解密出Pre-Master Secret。

wKgZO2l50_aAXgA3AAaIiszgLO0745.png

步驟 8: Certificate Verify(可選)

如果客戶端發送了證書(步驟6),它還需要用其私鑰對之前所有握手消息的哈希值進行簽名,并發送給服務器。服務器用客戶端證書中的公鑰驗證這個簽名,以證明客戶端確實擁有該證書對應的私鑰,完成了客戶端認證。

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

此時,客戶端和服務器已經擁有了生成會話密鑰的所有材料:

  • Client Random
  • Server Random
  • Pre-Master Secret

雙方使用相同的偽隨機函數(PRF),根據這三個參數獨立計算出相同的:

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

步驟 9: Change Cipher Spec

客戶端發送一個Change Cipher Spec消息。這是一個簡單的信號,通知服務器:“從現在開始,我發送的所有消息都將使用我們剛剛協商好的加密算法和密鑰進行加密?!?/p>

緊接著,客戶端發送Finished消息。這條消息本身已經是加密狀態,它包含之前所有握手消息的哈希值的MAC(消息認證碼)。服務器收到后,會解密并驗證這個MAC。如果驗證成功,說明:

  1. 客戶端計算出的密鑰與服務器的一致。
  2. 握手過程沒有被篡改。
wKgZPGl51PyAUKM4AAdCEzcR8YM359.png

步驟 10: Change Cipher Spec & Finished

服務器同樣發送Change Cipher Spec消息,通知客戶端:“我也準備好了,后續消息將加密?!?/p>

緊接著,服務器發送加密后的Finished消息。客戶端同樣進行解密和驗證。

wKgZPGl51SaAHO7FAAVfL_wC4cE164.png

握手完成

至此,TLS 1.2 握手全部完成。一個安全的加密通道已經建立。之后所有的應用數據(HTTP請求/響應等)都將使用協商出的對稱會話密鑰進行加密和完整性保護。

4.3.4 TLS和TCP/UDP是什么關系?

TLS 運行在 TCP 之上,為基于 TCP 的應用提供安全;

而 TLS 本身不能直接運行在 UDP 之上,但有其對應的安全版本 DTLS;DTLS應用沒有TLS廣泛,所以本講課程不再講述DTLS,大家有興趣可以自行上網學習了解;

我們再來看一下這張OSI七層模型 和 TCP/IP五層模型表格:

wKgZO2l51XCAWSWQAACvrByoYFs197.png

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

TCP/UDP 屬于傳輸層。它們的主要職責是建立主機到主機的連接,解決數據如何可靠(TCP)或高效(UDP)地送達的問題。

TLS 大致對應于表示層。它不關心數據如何送達,它的職責是解決數據在送達后內容是否安全的問題,即加密、身份認證和完整性驗證。

一個非常恰當的比喻:

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

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

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

4.4 socket概念

在了解了TCP/UDP/TLS/證書知識之后,大家可能覺得這些內容太復雜了,如果在編程過程中,直接操作這么復雜的接口,簡直是一個災難!

這時socket就出現了,socket的中文名稱是套接字;

socket是TCP/IP提供的網絡應用開發的編程接口,包含地址、端口、傳輸層/安全層協議 三部分;

socket 是網絡應用程序與網絡協議棧(TCP/IP棧)之間的橋梁,用戶可以直接使用socket api,而socket內部設計會根據用戶的api配置選擇對應的傳輸層和安全層協議,可以大大簡化網絡編程工作量。

LuatOS上也支持socket編程接口,提供了socket核心庫和libnet擴展庫兩個庫文件;


接下來我們重點看下這兩個庫的使用方法;

五、LuatOS上的socket核心庫

5.1 常量詳解

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

5.1.1 網絡適配器編號:

注意:

1. 網絡適配器,它的一個更廣為人知的名字是——網卡,后續我們會使用網卡和網絡適配器這兩種名稱,大家只要知道這兩種名稱表示同一個概念就行了;

2. LuatOS上的網絡適配器和電腦上的網絡適配器的作用是完全一樣的,我們先來看一張電腦上的網絡適配器圖片

wKgZO2l51ySACAE4AADg8-g5sHk760.png

在上面這張圖片中,有WiFi網卡、標準的物理以太網卡、虛擬的USB RNDIS以太網卡三種網卡;

3. 從下面這張TCP/IP五層模型圖中,我們再進一步理解下網卡這個概念

wKgZO2l5126AUHRAAACKNkdo-Uk497.png

網卡主要實現的是 物理層 和 數據鏈路層 的功能;

物理層的主要功能包括:

  • 信號轉換:將數字比特流(0和1)和 能夠在物理傳輸介質(網線、光纖、無線電波)上傳輸的物理信號(如電信號、光信號、無線電波) 之間轉換;
  • 信號發送與接收:通過接口(RJ-45水晶頭、天線)向傳輸介質上發送和接收這些物理信號;

數據鏈路層的主要功能包括

  • MAC地址控制:

使用唯一的MAC地址或者RNTI標識(4G網絡中使用)來標識網卡,并處理幀的尋址問題。網卡會檢查所有流過網絡的幀,只接收目標MAC地址與自己地址匹配或為廣播地址的幀,丟棄其他所有幀;

  • 數據幀的封裝與解封裝:

發送時,將從上層(網絡層)接收到的數據包,加上幀頭(包含目標MAC地址、源MAC地址等信息)和幀尾封裝成幀;

接收時,檢查接收到的幀,去掉幀頭和幀尾,將里面的數據包提取出來交給上層的網絡層處理;

4. 可以這樣理解,從本質上說,網卡建立了一條支持發送和接收的雙向通信的數據鏈路網絡承載,網絡承載類型可以是以太網,WiFi網絡,4G網絡等;

對于應用層,傳輸層,網絡層來說,不需要關心下面的網絡承載類型,一旦網絡承載建立之后,可以使用DHCP應用層協議動態獲取ip地址或者直接配置靜態ip地址,ip地址成功獲取之后,整個網絡環境就算準備就緒,就可以使用應用層協議的接口或者使用socket接口開發具體的網絡應用了;

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

6. LuatOS上只需要直接使用默認的網卡,或者根據自己的需求調用API配置使用的某一種或者多種網卡即可,至于數據鏈路網絡承載的建立,ip地址的分配,完全由核心庫或者擴展庫自動實現,使用起來非常簡單;

7. 下面所列舉的網卡編號常量,僅僅是一個編號,關于這個編號的理解,分為以下兩種情況:

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

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 網絡事件:

"IP_RAEDY"

常量含義

表示某一個網絡適配器編號對應的網卡準備就緒,string類型; 此處的“準備就緒”是指:AirXXX硬件(例如Air780EPM)的某一個網卡在狹義或者廣義的內網內,和路由設備之間雙向通信的數據鏈路已經建立,并且已經獲取到了本地的ip地址; 4G網絡環境下,是指AirXXX硬件和4G運營商的分組數據網關之間的數據鏈路已經建立,并且分組數據網關已經給AirXXX硬件分配了運營商內部的私有ip地址;

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

wKgZO2l54OKAVUCQAANRbBlR3c0973.png

一般來說,只要使用的sim卡沒有欠費,AirXXX硬件開機之后,3秒左右就可以產生4G網卡的"IP_READY"消息;

? 以太網網絡環境下,是指AirXXX硬件(例如Air8000)通過網線和內網內的路由器之間的數據鏈路已經建立,并且路由器已經給AirXXX硬件分配了內網內部的內網ip地址或者AirXXX硬件主動設置了內網靜態ip地址;

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

wKgZPGl54RGALB4XAAMDHXLE7j4714.png

一般來說,只要通過網線和路由器之間的連接正常,2秒左右就可以產生以太網網卡的"IP_READY"消息; WiFi網絡環境下,是指AirXXX硬件(例如Air6101)通過WiFi連接上了內網的無線路由器,并且路由器已經給AirXXX硬件分配了內網的ip地址或者AirXXX硬件主動設置了內網靜態ip地址;

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

wKgZPGl54TKAKpSEAALHY7K_kx4330.png

一般來說,只要輸入正確的密碼去連接WiFi路由器,2秒左右就可以產生WiFi網卡的"IP_READY"消息;

wKgZPGl54VKAHfy9AAXaHnaExNM244.png

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

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

2、配置成功之后,LuatOS內核固件會自動執行數據鏈路的建立以及ip地址的獲取動作;

3、準備就緒后,LuatOS內核固件中會執行sys.publish("IP_RAEDY", ip, adapter)發布全局消息;"IP_RAEDY"為消息名稱,string類型;ip為本地ip地址,string類型;adapter為網卡編號,number類型,和本文5.1.1章節所描述的網絡適配器編號常量對應;

4、LuatOS應用腳本中通過sys.subscribe或者sys.waitUntil訂閱處理"IP_RAEDY"這個消息; 如果使用sys.subscribe,要在第1步之前就要訂閱,否則會有遺漏"IP_RAEDY"消息的風險; 如果使用sys.waitUntil,在sys.waitUntil之前使用socket.adapter接口主動查詢下網卡狀態, 如果查詢結果是已經準備就緒,則不再需要sys.waitUntil,否則再使用sys.waitUntil;

對某一種網卡來說,以下兩種情況會產生"IP_READY"消息:

1、初始化配置網卡之后,網卡準備就緒后,會產生"IP_READY"消息;

2、如果網卡發生掉線產生了"IP_LOSE"消息,再次準備就緒后,會產生"IP_READY"消息;

再來看另外一個問題,如果某個網卡產生了"IP_READY"消息,是不是意味著使用這個網卡,肯定可以正常訪問外網了?這個是不一定的,以下圖中的WiFi網絡為例來說明一下:

wKgZO2l54cGAbEtOAALG_Fl_uDI244.png

如果無線路由器已經正常上電,處于運行狀態,但是路由器并沒有連接外網(例如和ISP接入網的CGANT設備之間的光纖沒有連接);

這種狀態下,紅框內的數據鏈路可以正常建立,并且無線路由器也可以給手機(類似于Air8000)分配內網ip地址,Air8000就能產生"IP_READY"消息,但是Air8000并不能訪問外網,因為無線路由器無法訪問外網;

同理,4G網絡環境下,以太網環境下的"IP_READY"消息都是表示一個廣義或者狹義的內網網絡環境準備就緒,能否訪問外網,取決于內網到外網以及整個外網的網絡環境是否正常;

也就是說:

沒有"IP_READY"是不能訪問外網的;

有"IP_READY",大概率是可以訪問外網的,但是也存在一些極低極低的概率不能訪問外網;

即使如此,用戶在編程時,還是要以"IP_READY"來作為判斷可以連接外網的第一個條件,然后在應用層,使用socket,http,mqtt等網絡應用接口去實現自己的業務邏輯,如果socket,http,mqtt連接不成功,就有可能是外網不通,遇到這種情況,在socket,http,mqtt執行重連就行了,用戶不用關系鏈路層的異常的原因,只關于自己的應用層異常應該怎么處理就行了;

應用層的網絡業務的核心代碼邏輯如下所示:

wKgZPGl57OqAJ1htAAPuL7RuJts339.png

使用示例

使用sys.subscribe處理的方式:

wKgZPGl57T6AFVEZAAF7wqGKAZs268.png

使用sys.waitUntil處理的方式:

wKgZO2l57WeAfmJjAAHC2HgbS3A684.png

"IP_LOSE"

常量含義

表示某一個網絡適配器編號對應的網卡從正常狀態下發生掉線,string類型;

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

1、4G網絡環境下,sim卡不識別、sim卡欠費、沒有4G網絡信號等;

2、WiFi網絡環境下,WiFi路由器關閉、WiFi路由器做了限制、離開WiFi路由器有效信號范圍等;

3、以太網網絡環境下,以太網路由器關閉、以太網路由器做了限制、網線斷開等;

發生掉線后,LuatOS內核固件中會執行sys.publish("IP_LOSE", adapter)發布全局消息;"IP_LOSE"為消息名稱,string類型;adapter為網卡編號,number類型,和本文5.1.1章節所描述的網絡適配器編號常量對應;

使用示例

一般情況下,推薦使用sys.subscribe處理的方式來監控"IP_LOSE"消息,監控到這個消息之后,可以根據自己的項目需求走一些具體項目業務邏輯的顯示,例如通知已斷網,但是不需要手動寫代碼再去控制網卡重試連網,因為在內核固件中,會自動重試連網動作;

wKgZO2l57fOAGMzIAACO3FEctl4395.png

socket.LINK(了解即可)

關于這個常量,了解即可,LuatOS項目應用腳本程序中不推薦使用

wKgZO2l57keAXiU2AAcpyXePyP8013.pngwKgZPGl57ouAJUhCAAXKS6vqPyU368.png

socket.ON_LINE(了解即可)

關于這個常量,了解即可,LuatOS項目應用腳本程序中不推薦使用

wKgZO2l57xOALKqLAAZHrTDU1fU090.png

socket.EVENT

wKgZPGl571WAQyFrAATBRCtDGYM218.png

socket.TX_OK(了解即可)

關于這個常量,了解即可,LuatOS項目應用腳本程序中不推薦使用

wKgZO2l575aAEhLEAAYmlzYsp4c356.png

socket.CLOSED(了解即可)

關于這個常量,了解即可,LuatOS項目應用腳本程序中不推薦使用

wKgZPGl579GAPHqJAAOU7R4O6Oo817.png

5.2 函數詳解

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

這些不推薦的異步api,在libnet擴展庫中已經被封裝成了同步api,使用起來更加方便,在下一章節,我們會詳細講解這些libnet擴展庫中的同步api接口;

除此之外,socket核心庫還有一些同步api接口,這些api主要涉及到網卡操作,socket的創建、配置、讀取、銷毀等功能,本章節,我們先詳細學習一下這些同步api接口;

socket.adapter(adapter_id)

功能

查看網卡的聯網狀態

參數

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)

功能

讀取或者設置當前使用的默認網卡;

默認網卡的作用如下:

創建socket,mqtt,http等網絡應用對象時,可以通過參數主動指定要使用的網卡;

如果沒有制定,就會使用系統中的默認網卡;

例如:

socket.create(socket.LWIP_GP, "tcp_task") 表示使用socket.LWIP_GP網卡創建一個socket對象,后續這個socket對象的所有數據通信都會基于socket.LWIP_GP網卡進行;

socket.create(nil, "tcp_task") 表示使用當前時刻的默認網卡創建一個socket對象,后續這個socket對象的所有數據通信都會基于當前時刻的默認網卡進行;

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

默認網卡的設置有以下三種方式:

1、LuatOS內核固件運行起來之后,已經初始化設置了默認網卡;目前Air8000/Air780系列等默認使用的是4G網卡,編號為socket.LWIP_GP;Air6101/Air8101系列默認使用的是WiFi設備模式網卡,編號為 socket.LWIP_STA;

2、使用擴展庫exnetif中的接口exnetif.set_priority_order配置單網卡或者多網卡時,set_priority_order接口內部會根據配置自動設置默認網卡;

3、LuatOS項目的用戶應用腳本運行起來之后,在腳本中可以調用接口socket.dft(adapter_id)主動設置新的默認網卡adapter_id;

在這三種設置默認網卡的方式中:

第1種設置方式,用戶無法參與設置;

第2種設置方式,用戶可以參與設置,如果需要更改設置默認網卡,推薦使用這一種方式;這樣設置有兩個好處:

1、exnetif擴展庫已經高度集成,使用這個擴展庫提供的接口,無論是單網卡設置還是多網卡設置,使用起來非常方便;

2、默認網卡設置和具體的socket,mqtt,http網絡應用解耦,用戶只需要在初始化時配置一次,所有的網絡應用中不要再指定具體的網卡,就可以使用初始化配置的優先級使用默認網卡;

我們結合實際代碼看一下exnetif擴展庫接口的使用方式;

第3種設置方式,用戶可以參與設置,如果需要更改設置默認網卡,不推薦使用這一種方式;因為和第2種方式相比,使用起來會復雜;

參數

adapter_id

wKgZO2l584uAQdYYAAF0WkWoPVA081.png

返回值

查詢默認網卡時:

local adapter_id, last_reg_adapter_id = socket.dft()

adapter_id

wKgZPGl587OAOAxoAADSkE8BKNg338.png

last_reg_adapter_id

wKgZO2l589mAC5zOAAD4YHNcBRA959.png

設置默認網卡時:

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來設置默認網卡,所有此處不再列舉設置功能的示例,僅列舉查詢功能的示例

wKgZO2l59FKAY2gGAAJa_JwU_6k844.png

socket.localIP(adapter_id)

功能

獲取某個網卡上的本地 ip地址、網絡掩碼和網關地址;

只有網卡準備就緒后,才能讀取到這三個值;

參數

adapter_id

wKgZPGl59IOABBC4AAES9TLO5Qg179.png

返回值

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

有三個返回值 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)

功能

設置某個網卡使用的DNS服務器IP地址;

內核固件中有4個位置可以存儲DNS服務器IP地址;

對應的位置索引為本接口的dns_index參數,取值范圍為1到4;

所以最多同時存在4個DNS服務器IP地址;

DNS服務器IP地址有兩大類:

1、第一類是:網卡初始化過程中,自動從網絡運營商獲取到默認的DNS服務器IP地址;

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

2、第二類是:在應用腳本程序中調用socket.setDNS接口手動設置的自定義的DNS服務器IP地址;例如:

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

socket.setDNS(socket.LWIP_GP, 2, "114.114.114.114")表示為4G網卡在位置2設置自定義的DNS服務器IP地址"114.114.114.114",這個DNS服務器IP地址是國內通用的DNS服務器IP地址;

DNS解析服務的邏輯是:

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

如果當前位置存在DNS服務器IP地址,則解析域名,每個DNS服務器IP地址嘗試3次,每次超時分別是1秒鐘、2秒鐘、3秒鐘;

如果當前位置不存在DNS服務器IP地址,則直接跳過;

也就是說,如果4個位置上都有DNS服務器IP地址,則最多嘗試12次,最長超時24秒可以返回解析結果;

為了防止出現默認的DNS服務器IP地址解析服務器不穩定的問題,把位置3和4用來存儲默認的DNS服務器IP地址,同時,可以在位置1和2設置為自定義的DNS服務器IP地址,如下所示,為了方便用戶參考使用,我們在每個網絡應用demo中,已經為所有使用到的網卡增加了如下配置:

wKgZPGl59XiADvCAAAGUGmGbVSo774.png

參數

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)

功能

設置內核固件中ssl功能的log等級;

一般來說,當需要抓取更多的日志給我們技術人員分析時,可以使用此接口,設置輸出更多日志信息的等級;

如果打開debug開關,使用Luatools抓日志時,在主界面窗口會出現類似于下面的日志信息(出現很多mbedtls開頭的日志):

wKgZPGl59n6AdaXKAAqRZTqEy6A044.png

參數

log_level

wKgZO2l59qqAMm0MAAHT7L2OAyg700.png

返回值

nil

示例

wKgZO2l59taAJdc6AABR7JJiknY029.png

socket.create(adapter_id, task_name)

功能

在指定網卡上創建一個socket對象;

ram資源足夠的情況下:

1、Air780系列/Air8000系列的模組,允許創建的同時存在的socket對象數量為64個;

2、Air6101系列/Air8101系列的模組,允許創建的同時存在的socket對象數量為32個;

參數

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)

功能

配置是否打開內核固件中network的debug日志信息;

一般來說,當需要抓取更多的日志給我們技術人員分析時,可以打開此開關;

如果打開debug開關,使用Luatools抓日志時,在主界面窗口會出現類似于下面的日志信息(出現很多network開頭的日志):

wKgZO2l59_2ARaUIAAkKL6IPRBg312.png

參數

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對象的參數(本地端口號,TCP/UDP/TLS協議,TCP keep alive心跳參數,證書認證信息)

本地端口號,TCP/UDP/TLS協議,證書認證信息,這三部分的知識,我們在理論知識章節,已經介紹過,此處就不再重復介紹了

TCP keep alive心跳參數,之前還沒有介紹過,我們先看一下TCP keep alive心跳;

TCP Keepalive 是一種用于檢測 TCP 連接另一端是否仍然存活和可達的機制。它通過在一條空閑的連接上定期發送特殊的探測報文(Keepalive 探針)來實現;

例如客戶端和服務器建立了 TCP 連接之后,雙方再也沒有應用數據要發送。此時,連接處于空閑狀態;

但是客戶端又想一直維持這個連接,否則有可能空閑超時被網絡服務商給斷開(例如4G網絡服務商發現某個連接長時間沒有數據通信,可能是幾分鐘,也能更長時間,時間不確定,就會主動的斷開這個連接);

TCP Keepalive機制可以定時發送Keepalive 探針報文,防止連接空閑時間太長,導致連接被異常斷開;

在TCP協議的規范中,TCP Keepalive機制的數據交互過程受三個核心參數控制:

keep_idle(默認值7200秒,也就是2小時):連接空閑多長時間后,開始發送第一個 Keepalive 探針報文;

keep_interval(默認值75秒):發送第一個探針后,如果沒收到ACK回復,間隔多久再發送下一個探針;

keep_cnt(默認值9次):總共發送多少次探針后,如果依然沒有回復,則判定連接已斷開;

假設這三個參數都使用默認值,TCP Keepalive機制的工作流程如下:

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

客戶端 發送第一個 Keepalive 探針報文到服務器;

可能出現三種結果:

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

超時:客戶端等待 75 秒,沒收到ACK,則重試發送第二個探針;

錯誤:服務器回復異常報文,并且斷開連接;

如果客戶端連續發送9個探針(每兩個探針之間間隔75秒)后都超時無任何響應,客戶端就判斷連接已斷開;

連接已經斷開的情況下,從開始探測到最終檢測到已經斷開的結果,最長需要:7200 + 75 * 9 ≈ 7875秒,約 2 小時 11 分鐘;

而4G網絡環境下,最長空閑十幾分鐘,大概率就被網絡服務商給異常中斷了,所以說,這三個核心參數如果使用默認值,TCP keepalive心跳沒有任何作用,根本起不到保持長連接的作用;

所以我們在LuatOS的socket核心庫中,提供了一個接口socket.config,可以配置這三個參數的值,讓TCP keepalive真正能夠起到保持長連接的作用; 例如keep_idle可以設置為300秒,keep_interval可以設置為10秒,keep_cnt可以設置為3次;

如果使用了TCP keepalive心跳機制,并且三個核心參數配置合適,就可以不再使用應用心跳機制來保持長連接;

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

參數

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

配置為不做證書校驗的tcp ssl socket client

wKgZPGl5-0yACIfoAAG33i_eZZU244.png

配置為單向證書校驗的tcp ssl socket client

wKgZO2l5-2qARTSsAAGuc_PzJv4459.png

配置為普通的udp socket client

wKgZPGl5-5uAcbKlAAF8MDxZbzk595.png

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

功能

接收對端發送過來的數據,注意數據已經緩存在內核固件底層,使用本函數只是讀取出來;

TCP模式下,對端發送過來的一包應用數據長度,沒有特別限制;

UDP模式下,對端發送過來的一包應用數據長度,不要超過1460字節數據;

對于tcp來說,數據已經緩存到內核固件底層的數據接收緩沖區,這個數據接收緩沖區就是滑動窗口,滑動窗口的理論知識

LuatOS tcp socket本地的窗口初始大小為8040字節,在接收數據過程中,會將窗口的動態大小通知給發送方,發送方必須遵守這個窗口的限制;

例如 tcp client和server建立連接后,server應用層輸入了34560字節的數據要發送過來,點擊發送按鈕,在tcp層傳輸數據時,server會根據client這邊的動態窗口大小,動態調整發送數據的速度;先看下Luatools抓取到的Air8000的應用日志:

wKgZPGl5-_GADdUEAASsPiYUtSQ355.png

一共收到34560字節的數據,沒有丟失;

我們再看看這個數據接收過程中網絡數據交互,滑動窗口機制是如何工作的;

下面這張截圖是從Air8000的運行日志中導出的網絡數據包:

wKgZPGl6zgKAOK3yAAlfmFbwpNY508.png

所以說,tcp socket,不用關心內核固件底層的接收緩沖區有多大,也不用關心對端發送過來的數據有多少,tcp的滑動窗口機制、序列號和確認號機制、超時重傳機制,保證了數據接收的完整性;

在編程時,唯一需要注意的就是,當內核固件接收到數據時,在應用腳本中及時讀出來數據即可,這樣內核固件的窗口大小就會動態變化;

對于udp來說,雖然udp協議規范應用數據一包的最大長度為65535字節,但是由于udp數據傳輸不可靠,另外收到大數據時,LuatOS內核分配連續的內存空間也存在失敗的概率,雙重失敗概率疊加,會導致udp大數據接收存在失敗的概率增高;

從傳輸可靠性說,整個udp應用數據包含在單個mtu內最佳,最常見的mtu是1500字節,減去網絡層和傳輸層的頭部,剩余1460字節的長度給應用數據,所以所以LuatOS上的udp socket,限制可以接收的一包udp應用數據長度為1460字節;這是一個推薦值,目前實際使用時,可能可以接收到更長的數據,但是為了可靠性,盡量將一包應用數據的長度控制在1460字節;

參數

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 當前狀態;

參數

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)

功能

主動釋放掉 socket對象,此接口和socket.create接口是一對逆操作;

使用socket.release之后,如果要發起重連,需要重新從socket.create開始;

參數

socket_ctrl

wKgZPGl6_JOAWH5fAADwoeK0FnU682.png

返回值

nil

示例

wKgZPGl6_c-AF9syAAErdL8TEWU144.png

六、LuatOS上的libnet擴展庫

剛才我們已經在上一章節學習了socket核心庫中的同步api接口,這些api主要涉及到網卡操作,socket的創建、配置、讀取、銷毀等功能;

在本章節,我們先詳細學習一下libnet擴展庫的api接口;

socket核心庫和libnet擴展庫的主要區別是:

1、socket核心庫提供了完整的api,可以實現socket的完整業務邏輯,但是部分api是異步接口,使用起來復雜;

2、所以我們開發一套libnet擴展庫api接口,將socket核心庫中的異步接口,封裝成同步接口,放到libnet擴展庫中,使用起來會更加方便;

最終,我們推薦使用socket核心庫中的同步api接口+libnet擴展庫中的同步api接口的方式,來開發完整的socket業務邏輯;這兩部分如何組合使用,在本文有一個詳細的socket client應用開發框架來演示;

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

功能

連接對端,阻塞等待連接結果的返回;

只能在sys.taskInitEx創建的task的任務處理函數中使用,因為要阻塞等待并且接收定向消息;

以下三種情況會返回:

1、連接成功;

2、連接失??;

3、連接超時(超時時長受timeout參數控制);

參數

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)

功能

發送數據到對端,阻塞等待發送結果的返回;

只能在sys.taskInitEx創建的task的任務處理函數中使用,因為要阻塞等待并且接收定向消息;

以下三種情況會返回:

1、發送成功;

2、發送失敗;

3、發送超時(超時時長受timeout參數控制);

參數

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連接已經成功后,阻塞等待socket對象上新的網絡事件消息socket.EVENT;

只能在sys.taskInitEx創建的task的任務處理函數中使用,因為要阻塞等待并且接收定向消息;

以下三種情況會退出阻塞等待狀態:

1、socket對象和對端之間的連接出現異常(例如對端主動斷開,網絡環境出現異常等),此時在內核固件中會發送消息socket.EVENT;

2、socket對象接收到對端發送過來的數據,此時在內核固件中會發送消息socket.EVENT;

3、在應用腳本中需要的位置,主動調用sys.sendMsg(task_name, socket.EVENT, 0)發送消息socket.EVENT給task_name對應的task;

參數

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)

功能

主動斷開socket連接;

TCP模式下,先四次揮手斷開連接(超時時長為timeout),再直接強制斷開;

UDP模式下,直接強制斷開;

只能在sys.taskInitEx創建的task的任務處理函數中使用,因為要阻塞等待并且接收定向消息;

參數

task_name

wKgZPGl7A32AdqGsAADcESlaMS0025.png

timeout

wKgZPGl7A56AS2LkAAFB1qNezNw512.png

socket_ctrl

wKgZPGl7A7qAJWb1AADSnwakK_o172.png

返回值

nil

示例

wKgZPGl7A96AZ1DwAAA53SdN-Q0768.png

七、LuatOS上的socke client 應用開發框架

現在,LuatOS socket和libnet的兩個重要的庫文件,基本上講完了,接下來,我們來實際看一個完整的socket client長連接的demo項目代碼,重點分析下如何在項目中使用LuatOS socket核心庫和libnet擴展庫;

7.1 總體設計框圖

demo項目的總體設計框圖如下:

wKgZO2l7BFOASgrAAAIkhJAUUxk405.png

7.2 模擬器上運行這個項目(使用模擬器單網卡演示項目完整的業務邏輯)

首先我們在LuatOS模擬器上運行一下這個demo項目,讓大家對實現的功能有一個直觀的認識

如果要在LuatOS模擬器上運行這個項目,代碼需要做以下幾點修改:

1、netdrv_device.lua中打開pc模擬器的網卡驅動文件require "netdrv_pc",注釋掉其他其他網卡文件;

2、 因為這個demo項目需要用到uart功能,要在pc上模擬uart收發功能,需要在pc上安裝一個虛擬串口工具,生成一組串口,例如串口1和串口2,如果這兩個串口id在你的pc上已經被占用,可以自定義生成任意兩個id的串口就行;


生成的這一對串口可以互相給對方發數據,也能互相接收對方發送過來的數據;

如果生成的是串口1和串口2,這個demo項目中的uart_app.lua中使用的uart1,不用修改uart_app.lua的代碼,此時在pc上使用sscom或者llcom串口工具打開串口2即可,這樣的話,模擬器中的uart1就可以和sscom或者llcom打開的uart2進行收發數據;

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

3、創建一個TCP server、一個UDP server,一個TCP SSL server,根據創建的服務器地址和端口,修改代碼中對應的地址和端口;

軟件環境準備好之后,接下來我們在模擬器上實際運行一下這個項目看看效果;

雙擊 cmd 命令行窗口,然后輸入下面一行命令,運行 luatos 批處理文件,同時輸入要運行的 luatos 項目配置文件

luatos --llt=H:LuatoolsprojectAir8000_socket_client_long_connection.ini

然后按回車鍵,就可以運行 socket_client_long_connection 項目軟件;

7.3 分析項目代碼

這個socket demo中的readme文件,以及代碼中的注釋都比較詳細,接下來我用vscode直接打開這份demo項目代碼,和大家一起分析下項目代碼;

7.4 Air8000開發板上運行演示這個項目(重點演示單網卡和多網卡的使用)

準備硬件環境:

1、Air8000開發板一塊+可上網的sim卡一張+4g天線一根+wifi天線一根+網線一根:

sim卡插入開發板的sim卡槽

天線裝到開發板上

網線一端插入開發板網口,另外一端連接可以上外網的路由器網口或者交換機網口;

2、TYPE-C USB數據線一根 + USB轉串口數據線一根,Air8000開發板和數據線的硬件接線方式為:

Air8000開發板通過TYPE-C USB口供電;(外部供電/USB供電 撥動開關 撥到 USB供電一端)

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

準備軟件環境:

1、手機打開WiFi熱點zhutianhua 123qweasd,修改netdrv_wifi.lua和netdrv_multiple.lua中的WiFi信息;

2、打開TCP/UDP web工具,創建一個TCP server、一個UDP server,一個TCP SSL server,根據創建的服務器地址和端口,修改代碼中對應的地址和端口;

3、netdrv_device.lua分別打開單網卡和多網卡驅動單獨演示;

4、Luatools燒錄內核固件以及修改后的demo腳本;

多網卡演示:

開機后,在Luatools運行日志中搜索 new adapter,如下圖所示,按照紅色文字操作演示

wKgZO2l7Bt-ASwDgAADvtPIyp20075.png

單網卡演示:

直接運行日志即可;

八、如何分析LuatOS socket日志

在socket開發使用過程中,或多或少,我們都會遇到一些問題,遇到問題時,如果我們自己可以根據日志進行初步分析,可能會大大提高解決問題的效率;在本章節我們提供三種日志分析方法;

8.1 三種日志分析方法

8.1.1 Luatools抓取的應用日志分析

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

wKgZPGl7B0WAa-6uAARX1OvCEvs507.png

應用日志分為兩種類型:

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

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

8.1.2 抓取LuatOS模擬器上的網絡交互包進行分析

socket應用完全可以在LuatOS模擬器上運行,所以我們可以使用LuatOS模擬器來運行自己的程序;

在運行過程中使用wireshark抓取網絡交互包,進行詳細分析,例如下圖是在LuatOS模擬器運行過程中,tls+單向認證連接服務器失敗的網絡交互包,從交互包中可以準確的得知,失敗原因是Unknown CA,未識別的CA證書

wKgZPGl7B5KAKJ9eAAak63jhrR8737.png

這種分析方法對于解決socket,http,mqtt,ftp等網絡應用的問題,幫助很大!

8.1.3 Luatools抓取的底層日志網絡交互包分析

這里所說的抓取底層日志網絡交互包分析,和 8.1.2 抓取LuatOS模擬器上的網絡交互包進行分析 相比,一個是在真實的硬件板上(例如Air8000)運行抓日志,一個是在LuatOS模擬器上運行抓網絡交互包;

在真實的硬件板上抓到日志后,然后再使用底層日志分析工具提取出來網絡交互包,然后再使用wireshark對提取出來的網絡交互包進行分析;

和模擬器運行直接抓網絡交互包相比,這種方式有以下幾種明顯的缺點:

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

2、硬件板內存資源有限,抓到的網絡日志會丟包,特別是網絡數據交互頻繁的時候,丟包問題嚴重;

雖然有以上兩項缺點,但是因為是真實的運行環境,對于LuatOS模擬器運行無法分析解決的問題,最終還是要通過這種方式解決;

如果需要用到這種方式來分析解決問題,當前階段,只需要提交Luatools抓到的日志給我們技術人員即可,由技術人員進行分析;

后續我們也會在docs.openluat.com寫一篇文章,單獨講解如何使用這種方法分析問題;大家如果有興趣,可自行查看文檔學習。

所以,在本章節接下來的內容中,我會針對一些常見的問題,分別使用Luatools應用日志分析和LuatOS模擬器上的網絡交互包分析這兩種方法來講述;

8.2 socket創建

8.2.1 創建失敗

Luatools應用日志分析

使用socket.create(adapter_id, task_name)接口創建socket時,常見的錯誤日志,如下圖所示:

wKgZO2l7CDWAPCg2AAA432sqPUY709.png

這種異常日志的意思是:無法為socket對象分配資源;

出現這種異常,通常是因為同時存在的socket數量超過了內核固件限制的最大數量:

Air780系列/Air8000系列的模組,允許同時存在的socket對象數量為64個;

Air6101系列/Air8101系列的模組,允許同時存在的socket對象數量為32個;

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

項目中開發業務代碼時,socket.create和socket.release是一對逆操作,如果不斷的create,但是沒有release,就會出現這種問題,這種錯誤的使用方式比較常見;

例如在一個實際項目中,創建socket,socket連接,socket收發業務邏輯處理,如果業務邏輯處理過程中出現異常,就會斷開socket,然后再銷毀socket;這是一套完整的操作,出現異常后,會從socket創建開始重試;在實際代碼開發過程中,有可能會忘記銷毀socket;這樣的話,每次重試都會創建一個新的socket;隨著重試的次數增多,最終同時存在的socket對象就會超過上限而出現錯誤;例如下圖中,如果漏寫了紅框內的代碼,隨著時間的推移,最終就會出現問題

wKgZPGl7CMmAXfuQAAGPj0AkFNg137.png

項目中正常業務邏輯,同時使用的socket數量超過了限制,這種情況下,只能簡化業務邏輯,減少對socket的使用;不過這種情況幾乎不會出現,因為一個項目的正常業務邏輯,幾乎不會出現同時使用幾十個socket的情況;

LuatOS模擬器上的網絡交互包分析

socket創建失敗,不涉及網絡交互包,所以不適用于此方法進行分析;

8.2 socket連接

8.2.1 dns解析失敗

Luatools應用日志分析

如下圖所示

一共四個DNS服務器,每個服務器嘗試解析3次,最終沒有解析成功,提示:dns_run 649:no ipv6, no ipv4

wKgZPGl7CUOAb0kOAAPfpdyDer0679.png

出現此種錯誤,可以通過以下幾步嘗試分析解決:

1、確認下域名輸入是否正確;

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

LuatOS模擬器上的網絡交互包分析

wKgZPGl7CWmAVEXyAAiGIFMF_js370.png

8.2.2 tcp握手連接失敗

Luatools應用日志分析

當對端ip地址存在,端口不存在時,例如:連接netlab tcp服務器,ip地址為:112.125.89.8,端口42145(不存在)

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

wKgZO2l7CaKAF2Z4AACVWVv_sWI004.png

這里有一個錯誤值:-14,表示:

ERR_RST = -14

  • 含義:連接被重置;
  • 場景:TCP 連接收到對端發送的 RST(重置)報文,導致連接強制關閉;

意味著,tcp連接已經發到了對端ip地址,但是被對端直接給rst了;

還有一種常見的錯誤是對端IP不存在,此時在異常日志中的錯誤值很可能是:-13;

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

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

這里有一個錯誤值:-13,表示:

ERR_ABRT = -13

  • 含義:連接被中止。
  • 場景:TCP 連接被本地或對端異常中止(如收到 RST 包,或本地主動調用tcp_abort)。

具體到本日志,因為對端ip不存在,所以應該是tcp三次握手過程中,超時,內核固件主動斷開了連接;

在LuatOS內核固件中,使用的是LwIP協議棧,此處的錯誤值的完整的取值范圍如下所述(大家在平時開發過程中,如果遇到異常,根據日志中的錯誤值,可以參考這部分說明自行簡單分析下是什么原因):

1、ERR_OK = 0:無錯誤,操作成功;

2、ERR_MEM = -1:內存分配失敗;

3、ERR_BUF = -2:

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

場景:發送數據時緩沖區空間不足(如pbuf大小不夠存放待發送數據),或接收時緩沖區溢出。

4、ERR_TIMEOUT = -3

含義:操作超時。

場景:TCP 連接超時(未收到 SYN-ACK)、ARP 請求超時(未收到目標 MAC 地址應答)、netconn_recv等待數據超時等。

5、ERR_RTE = -4

含義:路由錯誤(無可用路由)。

場景:發送 IP 數據包時,lwip 路由表中找不到目標 IP 地址的有效路由(如未配置默認網關且無直連路由)。

6、ERR_INPROGRESS = -5

含義:操作正在進行中。

場景:非阻塞模式下的操作(如tcp_connect)尚未完成,需等待后續回調通知結果。

7、ERR_VAL = -6

含義:無效值(參數值非法)。

場景:傳入 API 的參數值超出合法范圍(如端口號為 0 或大于 65535,IP 地址格式錯誤等)。

8、ERR_WOULDBLOCK = -7

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

場景:非阻塞模式下調用netconn_recv時暫無數據可接收,或tcp_send時發送窗口未滿導致無法立即發送。

9、ERR_USE = -8

含義:地址已被使用。

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

10、ERR_ALREADY = -9

含義:已在連接中。

場景:對已處于連接過程中的 TCP 控制塊再次調用tcp_connect

11、ERR_ISCONN = -10

含義:連接已建立。

場景:對已連接的 TCP 連接再次調用tcp_connect,或對已連接的netconn執行不需要連接的操作(如bind)。

12、ERR_CONN = -11

含義:未連接狀態。

場景:對未建立連接的netconn調用send,或關閉未連接的連接。

13、ERR_IF = -12

含義:底層網絡接口(netif)錯誤。

場景:網絡接口未初始化、鏈路斷開(如以太網物理層未連接),導致數據包無法發送。

14、ERR_ABRT = -13

含義:連接被中止。

場景:TCP 連接被本地或對端異常中止(如收到 RST 包,或本地主動調用tcp_abort)。

15、ERR_RST = -14

含義:連接被重置。

場景:TCP 連接收到對端發送的 RST(重置)報文,導致連接強制關閉。

16、ERR_CLSD = -15

含義:連接已關閉。

場景:對已正常關閉的連接執行讀寫操作(如tcp_send在連接關閉后調用)。

17、ERR_ARG = -16

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

場景:傳入 API 的參數為NULL(如netconn_new傳入無效的協議類型,tcp_send傳入NULL緩沖區)。

18、ERR_IF_HIGH_WATER = -17

含義:底層網絡接口達到高水位線(緩沖區滿)。

場景:網絡接口發送緩沖區已滿,暫時無法接收新的發送請求(通常用于流量控制)。

19、ERR_IF_SUSPEND = -18

含義:底層網絡接口被掛起。

場景:網絡接口因某種原因(如手動暫停、錯誤恢復中)暫時不可用。

20、ERR_IF_OOS = -19

含義:底層網絡接口處于 “OutOfService”(服務中斷)狀態。

場景:網絡接口硬件故障、驅動錯誤等導致完全無法提供服務。

LuatOS模擬器上的網絡交互包分析

wKgZPGl7CmWAbfT6AArLXYpnXH8311.png

8.2.3 tls握手連接失敗

Luatools應用日志分析

在tls連接+僅支持單向認證的場景中,如果我們在客戶端配置了錯誤的CA證書,本來應該是baidu_parent_ca.crt文件中的內容,現在配置為了錯誤的內容"123",如下圖所示:

wKgZPGl7CruAQKTnAAR399LM8yo762.png

在連接過程中,會有以下異常日志:network_state_shakehand 807:0x2700, 3

wKgZO2l7CtiAPPfhAACqCVohxxM042.png

這里有一個錯誤值:0x2700,MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,表示證書驗證失??;

在LuatOS內核固件中,使用的是MbedTLS開源庫,TLS握手連接過程中,MbedTLS中有以下常見的錯誤值(大家在平時開發過程中,如果遇到異常,根據日志中的錯誤值,可以參考這部分說明自行簡單分析下是什么原因,如果這里沒有覆蓋出現的錯誤值,可以使用AI工具提問,例如錯誤值為0x2700,可以提問:tls握手連接過程中,0x2700表示什么錯誤):

1、基礎加密 / 解密錯誤

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

MBEDTLS_ERR_SSL_BAD_HMAC(0x7082):HMAC 驗證失敗(消息完整性校驗不通過,可能被篡改)。

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

2、協議版本與協商錯誤

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

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

3、密碼套件與算法錯誤

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

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

MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION(0x7008):不支持對方發送的 TLS 擴展(如 ALPN、SNI 擴展不被認可)。

4、證書驗證錯誤

MBEDTLS_ERR_X509_CERT_VERIFY_FAILED(0x2700):證書驗證失?。ㄈ绾灻麩o效、過期、吊銷)。

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

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

MBEDTLS_ERR_SSL_BAD_CERTIFICATE(0x7042):證書格式錯誤或內容無效(如解析失敗、字段不合法)。

5、密鑰交換與認證錯誤

MBEDTLS_ERR_SSL_KEY_EXCHANGE_FAILED(0x7020):密鑰交換過程失敗(如 RSA 密鑰解密失敗、ECDH 密鑰協商錯誤)。

MBEDTLS_ERR_SSL_BAD_CLIENT_KEY_EXCHANGE(0x7022):客戶端密鑰交換消息格式錯誤或內容無效。

MBEDTLS_ERR_SSL_BAD_CERTIFICATE_VERIFY(0x7044):客戶端證書驗證消息(CertificateVerify)無效(如簽名不匹配)。

6、握手流程與消息錯誤

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

MBEDTLS_ERR_SSL_INVALID_HANDSHAKE_MESSAGE(0x7062):握手消息格式無效(如長度錯誤、字段缺失)。

MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE(0x7064):握手失?。ㄍㄓ缅e誤,可能因上述多種原因導致,如服務器拒絕客戶端配置)。

MBEDTLS_ERR_SSL_HANDSHAKE_TIMEOUT(0x7066):握手超時(未在規定時間內收到對方響應)。

7、連接與狀態錯誤

MBEDTLS_ERR_SSL_CONN_EOF(0x70a0):握手過程中連接被關閉(對方發送了關閉通知)。

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

MBEDTLS_ERR_SSL_WANT_READ / MBEDTLS_ERR_SSL_WANT_WRITE(0x70c0 / 0x70c2):非阻塞模式下需要繼續讀寫數據(非錯誤,需重試)。

LuatOS模擬器上的網絡交互包分析

wKgZO2l7CyKAePSMAAag0U7OtqA842.png

8.2 socket收發數據和斷開

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

九、課后作業

實現一個TCP短連接項目(LuatOS模擬器上或者AirXXXX硬件板上開發調試,二選一);

項目需求:

1、啟動一個tcp server;

2、開發LuatOS項目,實現一個tcp client,每隔5分鐘循環執行一次以下業務邏輯:

連接tcp server;如果連接失敗,退出本次循環;如果連接成功,繼續向下執行;

發送任意一包數據到server,如果發送失敗,立即斷開連接,退出本次循環;

server收到數據后,回復任意數據到client;

client等待接收數據,超時時間20秒;

在20秒內,如果收到數據,立即斷開連接,退出本次循環;

20秒超時沒有收到數據,立即斷開連接,退出本次循環;

在以上業務邏輯過程中,如果出現異常,立即斷開連接,退出本次循環;

作業提交內容:

1、2個Lua文件:main.lua,tcp_client_main.lua;

2、1個運行日志文件


今天的內容就分享到這里了~

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Socket
    +關注

    關注

    1

    文章

    214

    瀏覽量

    36908
  • LuatOS
    +關注

    關注

    0

    文章

    156

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    LuatOS平臺下BLE藍牙開發從入門到實踐

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

    LuatOS框架的使用(上)

    在資源受限的物聯網終端設備中,如何實現快速開發與穩定運行是關鍵挑戰。LuatOS框架通過將Lua語言與底層硬件抽象層深度融合,提供了一套簡潔高效的開發范式。本文將圍繞LuatOS框架的
    的頭像 發表于 01-27 19:38 ?156次閱讀
    <b class='flag-5'>LuatOS</b>框架的使用(上)

    掌握LuatOS系統消息:新手也能看懂的列表詳解

    你是否在LuatOS開發中遇到過事件不響應、回調未觸發的問題?這很可能與系統消息列表的配置或使用不當有關。作為LuatOS事件驅動模型的核心組件,消息列表管理著所有異步消息的排隊與分發。本文以新手
    的頭像 發表于 01-13 18:12 ?119次閱讀
    <b class='flag-5'>掌握</b><b class='flag-5'>LuatOS</b>系統消息:新手也能看懂的列表詳解

    嵌入式應掌握的幾種能力

    中,也會選擇使用C++來進行開發。 補充編程語言的知識時,除了掌握語言本身的知識之外。還需要同時學習:編譯、構建、調試等方面的相關知識。這
    發表于 12-08 06:05

    Linux驅動開發的必備知識

    內核基礎知識: 1、熟悉 Linux 內核的架構、模塊系統、進程管理、內存管理等。 了解內核的編譯和加載過程。 2、C編程技能: 精通 C 語言編程,包括指針操作、內存管理、結構體等
    發表于 12-04 07:58

    LuatOS MCU核心庫全接觸:新手操作與功能測試攻略!

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

    新手必備:LuatOS MCU核心庫功能測試與實踐指南

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

    LuatOS AGPS 輔助定位開發實戰教程

    為解決傳統 GPS 定位慢、功耗高的痛點,AGPS 技術通過輔助數據注入提升效率。本教程以 LuatOS 開發環境為基礎,循序漸進地講解 AGPS 輔助定位的開發流程,包括 AGPS 服務器對接
    的頭像 發表于 10-31 17:34 ?1186次閱讀
    <b class='flag-5'>LuatOS</b> AGPS 輔助定位<b class='flag-5'>開發</b>實戰教程

    零基礎也能玩轉TCP/IP?LuatOS上手全攻略

    TCP/IP看似復雜,但借助LuatOS的簡化開發模式,即使沒有網絡編程經驗,也能在短時間內輕松實現通信功能。本指南將帶你一步步用LuatOS快速入門,真正實現“
    的頭像 發表于 10-15 17:28 ?540次閱讀
    零基礎也能玩轉TCP/IP?<b class='flag-5'>LuatOS</b>上手全攻略

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

    想快速上手TCP/IP通信卻不知從何開始?LuatOS開發者提供了簡潔高效的開發路徑。通過本指南的實操步驟,你將發現,實現網絡連接其實比想象中更簡單。 提到網絡應用,就繞不開TCP/IP ——它不
    的頭像 發表于 10-15 17:27 ?664次閱讀
    快速<b class='flag-5'>掌握</b>TCP/IP?<b class='flag-5'>LuatOS</b>新手入門指南

    突破LuatOS開發瓶頸:三個二次開發必備知識揭秘!

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

    LuatOS編程基礎教程:手把手帶你入門物聯網開發

    對于渴望進入物聯網開發領域的初學者來說,LuatOS是一個理想的起點。本教程將通過由淺入深的教學方式,從搭建開發環境、理解核心API到編寫簡單應用,逐步引導你掌握
    的頭像 發表于 06-11 13:03 ?764次閱讀
    <b class='flag-5'>LuatOS</b>編程基礎教程:手把手帶你入門物聯網<b class='flag-5'>開發</b>!

    快速入門——LuatOS:sys庫多任務管理實戰攻略!

    開發者,這里將用最簡明的步驟,助你輕松實現多任務應用開發! sys庫是LuatOS的核心系統調度庫,它基于Lua協程機制實現了實時多任務調度、定時器管理以及消息通信等功能。 在詳細介
    的頭像 發表于 05-29 14:36 ?820次閱讀
    快速入門——<b class='flag-5'>LuatOS</b>:sys庫多任務管理實戰攻略!

    效果器的基礎知識

    電子發燒友網站提供《效果器的基礎知識.doc》資料免費下載
    發表于 03-26 14:30 ?7次下載

    【北京迅為】iTOP-RK3568OpenHarmony系統南向驅動開發GPIO基礎知識

    【北京迅為】iTOP-RK3568OpenHarmony系統南向驅動開發GPIO基礎知識
    的頭像 發表于 03-06 11:23 ?1252次閱讀
    【北京迅為】iTOP-RK3568OpenHarmony系統南向驅動<b class='flag-5'>開發</b>GPIO<b class='flag-5'>基礎知識</b>