九九热最新网址,777奇米四色米奇影院在线播放,国产精品18久久久久久久久久,中文有码视频,亚洲一区在线免费观看,国产91精品在线,婷婷丁香六月天

歡迎來到裝配圖網(wǎng)! | 幫助中心 裝配圖網(wǎng)zhuangpeitu.com!
裝配圖網(wǎng)
ImageVerifierCode 換一換
首頁 裝配圖網(wǎng) > 資源分類 > DOCX文檔下載  

Linux環(huán)境下高并發(fā)web服務(wù)器 的設(shè)計與實現(xiàn).docx

  • 資源ID:81621547       資源大?。?span id="24d9guoke414" class="font-tahoma">1.43MB        全文頁數(shù):31頁
  • 資源格式: DOCX        下載積分:28積分
快捷下載 游客一鍵下載
會員登錄下載
微信登錄下載
三方登錄下載: 微信開放平臺登錄 支付寶登錄   QQ登錄   微博登錄  
二維碼
微信掃一掃登錄
下載資源需要28積分
郵箱/手機:
溫馨提示:
用戶名和密碼都是您填寫的郵箱或者手機號,方便查詢和重復(fù)下載(系統(tǒng)自動生成)
支付方式: 支付寶    微信支付   
驗證碼:   換一換

 
賬號:
密碼:
驗證碼:   換一換
  忘記密碼?
    
友情提示
2、PDF文件下載后,可能會被瀏覽器默認(rèn)打開,此種情況可以點擊瀏覽器菜單,保存網(wǎng)頁到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站資源下載后的文檔和圖紙-無水印,預(yù)覽文檔經(jīng)過壓縮,下載后原文更清晰。
5、試題試卷類文檔,如果標(biāo)題沒有明確說明有答案則都視為沒有答案,請知曉。

Linux環(huán)境下高并發(fā)web服務(wù)器 的設(shè)計與實現(xiàn).docx

Linux環(huán)境下高并發(fā)web服務(wù)器的設(shè)計與實現(xiàn)摘要隨著信息技術(shù)的飛速開展,互聯(lián)網(wǎng)已經(jīng)成為社會生產(chǎn)生活中不可缺少的一局部。特別是近十年來,由于移動技 術(shù)的進步和智能移動設(shè)備的普及,互聯(lián)網(wǎng)用戶數(shù)量呈爆發(fā)式增長,越來越多的行業(yè)正在通過互聯(lián)網(wǎng)進行變革。用戶 群體的開展改變了互聯(lián)網(wǎng)服務(wù)的形式,越來越多的服務(wù)器需要同時為大量客戶提供服務(wù)。因此,如何設(shè)計服務(wù)器的 通信框架,如何有效利用服務(wù)器的系統(tǒng)資源,成為服務(wù)器開發(fā)人員關(guān)注的焦點。Web應(yīng)用具有連接間隔短、突發(fā)性強、響應(yīng)時間短等特點,它是一種對并發(fā)性要求很高的服務(wù)。本文在服務(wù)器系 統(tǒng)中選擇主流的Linux操作系統(tǒng),采用C+,結(jié)合Socket、I/O多路復(fù)用技術(shù)epoll、無阻塞I/O、線程池、定時器和 Reactor事件處理模式,設(shè)計并實現(xiàn)了一個穩(wěn)定支持高并發(fā)的Web服務(wù)器。本文首先介紹和分析了Wob服務(wù)器的相關(guān)技術(shù),包括Socket、epolK Reactor事件處理模式、線程池和數(shù)據(jù)庫連 接池;重點討論了epoll與其他I/O模型的區(qū)別,以及epoll模型的特點。其次,根據(jù)Reactor模式分析了服務(wù)器的整圖3. 4事件處理器與存儲隊列存儲單元從阻塞隊列獲取獲取數(shù) 據(jù)進行存儲。如圖3. 5所示。圖3. 5存儲隊列與存儲單元3. 2事件別離器流程事件別離器主要負(fù)責(zé)接收新連接、偵聽到達事件。HTTP長連接可以減少TCP連接的創(chuàng)立次數(shù),使客戶端和服務(wù)器能 夠有效復(fù)用TCP連接。但是,“在長連接應(yīng)用中,服務(wù)器與客戶端實例都保持一個持久的連接,這將大量消耗服務(wù)器資源,特別是在一些大型應(yīng)用系統(tǒng)中更是如 此,大量并發(fā)的長連接有可能導(dǎo)致新的請求被阻塞甚至系統(tǒng)崩潰18?!睘榱藢﹂L連接進行管控,服務(wù)器可以通過實現(xiàn)定時器,對每個連接記錄超時時間點來解決這個問題。每當(dāng)某個 連接有新請求到達時重置該連接的定時器,如果連接超時那么服務(wù)器主動釋放連接。判斷超時和重置定時器的工作均 由事件別離器完成,事件別離器工作流程如圖3. 6所示。設(shè)置新連接的定時 器,把新邇接加入設(shè)置新連接的定時 器,把新邇接加入重置龍援的定時器,把 事件和處理方法加入到I 到檢測集合中 II 事件阻塞隊列中 I圖3.6事件別離器流程3. 3事件處理器流程事件處理器是服務(wù)器的核心模塊,主要負(fù)責(zé)的工作是:服務(wù)器的I/O操作、業(yè)務(wù)處理,因此對服務(wù)器的業(yè)務(wù)拓展 工作主要是對事件處理器的功能進行拓展。在本工程實現(xiàn)的Web服務(wù)器中,I/O操作主要是指對Socket進行讀寫操 作 ,業(yè)務(wù)處理主要是指對接收到的HTTP請求報文進行解析,并生成相應(yīng)的HTTP響應(yīng)報文。同時為了能夠支持用戶登錄 功能和用戶注冊功能,當(dāng)HTTP請求為該兩種功能請求時,事件處理器還需要通過訪問數(shù)據(jù)庫對接收到的用戶名和用 戶密碼進行判斷或存儲操作。事件處理器的整體流程如圖3. 7所示。圖3. 7事件處理器流程在本工程中事件處理器的業(yè)務(wù)處理可以分為兩個模塊:HTTP請求報文解析模塊、HTTP 響應(yīng)報文生成模塊。3. 3. 1 HTTP請求報文解析模塊本模塊主要工作是對客戶端發(fā)送來的HTTP請求報文進行解析。HTTP請求報文由請求行、請求頭部、空白行、請 求體構(gòu)成,每一行都以CRLF (回車符和換行符)作為結(jié)尾標(biāo)志19。在IITTP/L1中,請求行由請求方法、URI、HTTP協(xié)議版本構(gòu)成。請求頭部由多行構(gòu)成,每行以鍵值對的形式表示 (鍵為頭部字段名)。請求頭部包含了一些該連接和報文的信息,如表示長連接狀態(tài)的keep-alive、請求體的編碼 方式content-type等??瞻仔袥]有數(shù)據(jù)只有CRLF表示空白的一行,用來區(qū)分請求頭部和請求體。請求體攜帶客戶端 發(fā)送的數(shù)據(jù),如通過POST請求報文發(fā)送的表單。HTTP請求解析模塊主要有三個狀態(tài):解析請求行、解析請求頭部、解析請求體。狀態(tài)轉(zhuǎn)移如圖3. 8所示。GET請求報 文和POST請求報文是本文的主要解析對象。GET請求報文把參數(shù)存放在URL請求體數(shù)據(jù)為空,事件處理器無需解析GET請求報文的請求體。POST請求報文的參數(shù)被存放在POST請求報文的請求體中,事件處理器需要對 POST請求報文的請求體進行解析,從中獲取報文參數(shù)。登陸和注冊通過POST報文發(fā)送請求,用戶名和用戶密碼存放在請求體中。在解析請求體過程中,需要對通過解 析得到的用戶名、用戶密碼進行處理:當(dāng)報文請求為登錄時,向存儲單元查詢用戶名、用戶密碼進行校驗;當(dāng)報文 請求為注冊時,向存儲單元查詢用戶名、密碼合法性,如果合法那么進行存儲。3.3.2 HTTP響應(yīng)報文生成模塊 本模塊主要工作是生成發(fā)送給客戶端的HTTP響應(yīng)報文。HTTP響應(yīng)報文由響應(yīng)行、響應(yīng) 頭部、空白行、響應(yīng)體構(gòu)成,每一行以CRLF表示該行結(jié)尾。響應(yīng)行由HTTP協(xié)議 版本、狀態(tài)碼、狀態(tài)碼描述構(gòu)成。狀態(tài)碼由三個十進制數(shù)字組成,狀態(tài)碼的類型由第一個數(shù)字定義。狀態(tài)碼和狀態(tài)碼描述表示HTTP響應(yīng)報文的報 文類型。HTTP響應(yīng)報文生成模塊流程如圖3. 9所示。圖3. 8 HTTP解析模塊狀態(tài)轉(zhuǎn)移圖3. 9 HTTP響應(yīng)報文生成模塊流程“客戶端請求資源合法”是指客戶端請求的資源存在并且是一些指定的文件,而不是某個文件夾。3.4日志系統(tǒng)日志是記錄服務(wù)器運行狀態(tài)的文件,對于服務(wù)器開發(fā)人員和服務(wù)器運維人員而言日志是一種能夠直觀地觀察服 務(wù)器狀態(tài)的重要文件。通過日志,服務(wù)器開發(fā)人員可以查看服務(wù)器的日常運行狀態(tài),對服務(wù)器架構(gòu)和功能作出調(diào)整 和拓展;服務(wù)器運維人員可以根據(jù)日志中的錯誤信息對服務(wù)器進行錯誤排查。日志系統(tǒng)的實現(xiàn)有兩種方式:同步模 式和異步模式。同步模式的寫入操作與事件處理器串行執(zhí)行。寫日志文件會涉及到I/O操作,同步模式在I/O操作時會阻塞整個 處理流程。當(dāng)單條日志記錄較大時,事件處理器會被阻塞較長時間,整個服務(wù)器的并發(fā)度將有所下降。如果服務(wù)器 需要處理大量連接請求時,寫日志操作可能會成為系統(tǒng)瓶頸。異步模式需要阻塞隊列作為事件處理器和寫日志模塊的傳輸介質(zhì)。事件處理器把日志記錄存入阻塞隊列,寫日 志模塊異步地從阻塞隊列中獲取日志記錄并寫入日志文件。異步模式把寫日志操作與業(yè)務(wù)處理流程進行別離,防止 業(yè)務(wù)處理流程被阻塞,提高了服務(wù)器業(yè)務(wù)處理的并發(fā)度。日志記錄根據(jù)記錄信息被劃分為多個等級。例如,日志記錄被分為調(diào)試信息、運行信息、錯誤信息等幾個級別 ,服務(wù)器正常運行時僅記錄運行信息和錯誤信息;服務(wù)器調(diào)試時記錄包括調(diào)試信息的所有信息。服務(wù)器可以根據(jù) 不 同的運行狀態(tài)選擇不同的日志等級,過濾無需記錄的日志信息,從而提高日志文件的可讀性。日志系統(tǒng)的寫入記錄 流程如圖3. 10所示。根據(jù)日志等 級、日志參數(shù) 創(chuàng)立相應(yīng)的E 志記錄 1 < JU)第N個日志文件結(jié)束同步璜式日阻先入業(yè)不11 志塞處板異步建式寫日志模塊異步地從阻塞隊列中茨取日志記錄,并把日志記錄寫入日志文件圖3.10寫入日志記錄流程4工程實現(xiàn)4.1服務(wù)器整體功能 本工程是在Linux環(huán)境下使用C+實現(xiàn)的Web服務(wù)器。目標(biāo)服務(wù)器基于Reactor模式,結(jié)合了 epoll和非阻塞Socket,利用線程池和數(shù)據(jù)庫連接池實現(xiàn)了LT模式、ET模式下對GET請求報文、POST請求報文的解析和響應(yīng),使用定 時器實現(xiàn)了對長連接的管控。此外,本工程還實現(xiàn)了同步和異步兩種模式下的日志系統(tǒng),用于記錄系統(tǒng)運行狀態(tài)。 4.2阻塞隊列STL向C+開發(fā)者提供了deque、queue等模板類隊列,這些模板類使用方便、接口清晰,但不具備線程平安性。 根據(jù)參考文獻20的第十二條: library implementation that allows multiple readers on one container and multiple writers on separate containers. You can't hope for the library to eliminate the need for manual concurrency control, and you can,t rely on any thread support at all. ”可知如果要實現(xiàn)STL的線程平安性,程序員必須 自己去完成相關(guān)平安措施。本工程通過互斥鎖、條件變量對deque重新封裝,利用“生產(chǎn)者-消費者”模式實現(xiàn)了具有線程平安性的阻塞隊 列。力口鎖(lock mutex)被條件兗量 consumer 阻塞元素出隊解鎖(unlock mutex)圖4.1阻塞隊列的入隊和出隊4.3日志系統(tǒng)4.3.1 單例模式為了防止日志文件混亂,日志系統(tǒng)在服務(wù)器運行過程中應(yīng)該只存在一個實例,即單例模式實現(xiàn)日志 系統(tǒng)。單例模式是最常用的設(shè)計模式之一,通過私有化構(gòu)造函數(shù)來保證一個類無法類外實例化,并提供相應(yīng)的實例訪問接口給 其它程序模塊訪問,該接口只能獲取該類的唯一實例。在C+11標(biāo)準(zhǔn)21中,對局部靜態(tài)變量的初始化作出以下要 求:“Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined. n 因此,在C+11 標(biāo)準(zhǔn)中,局部靜態(tài)變量的初始化 是具備線程平安性的。單例類可以通過在實例訪問接口中定義該類的局部靜態(tài)對象來定義唯一實例。這種方法是單例模式中的懶漢模式,因為C+中的局部靜態(tài)對象只有在第一次訪 問時才會被初始化。實例接口代碼如下所示。1 .Log* Log:Instance() . static Log minstance;2 . return &m_instance;.)4.3.2 日志級別日志系統(tǒng)提供四種日志級別,從低到高依次為:DEBUG、INFO、WARN、ERRORo低級別的記錄信息會 被日志系統(tǒng)的級別過濾。DEBUG:記錄調(diào)試信息,如請求資源信息、數(shù)據(jù)庫查詢信息等。該級別的信息用于記錄調(diào)試服務(wù)器時服務(wù)器的詳 細(xì)運行過程,在服務(wù)器實際運行時不使用。INFO:記錄服務(wù)器當(dāng)前狀態(tài),如當(dāng)前的執(zhí)行流程、接收信息、連接數(shù)量等。該級別的信息用于記錄服務(wù)器實際 運行時的狀態(tài)。WARN:記錄警告信息,如服務(wù)器連接數(shù)已滿。該級別的信息表示服務(wù)器可能出現(xiàn)了異常情況。ERROR:記錄系統(tǒng)出 錯信息,如服務(wù)器初始化出錯、創(chuàng)立Socket出錯、檢測到了未定義的事件等。該級別的信息用于記錄服務(wù)器的出錯信息。日志系統(tǒng)定義了四個宏:“LOG_DEBUG”、“L0GJNF0"、“LOGJVARN”、“ LOG_ERROR”。其它程序通過調(diào)用這四個宏向日志系統(tǒng)傳輸日志信息。為了區(qū)分記錄級別,四個宏都通過調(diào)用“LOG_BASE”來進行級別檢查,不同的 接口調(diào)用“LOG_BASE”時傳入不同的記錄等級參數(shù)?!癓OGBASE”的偽代碼如圖4. 2所示。4.3.3 分日期、分記錄數(shù)量創(chuàng)立日志文件日志記錄寫入日志文件時日志系統(tǒng)對當(dāng)前翻開的日志文件的日期、記錄數(shù)量進行檢查,日志系統(tǒng)根據(jù)日期、記 錄數(shù)量對日志文件進行分類。如果當(dāng)前日期與日志系統(tǒng)翻開日志文件的日期不一致,那么日志系統(tǒng)新建日志文件,日 志名稱為當(dāng)前日期;如果當(dāng)前翻開的日志文件的記錄數(shù)到達單個日志文件的最大記錄數(shù),那么日志系統(tǒng)將創(chuàng)立一個日志名稱帶有當(dāng)前日期和計數(shù)后綴的新日志文件22 o檢查日志文件日期、記錄數(shù)量的偽代碼如圖4. 3所示。4.3.4 同步模式、異步模式日志系統(tǒng)的模式在服務(wù)器初始化中決定:阻塞隊列長度等于零為同步模式,阻塞隊列長度大于零為異步模式。日志 系統(tǒng)根據(jù)不同的記錄級別、日志信息生成相應(yīng)的日志記錄,并寫入日志文件。同步模式中記錄寫入日志文件的I/O操作與處理業(yè)務(wù)的工作線程串行執(zhí)行,會阻塞工作線程;異步模式創(chuàng)立一個日志寫入線程,工作線程把日志 記錄插入阻塞隊列,由日志寫入線程異步地從阻塞隊列獲取日志記錄并執(zhí)行I/O操作。、日志寫入的偽代碼如圖4. 4 所示。Algorithm 1: LOG_BASEInput: level, loginfoif levelInstance.level thenWirteLog(level, loginfo);flush;end圖4.2 L0G_BASEAlgorithm 2: CheckLogif log. date * today or (count % maxCount) = 0 thenif log. date 盧 today thencreate new log, name is today;log. date = today;count = 1;elsecreate new log, name is today,(count / maxCount);endend圖4. 3檢查日志文件Algorithm 3: WriteLogInput: level, loginfoCheckLog;logging = C r eat eLogging (level. liglnfo);if is A sync thenLogging Q uque. p ush (logging);elsewrite (logging);end圖4. 4日志寫入4.3.5 4線程池4. 4.1線程池成員線程池主要由兒個成員組成:存儲任務(wù)(任務(wù)為回調(diào)函數(shù))的阻塞隊列、負(fù)責(zé)線程互斥訪問臨界 區(qū)的互斥鎖、負(fù)責(zé)線程同步的條件變量。4. 4.2工作線程的同步與競爭根據(jù)圖3. 7可知線程池中的工作線程與主線程存在同步關(guān)系,與其它工作線程存在競爭關(guān)系,即半同步/半異步模式。工作線程的執(zhí)行流程偽代碼如圖4. 5所示。Algorithm 4: Workmutex lock;while threadpool is not closed doif BlockQueue is not empty thenget task from BlockQueue;mutex unlock:processing the task;mutex lock;elsethread is blocked by condition variable;endendmutex unlock;圖4.5工作線程工作線程初始化后對線程池中的mutex進行加鎖,然后訪問臨界區(qū),在線程池關(guān)閉前循環(huán)執(zhí)行。如 果存儲任務(wù)的阻塞隊列不為空,工作線程從阻塞隊列中取出任務(wù),然后對mutex解鎖并處理任務(wù)。任務(wù)完成后重新嘗試對mutex力口 鎖,再次參與競爭。如果存儲任務(wù)的阻塞隊列為空,工作線程被條件變量阻塞(工作線程被條件變量阻塞會釋放 mutex的所有權(quán),即解鎖),只有主線程向阻塞隊列插入新的任務(wù)或主線程關(guān)閉線程池時才被喚醒(工作線程被喚醒 后重新嘗試對mutex加鎖,重新參與競爭)。兩種喚醒方式的區(qū)別在于新的任務(wù)插入阻塞隊列只會喚醒一個被條件變 量阻塞的工作線程,線程池關(guān)閉會喚醒所有被條件變量阻塞的線程。4.5數(shù)據(jù)庫連接池 數(shù)據(jù)庫連接池的實現(xiàn)方法比線程池更簡單,本質(zhì)是使用一個阻塞隊列存儲空閑的數(shù)據(jù)庫連接。工 作線程向數(shù)據(jù)庫連接池申請和歸還數(shù)據(jù)庫連接實際是對阻塞隊列的出隊和入隊操作。但阻塞隊列的入隊操作如果交給程序員處理 可能會存在遺漏入隊的情況,導(dǎo)致空閑的數(shù)據(jù)庫連接沒有重新進池,從而浪費空閑資源,甚至最后會導(dǎo)致數(shù)據(jù)庫連 接池?zé)o空閑的數(shù)據(jù)庫連接可用。同時,程序沒有主動釋放動態(tài)申請的資源,造成了內(nèi)存泄漏。為了防止某個線程使用完數(shù)據(jù)庫連接后沒有釋放數(shù)據(jù)庫連接的所有權(quán),數(shù)據(jù)庫連接的分配和回收通常采用RAH (Resource Acquisition Is Initialization,資源獲取就是初始化)機制,程序通過定義一個封裝了從數(shù)據(jù)庫連 接池獲取和歸還連接的RAU類來管理連接的分配和回收23。RAH類在構(gòu)造函數(shù)中獲取數(shù)據(jù)庫連接,在析構(gòu)函數(shù)中 歸還數(shù)據(jù)庫連接。通過RAU機制,工作線程只能通過定義一個RAH實例獲取數(shù)據(jù)庫連接。同時工作線程無需主動歸 還數(shù)據(jù)庫連接,因為線程對數(shù)據(jù)庫連接的所有權(quán)周期就是RAH實例的生命周期,當(dāng)線程完成數(shù)據(jù)庫訪問后退出相應(yīng) 作用域,RAH實例被系統(tǒng)自動銷毀,RAH實例的析構(gòu)函數(shù)釋放數(shù)據(jù)庫連接。數(shù)據(jù)庫連接RAH類的構(gòu)造函數(shù)和析構(gòu)函 數(shù)的偽代碼如圖4. 6所示。Algorithm 5: Construct SqlPoolRAIIOutput: sqlConnectionget sqlConnection from sqlConnectionQueue;mySqlConnection = sqlConnection;Algorithm 6: Destruct SqlPoolRAIIif mySqlConnection is not empty thensqlConnectionQueue.push(mySqlConnection):end圖4.6數(shù)據(jù)庫連接RAH類的構(gòu)造函數(shù)和析構(gòu)函數(shù)4. 6解析HTTP請求報文4. 6.1 HTTP請求報文解析流程根據(jù)圖3. 8可知HTTP解析主要分為三局部:解析請求行、解析請求頭部、解析請求體o請求行主要解析請求報文的請求方法、URI、HTTP協(xié)議版本,請求頭部主要解析關(guān)于連接和報文的各種信息,請求體主要解析某些報文的參數(shù)(POST報文)。解析請求體前逐行解析行、請求頭部。本工程HTTP請求報文解析模塊從HTTP請求中解析得到的信息,包含:請求方法,URL協(xié)議版本,連接類型(Connection,表示短連接或長連接),長連接信息(keep-alive)請求體編碼方式,請求體長度,表單參數(shù)(用 戶名、密碼)。4. 6. 2解析請求行請求行由請求方法、URI和HTTP協(xié)議版本組成,以空格分隔,整行格式為“請求方法URI HTTP/協(xié)議版本”。請 求行可以通過正那么表達式進行匹配。由于請求行的三個元素由空格隔開,并且版本協(xié)議前帶有“HTTP/",所以匹配 正那么表達式為:乂廠*)(廠*) HTTP/(1*)$通過正那么表達式匹配可得到請求報文的請求方法、URI和HTTP協(xié)議版本。URI作為 唯一資源標(biāo)識符,本工程可以通過URI和自定義的“URI-資源路徑”映射表得知請求資源的路徑。4. 6. 3解析請求頭部請求頭部包含許多連接信息,以鍵值對的形式表示,每個鍵值對占一行。STL提供了以鍵值對形式存儲的模板 類:map、unordered_mapo其中map底層由紅黑樹實現(xiàn),unorderedjnap底層由哈希表實現(xiàn)。由于HTTP請求頭部中的 信息無順序意義,因此本工程使用時間復(fù)雜度更低的unorderecUnap存儲請求頭部信息。請求頭部中的鍵值對以冒號和空格(“:”)進行分割,因此可以使用正那么表達式對鍵值對進行匹配。匹配請 求頭部信息的正那么表達式:”:*): ?(.*)$如果匹配失敗,說明解析到了空白行,結(jié)束解析請求頭部。解析請求體請求體的長度和編碼方式在解析請求首部中得知,鍵的名稱分別為"Content-Length"和"Content-Type' o 本工程對編碼方式為uapplication/x-www-form-(JRIencodeclv (大多數(shù)主流瀏覽器提交表單的默認(rèn)編碼方式)的 POST請求進行解析?!癮pplication/x-www-form-URIencoded”的數(shù)據(jù)參數(shù)是鍵值對,表現(xiàn)形式為“key=value”,因此可以使用 unorderedjnap存儲鍵值對參數(shù)。多個參數(shù)之間由別離。編碼規(guī)那么為:參數(shù)中的空格使用“ + ”替換,非數(shù)字、 字母的特殊字符使用三個字符“%xy”替換,其中“xy”表示該字符的十六進制表示形式。請求體的整體解析過程:根據(jù)"app 1 i cat i on/x-w wf orm-UR I encoded v編碼方式對請求體進行反編碼,別離鍵 值對參數(shù)并存入哈希表中。判斷請求報文是否請求注冊或登錄,如果是那么根據(jù)相應(yīng)的參數(shù)判斷請求是否合法,如參 數(shù)中否含有用戶名、用戶密碼。本工程的登陸與注冊校驗過程由HTTP解析模塊完成??蛻舳送ㄟ^POST請求報文提交表單,用戶名和用戶密碼存 放在請求體中。服務(wù)器解析post請求消息并獲取用戶名和密碼,然后通過數(shù)據(jù)庫連接訪問數(shù)據(jù)庫,并查詢用戶名和 密碼是否合法。HTTP請求體解析過程如圖4. 7所示。Algorithm 7: Parse Postif method = POST and Content-Type =application/x-www-form-urlencoded thenEncoded (Body);if Register or Login thenif username and password are legal then path = welcome;elsepath = error;endendend圖4.7解析HTTP請求體 如果請求報文是登錄或注冊請求,那么返回給客戶端的資源的路徑由用戶名、用戶密碼檢查結(jié) 果決定:如果信息正確,資源路徑為成功頁面的路徑;如果信息錯誤,那么資源路徑為錯誤頁面的路徑。4. 7生成HTTP響應(yīng)報文4. 7.1 HTTP響應(yīng)報文生成流程響應(yīng)報文生成模塊根據(jù)解析模塊的結(jié)果,生成響應(yīng)行、響應(yīng)頭部、空白行和響應(yīng)體。 響應(yīng)行主耍生成狀態(tài)碼;響應(yīng)頭部主要生成長連接狀態(tài)、響應(yīng)體長度;響應(yīng)體為根據(jù)解析結(jié)果得到的資源文件。本工程的HTTP響應(yīng)報文生成 模塊中,因為每個連接的報文信息都可能各不相同,因此響應(yīng)行、響應(yīng)頭部、空白行存儲在各個連接的響應(yīng)報文緩沖區(qū)中。為了加快發(fā)送報文時對資源文件的讀取速率,響應(yīng)體對應(yīng)的資源文件通過 內(nèi)存映射存放到內(nèi)存中?!皟?nèi)存映射文件提供了一種獨特的內(nèi)存管理特征,它允許應(yīng)用程序與通過指針訪問動態(tài)內(nèi)存相同的方式訪問磁盤上的文件。因 此,可以在進程地址空間中將磁盤上的文件局部或者全部映射到特定地址范圍,然后通過指針就可以訪問內(nèi)存映射 文件中的內(nèi)容。一旦該文件被映射,就可以訪問它,就像整個文件已經(jīng)加載內(nèi)存一樣,從而可以不必對文件執(zhí)行I/O 操作,這對大數(shù)據(jù)量文件來說存取效率較高24?!眻D4. 8響應(yīng)報文存儲關(guān)系4.7. 2生成狀態(tài)碼根據(jù)圖3. 9可知,能夠成功請求資源的請求報文需要經(jīng)過三次檢查:成功解析請求報文、客戶端請求的資源合 法、客戶端擁有足夠權(quán)限訪問資源。每個階段出錯都會生成相應(yīng)的狀態(tài)碼,只有三次檢查都通過才會生成表示成功 體框架,包括框架中的事件別離器、事件處理器;其中事件處理器是核心模塊,重點分析了其HTTP請求報文解析模 塊和HTTP響應(yīng)報文生成模塊;還分析了日志系統(tǒng)的同步模式和異步模式。在完成需求分析后,對服務(wù)器的各個模塊 進行設(shè)計和實現(xiàn),包括阻塞隊列、日志系統(tǒng)、線程池、數(shù)據(jù)庫連接池、HTTP請求報文解析、HTTP響應(yīng)報文生成以及 管控HTTP長連接的定時器。各模塊通過面向?qū)ο蟮乃枷雽崿F(xiàn)了相應(yīng)的功能接口,降低了模塊間的耦合度。最后,本 文對服務(wù)器進行了壓力測試和穩(wěn)定性測試,并對應(yīng)用層面的注冊功能、登錄功能和大文件傳輸功能進行了測試。本 文涉及了Socket的監(jiān)聽與連接、網(wǎng)絡(luò)I/O管理、線程池設(shè)計和HTTP協(xié)議分析,對解決Web服務(wù)器中遇到的問題具有很 好的工程參考價值。關(guān)鍵詞:Linux, C+,高并發(fā),epoll, Reactor AbstractWith the rapid development of information technology, the Internet has become an indispensable part of social production and life. Especially in the past decade, due to the progress of mobile technology and the popularity of intelligent mobile devices, the number of Internet users is growing explosively, and more and more industries are changing through the Internet. The development of user groups has changed the form of Internet services, more and more servers need to provide services for a large number of customers at the same time. Therefore, how to design the communication framework of the server and how to effectively use the system resources of the server have become the focus of server developers.Web application has the characteristics of short connection interval, strong burst and short response time. It is a service with high concurrency requirements. In this thesis, we choose the mainstream Linux operating system in the server system, use C+, combine socket, I/O multiplexing technology epoll, non blocking I/O, thread pool, timer and Reactor event processing mode, design and implement a stable and high concurrent web server.This thesis first introduces and analyzes the related technologies of web server, including socket, epoll, Reactor event processing mode, thread pool and database connection pool; the differences between epoll and other I/O models and the characteristics of epoll model are discussed. Secondly, according to the Reactor mode, the overall framework of the server is analyzed, including the event separator and event processor in the framework; the event processor is the core module, focusing on the analysis of its HTTP request message parsing module and HTTP response message generation module; the synchronous mode and asynchronous mode of the log system are also analyzed. After the completion of the requirements analysis, the design and implementation of each module of the server, including blocking queue, log system, thread pool, database connection pool, HTTP request message parsing, HTTP response message generation and the timer to control the HTTP long connection. Each module realizes the corresponding function interface through the idea of object-oriented, which reduces the coupling degree between modules. Finally, this thesis tests the pressure and stability of the server, and tests the registration function, login function and large file transfer function of the application level. This thesis involves socket monitoring and connection, network I/O management, thread pool design and HTTP protocol analysis, which has good engineering reference value to solve the problems encountered in web server. Key words: Linux, C+, high-concurrency, epoll, Reactor目錄1緒論.12開發(fā)技術(shù)介紹 22. 1 Socket,22.2 I/O多路復(fù)用技術(shù)EPOLL.41. 2.1 五種 I/O 模型 .42. 2 EPOLL42. 3 Reactor事件處理模式.7的狀態(tài)碼“200”。能否成功解析請求報文是由請求報文解析模塊進行判斷的。如果HTTP請求報文格式出錯(如請 求行格式出錯),那么狀態(tài)碼設(shè)置為“400”。該階段檢查的“出錯”僅表示請求報文格式出錯,而登錄或注冊請求中的用戶信息 出錯不屬于該階段的檢查范圍,僅屬于應(yīng)用層面上的出錯。所以用戶信息錯誤的登錄或注冊請求也是一次成功的請 求,服務(wù)器發(fā)送的響應(yīng)報文依然是狀態(tài)碼為“200”的成功響應(yīng)報文,只是頁面資源是表示用戶信息出錯的頁面,而 不是成功頁面。客戶端請求資源合法表示客戶端請求的資源應(yīng)該存在并且是有效資源,不能是某個文件夾。客戶端擁有足夠權(quán)限訪 問資源表示客戶端請求的資源在服務(wù)器的權(quán)限是中是“其它用戶可讀"。Linux中的文件權(quán)限分為“可讀”、“可寫”、“可執(zhí)行”,本工程主要檢查客戶端是否有權(quán)限讀資源,在開發(fā)中使用SJR0TH (表 示其他用戶可讀的權(quán)限值,與文件的權(quán)限值進行與運算可知文件能否被其他用戶讀)對資源文件的權(quán)限進行檢查。 生成狀態(tài)碼的偽代碼如圖4. 9所示。Algorithm 8: CreateStatusCode Output: Status Code if Parse Post = FALSE thenStatus Code = 400;endelse if resource does not exist or resource is a folder thenStatus Code = 404;endelse if resource is not readable thenStatus Code = 403;endelseStatus Code = 200;end圖4.9生成狀態(tài)碼的偽代碼生成響應(yīng)行、響應(yīng)頭部、空白行本工程定義了 “狀態(tài)碼-狀態(tài)碼描述”映射表,生成響應(yīng)行時向HTTP響應(yīng)報文緩沖區(qū)寫入?yún)f(xié)議版本、狀態(tài)碼、狀 態(tài)條件。本工程定義了 “文件類型-MIME類型”映射表,生成響應(yīng)頭部時根據(jù)資源的文件類型向HTTP響應(yīng)報文緩沖區(qū)寫入 資源的MIME類型參數(shù)(Content-Type) o同時,根據(jù)連接類型向緩沖區(qū)寫入連接類型參數(shù)(Connection),如果連 接類型為長連接還需寫入長連接參數(shù)(keep-alive) o長連接類型參數(shù)的值為timeout和max,表示連接生存時間和 最大請求數(shù)。最后寫入響應(yīng)體長度參數(shù)(Content-Length)和空白行。4. 7.4生成響應(yīng)體目標(biāo)資源文件通過內(nèi)存映射被映射到內(nèi)存中。服務(wù)器向客戶端發(fā)送響應(yīng)報時文從映射對象中讀取 數(shù)據(jù)并寫入Socketo為了防止程序影響原文件,內(nèi)存映射類型應(yīng)設(shè)為MAP_PRIVATE。這種類型表示程序?qū)?nèi)存映射中的映射區(qū)進 行修改時會執(zhí)行“寫時拷貝”獲得一份私有的文件拷貝,對文件的修改都是對這篇私有內(nèi)存的修改,不寫回原文件O4. 8定時器本工程通過定時器對HTTP長連接進行管控。服務(wù)器在初始化時定義連接的生存時間,接收到請求報文后為連接 設(shè)置定時器。定時器使用小頂堆實現(xiàn),每個節(jié)點存儲某個連接的定時器信息。定時器信息包括Socket的文件描述符、超時時 間點、回調(diào)函數(shù),其中超時時間點為定時器設(shè)置時間加上連接的生存時間,回調(diào)函數(shù)為關(guān)閉連接函數(shù)。各個信息的 作用是:主線程設(shè)置或重置連接的定時器時根據(jù)Socket的文件描述符找到指定的定時器節(jié)點;主線程根據(jù)定時器的 超時時間點判斷該連接是否超時,如果超時那么調(diào)用回調(diào)函數(shù)關(guān)閉連接。小頂堆的底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,根據(jù)節(jié)點的超時時間點排序建堆。主線程在重置定時器時需要根據(jù)文件描述符 找到定時器節(jié)點,因此還需要定義一個“文件描述符-節(jié)點下標(biāo)”映射表,可以使用unorderedjnap實現(xiàn)。新增連接時判斷堆中是否存在含有該Socket文件描述符的節(jié)點。如果不存在,主線程向堆尾中插入新的定時器 節(jié)點,并根據(jù)超時時間點對節(jié)點向上調(diào)整;如果存在,說明之前使用該文件描述符的連接雖然已經(jīng)被關(guān)閉但目前事 件還到達該連接的超時時間點,主線程重置該節(jié)點的超時時間點,并對節(jié)點向下調(diào)整。某個連接有新的事件到達,主線程重置該連接定時器的超時時間點:通過文件描述符和“文件描述符-節(jié)點下 標(biāo)”的映射表找到定時器節(jié)點的下標(biāo),修改定時器節(jié)點的超時時間點并對節(jié)點向下調(diào)整。調(diào)整過程中定時器需要維護“文件描述符-節(jié)點下標(biāo)”的映射表。向上調(diào)整如圖4. 10所示,向下調(diào)整如圖4. 11所/Js o圖4.10定時器節(jié)點向上調(diào)整國弱陸禁漁IIR延您腐圖4.11定時器節(jié)點向下調(diào)整清除超時節(jié)點只需要判斷根節(jié)點是否超時,如果超時那么刪除根節(jié)點,調(diào)整堆:交換根 節(jié)點與最后一個節(jié)點,刪除最后節(jié)點并對新的根節(jié)點向下調(diào)整。主線程不斷清除直到根節(jié)點不超時或堆為空。對于連接已經(jīng)關(guān)閉的節(jié)點無需 管理。因為如果有新的連接使用該節(jié)點的文件描述符,該節(jié)點會析構(gòu)舊連接的信息,存儲新連接的信息,并調(diào)整節(jié) 點位置;如果時間到達了舊連接的超時時間點,該節(jié)點會與其它超時節(jié)點一起被清除。為了能夠有效地對超時連接進行關(guān)閉,當(dāng)堆不為空時主線程應(yīng)有限地等待到達事件,并且等待時間為定時器根 節(jié)點的超時時間點減去當(dāng)前時間。在此期間內(nèi)如果沒有事件到達那么根節(jié)點對應(yīng)的連接一定超時,需要關(guān)閉。|清輻時節(jié)點|"葉e噩;鬻|-0Y1 斐斐二處是,重置定時弱|圖4. 12堆不為空時主線程有限等待4. 9服務(wù)器整體流程4. 9.1服務(wù)器初始化服務(wù)器啟動階段需要初始化一些數(shù)據(jù):偵聽端口號、epoll模式、連接生存時間、優(yōu)雅退出、 數(shù)據(jù)庫信息(數(shù)據(jù)庫用戶名、密碼、數(shù)據(jù)庫名、數(shù)據(jù)庫訪問端口)、工作線程數(shù)量、數(shù)據(jù)庫連接數(shù)量、日志開關(guān)、日志等級、日志模 式。偵聽端口號:客戶端根據(jù)服務(wù)器的IP地址和偵聽端口號發(fā)起TCP連接,服務(wù)器通過偵聽端口號接收客戶端請求。 epoll模式:決定服務(wù)器使用LT模式還是ET模式。連接生存時間:決定一個空閑的連接可以維持多長時間。優(yōu)雅退出:決定服務(wù)器關(guān)閉連接時是否優(yōu)雅退出。數(shù)據(jù)庫信息:用于初始化數(shù)據(jù)庫連接。日志開關(guān):決定服務(wù)器是 否使用日志系統(tǒng)。日志等級:決定服務(wù)器翻開的日志系統(tǒng) 的等級。日志模式:決定日志系統(tǒng)使用同步模式還是異步模式。服務(wù)器運行主線程流程如圖4. 13所示。error圖4. 13主線程流程工作線程流程如圖4. 14所示。圖4. 14工作線程流程5服務(wù)器測試測試環(huán)境 服務(wù)器系統(tǒng):ubuntul8. 04服務(wù)器處理器內(nèi)核總數(shù):4服務(wù)器內(nèi)存:8GB5.1 測試工具本工程使用WebBench對服務(wù)器進行壓力測試和穩(wěn) 定測試25。WebBench是VeriTest公司開發(fā)的一款測試工具,其原理是通過父進程fork多個子進程,由子進程對目標(biāo)URI發(fā)起 實際請求并記錄請求結(jié)果。子進程把結(jié)果返回給父進程,由父進程整理和統(tǒng)計子進程記錄的信息,反應(yīng)于用戶。用 戶能夠通過WebBench向目標(biāo)Web服務(wù)器發(fā)起一定數(shù)量的并發(fā)請求,并發(fā)連接數(shù)和持續(xù)時間可由用戶決定,但并發(fā)數(shù)量 不能超過三萬。5.2 壓力測試和穩(wěn)定測試的服務(wù)器參數(shù)關(guān)閉方式:優(yōu) 雅退出。線程數(shù)量:6O日志系統(tǒng):關(guān) 閉。epoll模式:偵聽Socket設(shè)為LT模式,連接Socket分LT模式和ET模式進行測試。5.3 壓力測試單次測試時長為5秒,并發(fā)連接數(shù)從1000開始,以2000為步長進行增長,直到服務(wù)器支持上萬并發(fā)。LT模式、ET 模式各進行十次測試,測試結(jié)果見附錄。結(jié)果平均值如表5.1、5.2所示。表5. 1 LT模式壓力測試并發(fā)連接數(shù)數(shù)據(jù)傳輸速率bytes/s成功次數(shù)每秒成功次數(shù)10005464886. 4202652.26754. 630004481209.4214422.67146.850004441323.4221291.77375. 970004556732229431. 57647. 390004461308.42273117586. 6110004292933.3222241.87407. 7表5. 2 ET模式壓力測試并發(fā)連接數(shù)數(shù)據(jù)傳輸速率bytes/s成功次數(shù)每秒成功次數(shù)10005368129.2199063. 8663530004447417. 8213078.57104. 750004364842. 2215823.27193. 770004424853. 2223747. 17457. 890004196370. 8215830.37193.9110004193782. 7218356.87278. 1從表中可知LT模式和ET模式均能支持上萬并發(fā),并且每秒處理的連接請求數(shù)(qps)約為7000。5.4 穩(wěn)定測試測試時長為10分鐘,并發(fā)連接數(shù)11000。對ET模式、LT模式各進行3次測試,測試結(jié) 果如下。11000 clients, running 600 sec.Speed=452658 pages/min, -2733954 bytes/sec.Requests: 4496798 susceed, 29787 failed.圖5.1 LT模式第一次穩(wěn)定測試11000 clients, running 600 sec.Speed=458109 pages/min, -2694015 bytes/sec.Requests: 4551932 susceed, 29163 failed.圖5. 2 LT模式第二次穩(wěn)定測試11000 clients, running 600 sec.Speed=443065 pages/min, -2833884 bytes/sec.Requests: 4400922 susceed, 29737 failed.圖5. 3 LT模式第三次穩(wěn)定測試11000 clients, running 600 sec.Speed=415562 pages/min, -3129087 bytes/sec.Requests: 4126594 susceed, 29035 failed.圖5. 4 ET模式第一次穩(wěn)定測試11000 clients, running 600 sec.Speed=424722 pages/min, -3033192 bytes/sec.Requests: 4218901 susceed, 28322 failed.圖5. 5 ET模式第二次穩(wěn)定測試11000 clients, running 600 sec.Speed=422485 pages/min, -3066281 bytes/sec.Requests: 4196183 susceed, 28669 failed.圖5.6 ET模式第三次穩(wěn)定測試根據(jù)測試結(jié)果可知服務(wù)器能在處理上萬并發(fā)連接的情況下保持服務(wù)器穩(wěn)定,每秒處理 的連接請求數(shù)和壓力測試結(jié)果一樣約為7000。測試結(jié)果中的每秒字節(jié)數(shù)傳輸速率為負(fù)是因為數(shù)據(jù)過大造成了整型溢出。5.5 注冊、登錄功能測試用戶表初始為空。rrysql> select * from user;Empty set (0.00 sec)圖5.7用戶表初始內(nèi)容注冊 用戶。C O A Not secure192.168.3.1. * y :首頁圖5.8首頁圖5. 9注冊圖5.10注冊成功,進入功能界面mysql> select * from user;+| username|password|+| 123456|123456|+1 row inset(0.00 sec)圖5.11數(shù)據(jù)庫存入用戶名、用戶密碼 登錄需要對用 戶名、用戶密碼進行校驗。<-> C O A Not secure 192.16.所 y登錄用戶名 用戶密碼確定用戶名、用戶密碼錯誤=圖5. 12用戶信息錯誤,返回錯誤信息 注冊對用戶名 進行校驗,防止重新注冊。圖5. 13用戶名被注冊5. 7文件測試服務(wù)器讀取內(nèi)存映射區(qū)中的文件數(shù)據(jù),作為響應(yīng)體發(fā)送給客戶端。S 今 C 。 A Not secure 192.1683.129:2333/. d . * n y圖5.14視頻測試192.168.3. R 192.168.3. R <-» C 6 A Not圖5. 15圖片測試6課題總結(jié)本文主要介紹了Linux環(huán)境下關(guān)于C+服務(wù)器開發(fā)的相關(guān)技術(shù),分析了服務(wù)器的整體需求,并設(shè)計了一個結(jié)合 Reactor模式、epoll、非阻塞I/O以及線程池的高并發(fā)Web服務(wù)器。其中主要對服務(wù)器的高并發(fā)相關(guān)技術(shù)進行了詳細(xì) 探討:epoll模式選擇、阻塞隊列實現(xiàn)原理、主線程與線程池的半同步/半異步模型、日志系統(tǒng)的同步/異步模式。 通過實驗測試,可以得知本文設(shè)計的服務(wù)器在主流PC中運行可以支持上萬并發(fā),并且可以保證服務(wù)器穩(wěn)定運行。同時,本文設(shè)計的服務(wù)器還支持用戶登錄、注冊功能。工作線程通過數(shù)據(jù)庫連接池和RAH機制完成多線程模式 下對數(shù)據(jù)庫的有序訪問,并對客戶端的用戶名、用戶密碼進行校驗。對于文件傳輸,服務(wù)器通過內(nèi)存映射把資源文 件拷貝進內(nèi)存,減少了程序?qū)ξ募x取的I/O操作,加快了文件傳輸速率。對于長連接,服務(wù)器通過小頂堆實現(xiàn)了定 時器,完成了對超時連接的主動釋放。本文設(shè)計的服務(wù)器雖然保證了高并發(fā)場景下的穩(wěn)定運行,但依然存在一些應(yīng)用場景問題。本文設(shè)計的服務(wù)器處 理的請求都是無狀態(tài)的,因此登錄功能會失去實際意義。有狀態(tài)場景需要服務(wù)器生成session并向客戶端返回 cookie, cookie的生成和session的保存在高并發(fā)場景下會變成一個新的難題。我將在后續(xù)工作中繼續(xù)改進,為服務(wù) 器的可用性提供更多支持。參考文獻1中國互聯(lián)網(wǎng)絡(luò)信息中心.第46次中國互聯(lián)網(wǎng)絡(luò)開展?fàn)顩r統(tǒng)計報告R.北京:中共中央網(wǎng)絡(luò)平安和信息化委員會 辦公室,中華人民共和國國家互聯(lián)網(wǎng)信息辦公室,2020.2周炎濤,李立明.TCP/IP協(xié)議下網(wǎng)絡(luò)編程技術(shù)及其實現(xiàn)J.航空計算技術(shù),2002(03):126-128+132.3W. RichardStevens, BillFenner, AndrewM. Rudoff. UNIX網(wǎng)絡(luò)編程,第 1 卷,套接口API M.清華大學(xué)出版 社,2006.4W. RICHARDSTEVENS. TCP/IP詳解.卷1,協(xié)議機械工業(yè)出版社,2000.5MichaelKerrisk,凱利斯克,孫劍,等.Linux/UNIX系統(tǒng)編程手冊M.人民郵電出版社,2014. 6胥光輝,徐永森.同步阻塞線程的喚醒問題研究J.計算機科學(xué),2002, 29(012):49-50.7 Gammo L , Brecht T , Shukla A , et al. Comparing and Evaluating epoll, select, and poll Event Mechanisms. Proceedings of Annual Linux Symposium, 2004.8Linux下基于EPOLL機制的海量網(wǎng)絡(luò)信息處理模型J.強激光與粒子束,2013, 25(Ozl):46-50. 9游 雙.Linux高性能服務(wù)器編程加.機械工業(yè)出版社,2013.10 Schmidt D C . Reactor - An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events. 1999.11李璞,張玲,胡術(shù),等.多線程環(huán)境下Reactor模式的研究與實現(xiàn)J.網(wǎng)絡(luò)新媒體技術(shù)

注意事項

本文(Linux環(huán)境下高并發(fā)web服務(wù)器 的設(shè)計與實現(xiàn).docx)為本站會員(黑**)主動上傳,裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對上載內(nèi)容本身不做任何修改或編輯。 若此文所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng)(點擊聯(lián)系客服),我們立即給予刪除!

溫馨提示:如果因為網(wǎng)速或其他原因下載失敗請重新下載,重復(fù)下載不扣分。




關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!