單芯片解決方案,開(kāi)啟全新體驗(yàn)——W55MH32 高性能以太網(wǎng)單片機(jī)
W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機(jī),它為用戶帶來(lái)前所未有的集成化體驗(yàn)。這顆芯片將強(qiáng)大的組件集于一身,具體來(lái)說(shuō),一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達(dá)216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲(chǔ)與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨(dú)立的32KB以太網(wǎng)收發(fā)緩存,可供8個(gè)獨(dú)立硬件socket使用。如此配置,真正實(shí)現(xiàn)了All-in-One解決方案,為開(kāi)發(fā)者提供極大便利。
在封裝規(guī)格上,W55MH32提供了兩種選擇:QFN100和QFN68。
W55MH32L采用QFN100封裝版本,尺寸為12x12mm,其資源豐富,專(zhuān)為各種復(fù)雜工控場(chǎng)景設(shè)計(jì)。它擁有66個(gè)GPIO、3個(gè)ADC、12通道DMA、17個(gè)定時(shí)器、2個(gè)I2C、5個(gè)串口、2個(gè)SPI接口(其中1個(gè)帶I2S接口復(fù)用)、1個(gè)CAN、1個(gè)USB2.0以及1個(gè)SDIO接口。如此豐富的外設(shè)資源,能夠輕松應(yīng)對(duì)工業(yè)控制中多樣化的連接需求,無(wú)論是與各類(lèi)傳感器、執(zhí)行器的通信,還是對(duì)復(fù)雜工業(yè)協(xié)議的支持,都能游刃有余,成為復(fù)雜工控領(lǐng)域的理想選擇。同系列還有QFN68封裝的W55MH32Q版本,該版本體積更小,僅為8x8mm,成本低,適合集成度高的網(wǎng)關(guān)模組等場(chǎng)景,軟件使用方法一致。更多信息和資料請(qǐng)進(jìn)入http://www.w5500.com/網(wǎng)站或者私信獲取。
此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應(yīng)用,涵蓋TCP SSL、HTTP SSL以及 MQTT SSL等,為網(wǎng)絡(luò)通信安全再添保障。
為助力開(kāi)發(fā)者快速上手與深入開(kāi)發(fā),基于W55MH32L這顆芯片,WIZnet精心打造了配套開(kāi)發(fā)板。開(kāi)發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實(shí)現(xiàn)調(diào)試、下載以及串口打印日志等功能。開(kāi)發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開(kāi)發(fā)者全面評(píng)估芯片性能。
若您想獲取芯片和開(kāi)發(fā)板的更多詳細(xì)信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價(jià)格等,歡迎訪問(wèn)官方網(wǎng)頁(yè):http://www.w5500.com/,我們期待與您共同探索W55MH32的無(wú)限可能。
第三十章 W55MH32 HTTP_Server&NetBIOS示例
本篇文章我們將詳細(xì)介紹如何在W55MH32芯片上面實(shí)現(xiàn)HTTP_Server與NetBIOS功能,并通過(guò)實(shí)戰(zhàn)例程,為大家講解如何通過(guò)NetBIOS來(lái)訪問(wèn)HTTP服務(wù)器的網(wǎng)頁(yè)內(nèi)容。
該例程用到的其他網(wǎng)絡(luò)協(xié)議,例如DHCP,請(qǐng)參考相關(guān)章節(jié)。有關(guān)W55MH32的初始化過(guò)程,也請(qǐng)參考相關(guān)章節(jié),這里將不再贅述。
1 HTTP_Server&NetBIOS簡(jiǎn)介
通過(guò) NetBIOS實(shí)現(xiàn) HTTP_Server是將傳統(tǒng)的 HTTP服務(wù)與 NetBIOS名稱(chēng)解析功能結(jié)合,允許基于局域網(wǎng)中的 NetBIOS名稱(chēng)進(jìn)行 HTTP請(qǐng)求和響應(yīng)。通常,NetBIOS被用于局域網(wǎng)中的設(shè)備發(fā)現(xiàn)與名稱(chēng)解析,因此,HTTP服務(wù)器可以通過(guò) NetBIOS名稱(chēng)而非 IP地址來(lái)進(jìn)行訪問(wèn),簡(jiǎn)化了網(wǎng)絡(luò)環(huán)境中設(shè)備的配置和通信。
2 HTTP_Server&NetBIOS特點(diǎn)
名稱(chēng)解析:利用 NetBIOS名稱(chēng)解析功能,客戶端可以通過(guò)計(jì)算機(jī)名稱(chēng)而非 IP地址訪問(wèn) HTTP服務(wù)器,簡(jiǎn)化了網(wǎng)絡(luò)配置,尤其適用于沒(méi)有 DNS服務(wù)器的環(huán)境。
局域網(wǎng)優(yōu)化:適合局域網(wǎng)內(nèi)部使用,能在沒(méi)有互聯(lián)網(wǎng)連接的情況下提供 HTTP服務(wù),方便設(shè)備之間的通信和資源共享。
無(wú)需復(fù)雜配置:通過(guò) NetBIOS提供自動(dòng)的設(shè)備發(fā)現(xiàn)和名稱(chēng)解析,減少了對(duì) IP地址配置的依賴(lài),使得設(shè)備間互聯(lián)更加便捷。
兼容性:適用于舊版系統(tǒng)或老舊硬件設(shè)備,尤其是在 Windows系統(tǒng)中,NetBIOS和 HTTP服務(wù)器可以平滑集成。
提高網(wǎng)絡(luò)效率:通過(guò) NetBIOS提供的輕量級(jí)通信機(jī)制,HTTP服務(wù)在局域網(wǎng)環(huán)境中能夠提供快速且穩(wěn)定的數(shù)據(jù)傳輸。
3 HTTP_Server&NetBIOS的基本工作流程
1.初始化:HTTP服務(wù)器啟動(dòng),使用 NetBIOS over TCP/IP(NBT)協(xié)議在局域網(wǎng)內(nèi)廣播自己的名稱(chēng)。
2.名稱(chēng)解析:客戶端通過(guò) NetBIOS名稱(chēng)解析服務(wù)(NBNS)獲取服務(wù)器的 IP地址。
3.客戶端請(qǐng)求:客戶端通過(guò) TCP連接向 HTTP服務(wù)器發(fā)送 HTTP請(qǐng)求。
4.請(qǐng)求處理:服務(wù)器處理請(qǐng)求,生成相應(yīng)的 HTTP響應(yīng)并準(zhǔn)備返回。
5.響應(yīng)返回:服務(wù)器通過(guò) TCP連接將響應(yīng)數(shù)據(jù)(如網(wǎng)頁(yè)或文件)發(fā)送回客戶端。
6.會(huì)話關(guān)閉:請(qǐng)求完成后,服務(wù)器和客戶端關(guān)閉連接或保持連接等待下次請(qǐng)求。
7.結(jié)束與清理:服務(wù)器釋放資源,準(zhǔn)備處理下一個(gè)請(qǐng)求。
HTTP的請(qǐng)求-響應(yīng)模型通常由以下幾個(gè)步驟組成
建立連接:客戶端與服務(wù)器之間基于TCP/IP協(xié)議建立連接。
發(fā)送請(qǐng)求:客戶端向服務(wù)器發(fā)送請(qǐng)求,請(qǐng)求中包含要訪問(wèn)的資源的 URL、請(qǐng)求方法(GET、POST、PUT、DELETE等)、請(qǐng)求頭(例如,Accept、User-Agent)以及可選的請(qǐng)求體(對(duì)于 POST 或 PUT請(qǐng)求)。
處理請(qǐng)求:服務(wù)器接收到請(qǐng)求后,根據(jù)請(qǐng)求中的信息找到相應(yīng)的資源,執(zhí)行對(duì)應(yīng)的處理操作。這可能涉及從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)、生成動(dòng)態(tài)內(nèi)容或者簡(jiǎn)單地返回靜態(tài)文件。
發(fā)送響應(yīng):服務(wù)器將處理后的結(jié)果封裝在響應(yīng)中,并將其發(fā)送回客戶端。響應(yīng)包含狀態(tài)碼(用于指示請(qǐng)求的成功或失敗)、響應(yīng)頭(例如,Content-Type、Content-Length)以及可選的響應(yīng)體(例如,HTML頁(yè)面、圖像數(shù)據(jù))。
關(guān)閉連接:在完成請(qǐng)求-響應(yīng)周期后,客戶端和服務(wù)器之間的連接將被關(guān)閉,除非使用了持久連接(如 HTTP/1.1中的 keep-alive)。
4 HTTP請(qǐng)求方法
在HTTP協(xié)議中,GET和POST是兩種常用的請(qǐng)求方法,用于客戶端向服務(wù)器發(fā)送數(shù)據(jù)和獲取資源。
GET方法
GET方法通常用于從服務(wù)器獲取資源。它有以下特點(diǎn):
參數(shù)傳遞:請(qǐng)求參數(shù)通過(guò)URL中的查詢(xún)字符串傳遞,形如?key1=value1&key2=value2。
數(shù)據(jù)大小限制:由于參數(shù)附加在URL后,長(zhǎng)度可能受URL長(zhǎng)度限制(取決于瀏覽器和服務(wù)器設(shè)置)。
安全性:數(shù)據(jù)在URL中明文顯示,不適合傳遞敏感信息。
請(qǐng)求格式:
GET HTTP/
Request-URI:表示目標(biāo)資源的路徑,可能包含參數(shù)。
Version:HTTP協(xié)議版本。
Headers:包含元信息,例如客戶端的屬性、支持的格式等。
Blank Line:空行。
POST方法
POST方法通常用于向服務(wù)器提交數(shù)據(jù)。它有以下特點(diǎn):
參數(shù)傳遞:數(shù)據(jù)放在請(qǐng)求體中,而不是URL中。
數(shù)據(jù)大小限制:POST請(qǐng)求的體積沒(méi)有明顯限制,可以傳遞大量數(shù)據(jù)。
安全性:數(shù)據(jù)在請(qǐng)求體中傳輸,相對(duì)來(lái)說(shuō)更安全。
請(qǐng)求格式:
POST HTTP/
字段解釋?zhuān)?/p>
Request-URI:目標(biāo)資源的路徑,通常是API的端點(diǎn)。
Headers:元信息,例如內(nèi)容類(lèi)型和長(zhǎng)度。
Blank Line:空行,區(qū)分頭和主體。
Body:數(shù)據(jù)的主體,包含客戶端發(fā)送到服務(wù)器的長(zhǎng)度。
5 HTTP協(xié)議響應(yīng)內(nèi)容
HTTP協(xié)議響應(yīng)內(nèi)容包含狀態(tài)行、響應(yīng)頭以及響應(yīng)體三個(gè)部分。
狀態(tài)行
HTTP狀態(tài)行包含HTTP協(xié)議版本、狀態(tài)碼以及狀態(tài)描述。
狀態(tài)碼由三個(gè)十進(jìn)制數(shù)字組成,第一個(gè)十進(jìn)制數(shù)字定義了狀態(tài)碼的類(lèi)型。
狀態(tài)碼分為五類(lèi):
1xx(信息性狀態(tài)碼):表示接收的請(qǐng)求正在處理。
2xx(成功狀態(tài)碼):表示請(qǐng)求正常處理完畢。
3xx(重定向狀態(tài)碼):需要后續(xù)操作才能完成這一請(qǐng)求。
4xx(客戶端錯(cuò)誤狀態(tài)碼):表示請(qǐng)求包含語(yǔ)法錯(cuò)誤或無(wú)法完成。
5xx(服務(wù)器錯(cuò)誤狀態(tài)碼):服務(wù)器在處理請(qǐng)求的過(guò)程中發(fā)生了錯(cuò)誤。
示例:
HTTP/1.1200 OK
響應(yīng)頭
響應(yīng)頭則會(huì)包含內(nèi)容類(lèi)型、長(zhǎng)度、編碼等信息。
常見(jiàn)的響應(yīng)頭字段有:
Content-Type:響應(yīng)內(nèi)容的MIME類(lèi)型,例如 text/html、application/json。
Content-Length:響應(yīng)內(nèi)容的字節(jié)長(zhǎng)度。
Server:服務(wù)器信息。
Set-Cookie:設(shè)置客戶端的Cookie。
示例:
Content-Type: text/html; charset=UTF-8 Content-Length:3495 Server:Apache/2.4.41(Ubuntu)
響應(yīng)體
響應(yīng)體包含實(shí)際的數(shù)據(jù)內(nèi)容,具體形式取決于響應(yīng)的類(lèi)型和請(qǐng)求內(nèi)容。例如:HTML頁(yè)面內(nèi)容,JSON數(shù)據(jù),文件的二進(jìn)制數(shù)據(jù)等。
如果是狀態(tài)碼為204 No Content或 304 Not Modified的響應(yīng),則通常沒(méi)有正文。
注意:響應(yīng)體和響應(yīng)頭之間會(huì)添加一個(gè)空行來(lái)分隔內(nèi)容。
6 Web頁(yè)面的基本構(gòu)成
HTML(超文本標(biāo)記語(yǔ)言)
、、。
作用:定義網(wǎng)頁(yè)的結(jié)構(gòu)和內(nèi)容。
內(nèi)容:
結(jié)構(gòu)標(biāo)簽:如
內(nèi)容標(biāo)簽:如
、
、、。
表單標(biāo)簽:如 、、。
CSS(層疊樣式表)
作用:控制網(wǎng)頁(yè)的樣式和布局。
內(nèi)容:
字體設(shè)置:如 font-family、font-size。
顏色設(shè)置:如 color、background-color。
布局設(shè)計(jì):如 margin、padding、display、flex。
響應(yīng)式設(shè)計(jì):如媒體查詢(xún)(@media)。
JavaScript(腳本語(yǔ)言)
作用:增加網(wǎng)頁(yè)的交互性和動(dòng)態(tài)功能。
應(yīng)用:
表單驗(yàn)證。
動(dòng)畫(huà)效果。
與服務(wù)器交互(如通過(guò) AJAX請(qǐng)求)。
處理用戶事件(如點(diǎn)擊、懸停)。
Meta信息
中。
作用:提供頁(yè)面的元數(shù)據(jù),通常包含在
內(nèi)容:
網(wǎng)頁(yè)標(biāo)題:
字符集:。
SEO信息:如 。
設(shè)備適配:如 。
示例:
!DOCTYPE html?> Simple Page/title?> body{ font-family:Arial, sans-serif; text-align: center; padding:20px;} button{ padding:10px20px; cursor: pointer;} /style?> /head?>Hello, Web!/h1?> Click the button for a surprise./p?>
7 Web頁(yè)面交互
Web頁(yè)面實(shí)現(xiàn)HTTP請(qǐng)求的方式:
HTTP請(qǐng)求頁(yè)面
描述:客戶端通過(guò) HTTP協(xié)議向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器處理后返回響應(yīng)。
特點(diǎn):
最基礎(chǔ)的交互方式。
包括常見(jiàn)的 HTTP方法:GET、POST、PUT、DELETE等。
示例:
GET請(qǐng)求:瀏覽器訪問(wèn)網(wǎng)頁(yè),獲取靜態(tài)資源(HTML、CSS、JavaScript等)。
POST請(qǐng)求:提交表單數(shù)據(jù)。
表單提交
描述:通過(guò) HTML表單向服務(wù)器提交數(shù)據(jù)。
特點(diǎn):
表單數(shù)據(jù)會(huì)被編碼后隨請(qǐng)求發(fā)送。
可使用 GET或 POST方法。
示例:
Submit/button?> /form?>
AJAX(Asynchronous JavaScript and XML)
描述:使用 JavaScript在后臺(tái)與服務(wù)器通信,更新部分頁(yè)面內(nèi)容而無(wú)需刷新整個(gè)頁(yè)面。
特點(diǎn):
提高用戶體驗(yàn),減少頁(yè)面加載時(shí)間。
現(xiàn)代開(kāi)發(fā)中多用 JSON代替 XML。
示例:
fetch('/api/data',{ method:'GET' }) .then(response=> response.json()) .then(data=> console.log(data));
Web服務(wù)器響應(yīng)處理
直接響應(yīng)
定義:服務(wù)器直接處理請(qǐng)求,返回靜態(tài)資源或簡(jiǎn)單的動(dòng)態(tài)內(nèi)容,而不調(diào)用外部腳本或程序。
特點(diǎn)
高效:直接處理請(qǐng)求,無(wú)需額外調(diào)用外部程序,適合靜態(tài)內(nèi)容。
適用場(chǎng)景:
靜態(tài)資源(HTML、CSS、JavaScript、圖像等)的分發(fā)。
輕量級(jí)動(dòng)態(tài)內(nèi)容生成。
工作流程
客戶端發(fā)送 HTTP請(qǐng)求。
服務(wù)器解析請(qǐng)求 URL,查找相應(yīng)的資源(如文件路徑)。
直接讀取資源內(nèi)容并返回給客戶端,附加適當(dāng)?shù)?HTTP響應(yīng)頭。
CGI響應(yīng)
定義:服務(wù)器通過(guò) CGI(Common Gateway Interface)調(diào)用外部程序或腳本,處理客戶端請(qǐng)求并生成動(dòng)態(tài)響應(yīng)內(nèi)容。
特點(diǎn)
靈活性:可以動(dòng)態(tài)生成內(nèi)容,支持復(fù)雜邏輯。
適用場(chǎng)景:
動(dòng)態(tài)內(nèi)容生成(如用戶登錄、數(shù)據(jù)查詢(xún))。
與數(shù)據(jù)庫(kù)交互或其他后臺(tái)服務(wù)的復(fù)雜邏輯處理。
工作流程
客戶端發(fā)送 HTTP請(qǐng)求。
服務(wù)器解析請(qǐng)求并將請(qǐng)求數(shù)據(jù)(如 URL參數(shù)或表單數(shù)據(jù))傳遞給 CGI程序。
CGI程序處理請(qǐng)求,生成響應(yīng)內(nèi)容并返回給服務(wù)器。
服務(wù)器將 CGI程序生成的內(nèi)容包裝為 HTTP響應(yīng)發(fā)送給客戶端。
8 HTTP_Server&NetBIOS應(yīng)用場(chǎng)景
接下來(lái),我們了解下在W55MH32上,可以使用HTTP_Server&NetBIOS完成哪些操作及應(yīng)用呢?
1.簡(jiǎn)化設(shè)備互聯(lián):通過(guò) NetBIOS名稱(chēng)解析,嵌入式設(shè)備無(wú)需依賴(lài) DNS即可在局域網(wǎng)內(nèi)互相發(fā)現(xiàn)和訪問(wèn) HTTP服務(wù),簡(jiǎn)化網(wǎng)絡(luò)配置。
2.自動(dòng)化配置與管理:NetBIOS使得設(shè)備可以通過(guò)名稱(chēng)自動(dòng)發(fā)現(xiàn)并配置,提高設(shè)備部署和維護(hù)效率,尤其適用于大規(guī)模嵌入式設(shè)備部署。
3.無(wú)需 DNS的網(wǎng)絡(luò)環(huán)境:適用于沒(méi)有 DNS的小型局域網(wǎng)或開(kāi)發(fā)環(huán)境,減少了 IP地址管理的復(fù)雜性,提供便捷的設(shè)備通信方式。
4.調(diào)試與維護(hù)工具:NetBIOS和 HTTP Server的結(jié)合使得開(kāi)發(fā)人員能夠快速調(diào)試嵌入式設(shè)備,監(jiān)控系統(tǒng)性能并進(jìn)行故障排查。
5.嵌入式Web服務(wù):提供基于HTTP的控制接口或狀態(tài)監(jiān)控,方便遠(yuǎn)程管理和調(diào)試,適合嵌入式設(shè)備的配置和管理。
9實(shí)現(xiàn)過(guò)程
接下來(lái),我們?cè)赪55MH32上實(shí)現(xiàn)HTTP_Server&NetBIOS功能。
注意:測(cè)試實(shí)例需要PC端和W55MH32處于同一網(wǎng)段。
在主循環(huán)中,程序并行處理 HTTP與 NetBIOS相關(guān)事務(wù)。有以下步驟:
1. while(1) 2. { 3. httpServer_run(SOCKET_ID); 4. do_netbios(SOCKET_ID); 5. } 6.
步驟一:HTTP服務(wù)器處理
httpServer_run()函數(shù)負(fù)責(zé) HTTP服務(wù)器功能,根據(jù)socket狀態(tài)進(jìn)行監(jiān)聽(tīng)、接收請(qǐng)求、處理并響應(yīng),如針對(duì)不同的 GET請(qǐng)求返回對(duì)應(yīng)網(wǎng)頁(yè)內(nèi)容,處理 POST請(qǐng)求時(shí)更新配置并設(shè)置重啟標(biāo)志。
httpServer_run()函數(shù)如下:
1. void httpServer_run(uint8_t seqnum) 2. { 3. uint8_t s;// socket number 4. uint16_t len; 5. uint32_t gettime=0; 6. 7. #ifdef _HTTPSERVER_DEBUG_ 8. uint8_t destip[4]={ 9. 0, 10. }; 11. uint16_t destport=0; 12. #endif 13. 14. http_request =(st_http_request*)pHTTP_RX;// Structure of HTTP Request 15. parsed_http_request=(st_http_request*)pHTTP_TX; 16. 17. // Get the H/W socket number 18. s= getHTTPSocketNum(seqnum); 19. 20. /* HTTP Service Start */ 21. switch(getSn_SR(s)) 22. { 23. case SOCK_ESTABLISHED: 24. // Interrupt clear 25. if(getSn_IR(s)&Sn_IR_CON) 26. { 27. setSn_IR(s,Sn_IR_CON); 28. } 29. 30. // HTTP Process states 31. switch(HTTPSock_Status[seqnum].sock_status) 32. { 33. case STATE_HTTP_IDLE: 34. if((len= getSn_RX_RSR(s))>0) 35. { 36. if(len> DATA_BUF_SIZE) len= DATA_BUF_SIZE; 37. len = recv(s,(uint8_t*)http_request, len); 38. *(((uint8_t*)http_request)+ len)=''; 39. 40. parse_http_request(parsed_http_request,(uint8_t*)http_request); 41. #ifdef _HTTPSERVER_DEBUG_ 42. getSn_DIPR(s, destip); 43. destport= getSn_DPORT(s); 44. printf("rn"); 45. printf("> HTTPSocket[%d] : HTTP Request received ", s); 46. printf("from %d.%d.%d.%d : %drn", destip[0], destip[1], destip[2], destip[3], destport); 47. #endif 48. #ifdef _HTTPSERVER_DEBUG_ 49. printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONErn", s); 50. #endif 51. // HTTP 'response' handler; includes send_http_response_header / body function 52. http_process_handler(s, parsed_http_request); 53. 54. gettime= get_httpServer_timecount(); 55. // Check the TX socket buffer for End of HTTP response sends 56. while(getSn_TX_FSR(s)!=(getSn_TxMAX(s))) 57. { 58. if((get_httpServer_timecount()- gettime)>3) 59. { 60. #ifdef _HTTPSERVER_DEBUG_ 61. printf("> HTTPSocket[%d] : [State] STATE_HTTP_REQ_DONE: TX Buffer clear timeoutrn", s); 62. #endif 63. break; 64. } 65. } 66. 67. if(HTTPSock_Status[seqnum].file_len>0) 68. HTTPSock_Status[seqnum].sock_status= STATE_HTTP_RES_INPROC; 69. else 70. HTTPSock_Status[seqnum].sock_status= STATE_HTTP_RES_DONE;// Send the 'HTTP response' end 71. } 72. break; 73. 74. case STATE_HTTP_RES_INPROC: 75. /* Repeat: Send the remain parts of HTTP responses */ 76. #ifdef _HTTPSERVER_DEBUG_ 77. printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_INPROCrn", s); 78. #endif 79. // Repeatedly send remaining data to client 80. send_http_response_body(s,0, http_response,0,0); 81. 82. if(HTTPSock_Status[seqnum].file_len==0)HTTPSock_Status[seqnum].sock_status= STATE_HTTP_RES_DONE; 83. break; 84. 85. case STATE_HTTP_RES_DONE: 86. #ifdef _HTTPSERVER_DEBUG_ 87. printf("> HTTPSocket[%d] : [State] STATE_HTTP_RES_DONErn", s); 88. #endif 89. // Socket file info structure re-initialize 90. HTTPSock_Status[seqnum].file_len =0; 91. HTTPSock_Status[seqnum].file_offset=0; 92. HTTPSock_Status[seqnum].file_start =0; 93. HTTPSock_Status[seqnum].sock_status= STATE_HTTP_IDLE; 94. 95. //#ifdef _USE_SDCARD_ 96. // f_close(&fs); 97. //#endif 98. #ifdef _USE_WATCHDOG_ 99. HTTPServer_WDT_Reset(); 100. #endif 101. http_disconnect(s); 102. break; 103. 104. default: 105. break; 106. } 107. break; 108. 109. case SOCK_CLOSE_WAIT: 110. #ifdef _HTTPSERVER_DEBUG_ 111. printf("> HTTPSocket[%d] : ClOSE_WAITrn", s);// if a peer requests to close the current connection 112. #endif 113. disconnect(s); 114. break; 115. 116. case SOCK_CLOSED: 117. #ifdef _HTTPSERVER_DEBUG_ 118. printf("> HTTPSocket[%d] : CLOSEDrn", s); 119. #endif 120. if(socket(s,Sn_MR_TCP, HTTP_SERVER_PORT,0x00)== s)/* Reinitialize the socket */ 121. { 122. #ifdef _HTTPSERVER_DEBUG_ 123. printf("> HTTPSocket[%d] : OPENrn", s); 124. #endif 125. } 126. break; 127. 128. case SOCK_INIT: 129. listen(s); 130. break; 131. 132. case SOCK_LISTEN: 133. break; 134. 135. default: 136. break; 137. 138. }// end of switch 139. 140. #ifdef _USE_WATCHDOG_ 141. HTTPServer_WDT_Reset(); 142. #endif 143. } 144.
該函數(shù)用于處理 HTTP服務(wù)器的運(yùn)行邏輯。函數(shù)接受一個(gè)參數(shù) seqnum,表示當(dāng)前處理的套接字的序列號(hào)。進(jìn)入該函數(shù)后,程序會(huì)執(zhí)行一個(gè)狀態(tài)機(jī),根據(jù)Socket的狀態(tài)來(lái)執(zhí)行不同的操作。
當(dāng)Socket處于SOCK_CLOSED時(shí)為關(guān)閉狀態(tài),程序會(huì)打開(kāi)并重新初始化套接字;
為SOCK_ESTABLISHED時(shí)表示已建立連接,首先會(huì)清除中斷標(biāo)志,然后根據(jù)套接字的狀態(tài)進(jìn)行不同的處理,在空閑狀態(tài)時(shí),接收并解析數(shù)據(jù),處理 HTTP請(qǐng)求后發(fā)送響應(yīng),并根據(jù)文件長(zhǎng)度更新?tīng)顟B(tài);在響應(yīng)處理中狀態(tài)時(shí),發(fā)送剩余的響應(yīng)數(shù)據(jù),文件傳輸完成時(shí)切換到響應(yīng)完成狀態(tài);響應(yīng)完成后重置文件信息并關(guān)閉套接字,返回空閑狀態(tài);
SOCK_CLOSE_WAIT則為關(guān)閉等待狀態(tài),此時(shí)調(diào)用 disconnect()函數(shù)關(guān)閉套接字;
SOCK_INIT表示處于初始化狀態(tài),調(diào)用 listen()函數(shù)監(jiān)聽(tīng)連接;
SOCK_LISTEN為處于監(jiān)聽(tīng)狀態(tài),不進(jìn)行任何操作。
步驟二:NetBIOS服務(wù)處理
do_netbios()函數(shù)實(shí)現(xiàn) NetBIOS名稱(chēng)解析,當(dāng)處于 SOCK_UDP 狀態(tài)且接收到數(shù)據(jù)包,若為對(duì)本機(jī) NetBIOS名稱(chēng)的查詢(xún),便構(gòu)造并發(fā)送響應(yīng)包,在 SOCK_CLOSED狀態(tài)時(shí)則重新打開(kāi)socket。通過(guò)這樣的循環(huán)機(jī)制,程序持續(xù)提供 HTTP服務(wù)與 NetBIOS名稱(chēng)解析服務(wù)。
do_netbios()函數(shù)如下:
1. void do_netbios(uint8_t sn) 2. { 3. unsignedchar state; 4. unsignedint len; 5. state= getSn_SR(sn); 6. switch(state) 7. { 8. case SOCK_UDP: 9. if((len= getSn_RX_RSR(sn))>0) 10. { 11. unsignedchar rem_ip_addr[4]; 12. uint16_t rem_udp_port; 13. char netbios_name[NETBIOS_NAME_LEN+1]; 14. NETBIOS_HDR *netbios_hdr; 15. NETBIOS_NAME_HDR*netbios_name_hdr; 16. len= recvfrom(sn,(unsignedchar*)&netbios_rx_buf, len, rem_ip_addr,&rem_udp_port); 17. printf("rem_ip_addr=%d.%d.%d.%d:%drn", rem_ip_addr[0], rem_ip_addr[1], rem_ip_addr[2], rem_ip_addr[3], rem_udp_port); 18. netbios_hdr =(NETBIOS_HDR*)netbios_rx_buf; 19. netbios_name_hdr=(NETBIOS_NAME_HDR*)(netbios_hdr+1); 20. // If the packet is a NetBIOS query packet 21. if(((netbios_hdr->flags& ntohs(NETB_HFLAG_OPCODE))== ntohs(NETB_HFLAG_OPCODE_NAME_QUERY))&&((netbios_hdr->flags& ntohs(NETB_HFLAG_RESPONSE))==0)&&(netbios_hdr->questions== ntohs(1))) 22. { 23. printf("netbios name query questionrn"); 24. // Decode the NetBIOS package 25. netbios_name_decoding((char*)(netbios_name_hdr->encname), netbios_name,sizeof(netbios_name)); 26. printf("name is %srn", netbios_name); 27. // If the query is made against the native Netbios 28. if(strcmp(netbios_name, NETBIOS_W55MH32_NAME)==0) 29. { 30. uint8_t ip_addr[4]; 31. NETBIOS_RESP*resp=(NETBIOS_RESP*)netbios_tx_buf; 32. // Handle the header of the NetBIOS response packet 33. resp->resp_hdr.trans_id = netbios_hdr->trans_id; 34. resp->resp_hdr.flags = htons(NETB_HFLAG_RESPONSE| NETB_HFLAG_OPCODE_NAME_QUERY| NETB_HFLAG_AUTHORATIVE | NETB_HFLAG_RECURS_DESIRED); 35. resp->resp_hdr.questions =0; 36. resp->resp_hdr.answerRRs = htons(1); 37. resp->resp_hdr.authorityRRs =0; 38. resp->resp_hdr.additionalRRs=0; 39. // Process the header data of the NetBIOS response packet 40. memcpy(resp->resp_name.encname, netbios_name_hdr->encname,sizeof(netbios_name_hdr->encname)); 41. resp->resp_name.nametype= netbios_name_hdr->nametype; 42. resp->resp_name.type = netbios_name_hdr->type; 43. resp->resp_name.cls = netbios_name_hdr->cls; 44. resp->resp_name.ttl = htonl(NETBIOS_NAME_TTL); 45. resp->resp_name.datalen = htons(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr)); 46. resp->resp_name.flags = htons(NETB_NFLAG_NODETYPE_BNODE); 47. getSIPR(ip_addr); 48. memcpy(resp->resp_name.addr, ip_addr,4); 49. // Send a response packet 50. sendto(sn,(unsignedchar*)resp,sizeof(NETBIOS_RESP), rem_ip_addr, rem_udp_port); 51. printf("send responsern"); 52. } 53. } 54. } 55. break; 56. 57. case SOCK_CLOSED: 58. close(sn); 59. socket(sn,Sn_MR_UDP, NETBIOS_PORT,0); 60. break; 61. 62. default: 63. break; 64. } 65. } 66.
do_netbios()函數(shù)主要執(zhí)行 NetBIOS相關(guān)操作。程序首先會(huì)執(zhí)行一個(gè)狀態(tài)機(jī),根據(jù)套接字狀態(tài)執(zhí)行不同操作:在關(guān)閉狀態(tài)(SOCK_CLOSED)時(shí),關(guān)閉并重新創(chuàng)建套接字監(jiān)聽(tīng)NetBIOS端口;在UDP狀態(tài)時(shí)(SOCK_UDP),接收數(shù)據(jù)并解析 NetBIOS查詢(xún)包,匹配本地名稱(chēng)時(shí)發(fā)送響應(yīng)包;其他狀態(tài)下不操作。
10運(yùn)行結(jié)果
燒錄例程運(yùn)行后,首先進(jìn)行了PHY鏈路檢測(cè),然后是通過(guò)DHCP獲取網(wǎng)絡(luò)地址并打印網(wǎng)絡(luò)地址信息,通過(guò)NetBIOS名稱(chēng)解析打印提示解析名稱(chēng),接著我們打開(kāi)瀏覽器,輸入W55MH32/進(jìn)行即可訪問(wèn)網(wǎng)頁(yè)信息:
11總結(jié)
本文講解了如何在 W55MH32芯片上實(shí)現(xiàn) HTTP_Server與 NetBIOS功能,并通過(guò) NetBIOS訪問(wèn) HTTP服務(wù)器網(wǎng)頁(yè)內(nèi)容,通過(guò)實(shí)戰(zhàn)例程展示了在主循環(huán)中并行處理 HTTP與 NetBIOS相關(guān)事務(wù)的過(guò)程。感謝觀看!
WIZnet是一家無(wú)晶圓廠半導(dǎo)體公司,成立于 1998年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術(shù),基于獨(dú)特的專(zhuān)利全硬連線 TCP/IP。iMCU? 面向各種應(yīng)用中的嵌入式互聯(lián)網(wǎng)設(shè)備。
WIZnet在全球擁有 70多家分銷(xiāo)商,在香港、韓國(guó)、美國(guó)設(shè)有辦事處,提供技術(shù)支持和產(chǎn)品營(yíng)銷(xiāo)。
香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國(guó)和日本除外)。
審核編輯 黃宇
-
芯片
+關(guān)注
關(guān)注
462文章
53166瀏覽量
453452 -
NETBIOS
+關(guān)注
關(guān)注
0文章
8瀏覽量
9551
發(fā)布評(píng)論請(qǐng)先 登錄
第十章 W55MH32中斷應(yīng)用概覽

第二章 W55MH32 DHCP示例

第三章 W55MH32 TCP Client示例

第五章 W55MH32 UDP示例

第六章 W55MH32 UDP?Multicast示例

第九章 W55MH32 HTTP Server示例

第十章 W55MH32 SNTP示例

第十二章 W55MH32 NetBIOS示例

第十四章 W55MH32 TFTP示例

第十五章 W55MH32 SNMP示例

第十六章 W55MH32 PING示例

第十八章 W55MH32 FTP_Server示例

第二十二章 W55MH32 MQTT&amp;Aliyun示例

第二十六章 W55MH32?上位機(jī)搜索和配置示例

第二十九章 W55MH32 Modbus_TCP_Server示例

評(píng)論