基于A(yíng)RM-Linux嵌入式系統的多進(jìn)程并發(fā)服務(wù)器設計
摘要:隨著(zhù)物聯(lián)網(wǎng)、智能電網(wǎng)、智能移動(dòng)設備的發(fā)展,我們將能在任何時(shí)候任何地方獲取我們所需的信息,本文設計一款基于ARM-Linux嵌入式系統的多進(jìn)程并發(fā)服務(wù)器。它擁有傳統服務(wù)器的功能,可遠程訪(fǎng)問(wèn)和操作,同時(shí)又具有體積小、噪聲低、低功耗、低成本的優(yōu)勢,非常適合用于智能樓宇的家用服務(wù)器。
本文引用地址:http://dyxdggzs.com/article/201609/304671.htm目前大家所用的大多是X86服務(wù)器,其功能完善、運行速度快、軟件支持性好等優(yōu)點(diǎn),已被人們普遍認同。但其由于價(jià)格昂貴、功耗高、噪聲大等原因,一般只應用于工廠(chǎng)、企事業(yè)單位,但隨著(zhù)互連網(wǎng)的發(fā)展,我們需要更多的小型服務(wù)器終端,因此,低成本、低功耗的嵌入式服務(wù)器將有極大的應用空間。
面向連接的并發(fā)服務(wù)器是目前Linux網(wǎng)絡(luò )服務(wù)器的主流形式。它采用主、從服務(wù)器的工作方式,能較好地解決了網(wǎng)絡(luò )中客戶(hù)進(jìn)程的并發(fā)請求問(wèn)題。目前在嵌入式領(lǐng)域,基于A(yíng)RM技術(shù)的微處理器應用約占據了32位RISC微處理器80%以上的市場(chǎng)份額,同時(shí),ARM處理器和嵌入式Linux的結合也正變得越來(lái)越緊密,在工業(yè)控制、消費類(lèi)電子產(chǎn)品、通信系統、無(wú)線(xiàn)系統等各類(lèi)產(chǎn)品市場(chǎng)都可以看到ARM與Linux相結合的身影。因此,本文介紹了一種基于ARM-Linux嵌入式系統的多進(jìn)程并發(fā)服務(wù)器設計。
1 并發(fā)服務(wù)器原理及框架
1. 1 基本的C/S服務(wù)模型
相互通信的網(wǎng)絡(luò )程序通??梢苑譃榭蛻?hù)端和服務(wù)器端兩部分。簡(jiǎn)單的C/S服務(wù)模式客戶(hù)端和服務(wù)器采用的是一對一的關(guān)系,而實(shí)際上一個(gè)客戶(hù)同時(shí)可以與多個(gè)服務(wù)器通信,一個(gè)服務(wù)器同時(shí)也能與多個(gè)客戶(hù)通信。
Linux下使用TCP套接字編程可以實(shí)現基于TCP/IP協(xié)議的面向連接的通信,它分為服務(wù)器端和客戶(hù)端兩部分,如圖1所示。

服務(wù)器端與客戶(hù)端連接的步驟如下:
1)使用socket0函數創(chuàng )建套接字;
2)將創(chuàng )那的套接字綁定到指定的地址結構
3)Listen0函數設置套接字為監聽(tīng)模式,使服務(wù)器進(jìn)入被動(dòng)打開(kāi)的狀態(tài)
4)接受客戶(hù)端的連接請求,建立連接
5)終止連接
客戶(hù)端實(shí)現步驟:
1)使用socket0函數創(chuàng )建套接字
2)調用connect0函數建立一個(gè)TCP服務(wù)器的連接
3)發(fā)送數據請求,接收服務(wù)器的數據應答
4)終止連接
這樣就建立了最簡(jiǎn)單的C/S連接模式,而所有基于TCP套接字的網(wǎng)絡(luò )服務(wù)也都是建立在這個(gè)基礎上的。
1.2 多進(jìn)程并發(fā)服務(wù)器模型
前面介紹了簡(jiǎn)單的TCP客戶(hù)端/服務(wù)器概念和連接,其中服務(wù)器每次只能處理一個(gè)客戶(hù)的請求,它的實(shí)現雖然很簡(jiǎn)單但效率卻很低,在實(shí)際應用中,這樣的服務(wù)器是不能滿(mǎn)足實(shí)際需求的。
在實(shí)際應用中為了讓一個(gè)服務(wù)器同時(shí)為多個(gè)客戶(hù)服務(wù),處理多個(gè)客戶(hù)的請求,那么就需要用并發(fā)服務(wù)器。Linux下主要支持的并發(fā)服務(wù)器有進(jìn)程、線(xiàn)程。創(chuàng )建線(xiàn)程要比進(jìn)程快,但一個(gè)進(jìn)程內的所有線(xiàn)程共享相同的內存空間、全局變量等信息,所以當一個(gè)線(xiàn)程崩潰時(shí),它會(huì )影響同一進(jìn)程中的其他線(xiàn)程。
Linux系統中可以同時(shí)存在多個(gè)進(jìn)程,但相對線(xiàn)程來(lái)說(shuō),進(jìn)程是獨立的。它擁有獨立的地址空間、執行堆棧、文件描述符等,在未經(jīng)允許的情況下,一個(gè)進(jìn)程不能訪(fǎng)問(wèn)另一個(gè)進(jìn)程的資源,因此一個(gè)進(jìn)程崩潰不會(huì )造成其他進(jìn)程的崩潰。由于考慮遠程監控系統要求的安全性和穩定性,本系統設計為多進(jìn)程并發(fā)服務(wù)器。圖2為并發(fā)服務(wù)器的基本模型圖。

1.3 多進(jìn)程服務(wù)器原理
在多進(jìn)程并發(fā)服務(wù)器中是通過(guò)調用fork或vfork函數來(lái)創(chuàng )建新進(jìn)程。當父進(jìn)程產(chǎn)生新的子進(jìn)程后,父、子進(jìn)程共享父進(jìn)程在調用fork之前的所有描述符。接下來(lái)父進(jìn)程只負責接收客戶(hù)請求,而子進(jìn)程只負責處理客戶(hù)請求。
圖3說(shuō)明父進(jìn)程調用fork生成子進(jìn)程后,父、子進(jìn)程對客戶(hù)請求和描述符的操作過(guò)程。

1)當服務(wù)器調用accept0函數時(shí),連接請求從客戶(hù)到達服務(wù)器時(shí)雙方狀態(tài)。
2)當客戶(hù)的請求被接受后。接下來(lái)服務(wù)器就會(huì )調用fork函數生成子進(jìn)程。
3)最后父進(jìn)程關(guān)閉已連接描述符,由子進(jìn)程關(guān)閉監聽(tīng)描述符,這樣既可以節省系統資源,又可以防止父、子進(jìn)程同時(shí)對共享描述符進(jìn)程操作。至此子進(jìn)程處理與客戶(hù)的連接,父進(jìn)程可以對監聽(tīng)描述符再次調用accept,繼續處理下一個(gè)客戶(hù)的請求。
2 功能代碼分析
網(wǎng)絡(luò )主程序設計其實(shí)主要也就是父進(jìn)程所執行的程序,程序設計的流程圖如4所示。

linux中的網(wǎng)絡(luò )編程通過(guò)socket接口實(shí)現。socket既是一種特殊的I/O,它也是一種文件描述符。一個(gè)完整的socket包括協(xié)議、本地地址、本地端口、遠程地址、遠程端口;每一個(gè)socket有一個(gè)本地的唯一socket號,由操作系統自動(dòng)分配。以下是建立TCP socket,其中AF_INET為IPv4,SOCK_STREAM為T(mén)CP協(xié)議,如建立失敗則返回-1。
listen_fd=socket(AF_INET,SOCK_STREAM,0)
調用bzero初始化套接字地址結構,并對地址結構中的成員賦值,代碼如下。
bzero(client_addr,sizeof(struct sockaddr_in));
client_addr.sin_family=AF_INET;
client_addr.sin_port=htons(MY_PORT);
client_addr.sin_addr.s_addr=htonl(INADDR_ANY);
為了給調用socket0函數產(chǎn)生的套接字分配一個(gè)本地協(xié)議地址,建立地址與套接字的對應關(guān)系,就要用到綁定函數bind0。通過(guò)綁定后端口號保證了地址信息的唯一性。如失敗返回-1。
評論