Linux環(huán)境下高并發(fā)web服務(wù)器 的設(shè)計與實(shí)現(xiàn).docx
《Linux環(huán)境下高并發(fā)web服務(wù)器 的設(shè)計與實(shí)現(xiàn).docx》由會員分享,可在線閱讀,更多相關(guān)《Linux環(huán)境下高并發(fā)web服務(wù)器 的設(shè)計與實(shí)現(xiàn).docx(31頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、Linux環(huán)境下高并發(fā)web服務(wù)器的設(shè)計與實(shí)現(xiàn) 摘要 隨著信息技術(shù)的飛速開展,互聯(lián)網(wǎng)已經(jīng)成為社會生產(chǎn)生活中不可缺少的一局部。特別是近十年來,由于移動技 術(shù)的進(jìn)步和智能移動設(shè)備的普及,互聯(lián)網(wǎng)用戶數(shù)量呈爆發(fā)式增長,越來越多的行業(yè)正在通過互聯(lián)網(wǎng)進(jìn)行變革。用戶 群體的開展改變了互聯(lián)網(wǎng)服務(wù)的形式,越來越多的服務(wù)器需要同時為大量客戶提供服務(wù)。因此,如何設(shè)計服務(wù)器的 通信框架,如何有效利用服務(wù)器的系統(tǒng)資源,成為服務(wù)器開發(fā)人員關(guān)注的焦點(diǎn)。 Web應(yīng)用具有連接間隔短、突發(fā)性強(qiáng)、響應(yīng)時間短等特點(diǎn),它是一種對并發(fā)性要求很高的服務(wù)。本文在服務(wù)器系 統(tǒng)中選擇主流的Linux操作系統(tǒng),采用C++,結(jié)合Socket、
2、I/O多路復(fù)用技術(shù)epoll、無阻塞I/O、線程池、定時器和 Reactor事件處理模式,設(shè)計并實(shí)現(xiàn)了一個穩(wěn)定支持高并發(fā)的Web服務(wù)器。 本文首先介紹和分析了Wob服務(wù)器的相關(guān)技術(shù),包括Socket、epolK Reactor事件處理模式、線程池和數(shù)據(jù)庫連 接池;重點(diǎn)討論了epoll與其他I/O模型的區(qū)別,以及epoll模型的特點(diǎn)。其次,根據(jù)Reactor模式分析了服務(wù)器的整 圖3. 4事件處理器與存儲隊列存儲單元從阻塞隊列獲取獲取數(shù) 據(jù)進(jìn)行存儲。如圖3. 5所示。 圖3. 5存儲隊列與存儲單元 3. 2事件別離器流程事件別離器主要負(fù)責(zé)接收新連接、偵聽到達(dá)事件。HTTP長連
3、接可以減少TCP連接的創(chuàng)立次數(shù),使客戶端和服務(wù)器能 夠有效復(fù)用TCP連接。但是,“在長連接應(yīng)用 中,服務(wù)器與客戶端實(shí)例都保持一個持久的連接,這將大量消耗服務(wù)器資源,特別是在一些大型應(yīng)用系統(tǒng)中更是如 此,大量并發(fā)的長連接有可能導(dǎo)致新的請求被阻塞甚至系統(tǒng)崩潰[18]?!? 為了對長連接進(jìn)行管控,服務(wù)器可以通過實(shí)現(xiàn)定時器,對每個連接記錄超時時間點(diǎn)來解決這個問題。每當(dāng)某個 連接有新請求到達(dá)時重置該連接的定時器,如果連接超時那么服務(wù)器主動釋放連接。判斷超時和重置定時器的工作均 由事件別離器完成,事件別離器工作流程如圖3. 6所示。 設(shè)置新連接的定時 器,把新邇接加入 設(shè)置新連接的定時 器,把新
4、邇接加入 重置龍援的定時器,把 事件和處理方法加入到 I 到檢測集合中 II 事件阻塞隊列中 I 圖3.6事件別離器流程3. 3事件處理器流程 事件處理器是服務(wù)器的核心模塊,主要負(fù)責(zé)的工作是:服務(wù)器的I/O操作、業(yè)務(wù)處理,因此對服務(wù)器的業(yè)務(wù)拓展 工作主要是對事件處理器的功能進(jìn)行拓展。在本工程實(shí)現(xiàn)的Web服務(wù)器中,I/O操作主要是指對Socket進(jìn)行讀寫操 作 ,業(yè)務(wù)處理主要是指對接收到的HTTP請求報文進(jìn)行解析,并生成相應(yīng)的HTTP響應(yīng)報文。同時為了能夠支持用戶登錄 功能和用戶注冊功能,當(dāng)HTTP請求為該兩種功能請求時,事件處理器還需要通過訪問數(shù)據(jù)庫對接收到的用戶名和用 戶密碼進(jìn)行判斷
5、或存儲操作。 事件處理器的整體流程如圖3. 7所示。 圖3. 7事件處理器流程在本工程中事件處理器的業(yè)務(wù)處理可以分為兩個模塊:HTTP請求報文解析模塊、HTTP 響應(yīng)報文生成模塊。3. 3. 1 HTTP請求報文解析模塊 本模塊主要工作是對客戶端發(fā)送來的HTTP請求報文進(jìn)行解析。HTTP請求報文由請求行、請求頭部、空白行、請 求體構(gòu)成,每一行都以CRLF (回車符和換行符)作為結(jié)尾標(biāo)志[19]。 在IITTP/L1中,請求行由請求方法、URI、HTTP協(xié)議版本構(gòu)成。請求頭部由多行構(gòu)成,每行以鍵值對的形式表示 (鍵為頭部字段名)。請求頭部包含了一些該連接和報文的信息,如表示長連接狀態(tài)
6、的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請求報文的請求體進(jìn)行解析,從中獲取報文參數(shù)。 登陸和注冊通過P
7、OST報文發(fā)送請求,用戶名和用戶密碼存放在請求體中。在解析請求體過程中,需要對通過解 析得到的用戶名、用戶密碼進(jìn)行處理:當(dāng)報文請求為登錄時,向存儲單元查詢用戶名、用戶密碼進(jìn)行校驗(yàn);當(dāng)報文 請求為注冊時,向存儲單元查詢用戶名、密碼合法性,如果合法那么進(jìn)行存儲。 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)碼由三個十進(jìn)制數(shù)字組成,狀態(tài)碼的類型由第一個數(shù)字定義。狀態(tài)碼和狀態(tài)碼描述表示HTTP響應(yīng)報文的報 文
8、類型。HTTP響應(yīng)報文生成模塊流程如圖3. 9所示。 圖3. 8 HTTP解析模塊狀態(tài)轉(zhuǎn)移 圖3. 9 HTTP響應(yīng)報文生成模塊流程“客戶端請求資源合法”是指客戶端請求的資源存在并且是一些 指定的文件,而不是某個文件夾。3.4日志系統(tǒng) 日志是記錄服務(wù)器運(yùn)行狀態(tài)的文件,對于服務(wù)器開發(fā)人員和服務(wù)器運(yùn)維人員而言日志是一種能夠直觀地觀察服 務(wù)器狀態(tài)的重要文件。通過日志,服務(wù)器開發(fā)人員可以查看服務(wù)器的日常運(yùn)行狀態(tài),對服務(wù)器架構(gòu)和功能作出調(diào)整 和拓展;服務(wù)器運(yùn)維人員可以根據(jù)日志中的錯誤信息對服務(wù)器進(jìn)行錯誤排查。日志系統(tǒng)的實(shí)現(xiàn)有兩種方式:同步模 式和異步模式。 同步模式的寫入操
9、作與事件處理器串行執(zhí)行。寫日志文件會涉及到I/O操作,同步模式在I/O操作時會阻塞整個 處理流程。當(dāng)單條日志記錄較大時,事件處理器會被阻塞較長時間,整個服務(wù)器的并發(fā)度將有所下降。如果服務(wù)器 需要處理大量連接請求時,寫日志操作可能會成為系統(tǒng)瓶頸。 異步模式需要阻塞隊列作為事件處理器和寫日志模塊的傳輸介質(zhì)。事件處理器把日志記錄存入阻塞隊列,寫日 志模塊異步地從阻塞隊列中獲取日志記錄并寫入日志文件。異步模式把寫日志操作與業(yè)務(wù)處理流程進(jìn)行別離,防止 業(yè)務(wù)處理流程被阻塞,提高了服務(wù)器業(yè)務(wù)處理的并發(fā)度。 日志記錄根據(jù)記錄信息被劃分為多個等級。例如,日志記錄被分為調(diào)試信息、運(yùn)行信息、錯誤信息等幾個級別
10、,服務(wù)器正常運(yùn)行時僅記錄運(yùn)行信息和錯誤信息;服務(wù)器調(diào)試時記錄包括調(diào)試信息的所有信息。服務(wù)器可以根據(jù) 不 同的運(yùn)行狀態(tài)選擇不同的日志等級,過濾無需記錄的日志信息,從而提高日志文件的可讀性。日志系統(tǒng)的寫入記錄 流程如圖3. 10所示。 根據(jù)日志等 級、日志參數(shù) 創(chuàng)立相應(yīng)的E 志記錄 ? 1 < ? JU) 第N個日志文件 結(jié)束 同步璜式 日阻先 入業(yè)不 11 志塞處板 異步建式 寫日志模塊異步地從 阻塞隊列中茨取日志 記錄,并把日志記錄 寫入日志文件 圖3.10寫入日志記錄流程 4工程實(shí)現(xiàn)4.1服務(wù)器整體功能 本工程是在Linux環(huán)境下使用C++實(shí)現(xiàn)的Web服務(wù)器
11、。目標(biāo)服務(wù)器基于Reactor模式,結(jié)合了 epoll和非阻塞 Socket,利用線程池和數(shù)據(jù)庫連接池實(shí)現(xiàn)了LT模式、ET模式下對GET請求報文、POST請求報文的解析和響應(yīng),使用定 時器實(shí)現(xiàn)了對長連接的管控。此外,本工程還實(shí)現(xiàn)了同步和異步兩種模式下的日志系統(tǒng),用于記錄系統(tǒng)運(yùn)行狀態(tài)。 4.2阻塞隊列 STL向C++開發(fā)者提供了deque、queue等模板類隊列,這些模板類使用方便、接口清晰,但不具備線程平安性。 根據(jù)參考文獻(xiàn)[20]的第十二條: library implementation that allows multiple readers on one container and
12、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. ”可知如果要實(shí)現(xiàn)STL的線程平安性,程序員必須 自己去完成相關(guān)平安措施。 本工程通過互斥鎖、條件變量對deque重新封裝,利用“生產(chǎn)者-消費(fèi)者”模式實(shí)現(xiàn)了具有線程平安性的阻塞隊 列。 力口鎖(lock mutex) 被條件兗量 consumer
13、 阻塞 元素出隊 解鎖(unlock mutex) 圖4.1阻塞隊列的入隊和出隊4.3日志系統(tǒng) 4.3.1 單例模式為了防止日志文件混亂,日志系統(tǒng)在服務(wù)器運(yùn)行過程中應(yīng)該只存在一個實(shí)例,即單例模式實(shí)現(xiàn)日志 系統(tǒng)。單例模式是最常用的設(shè)計模式之一,通過私有化構(gòu)造函數(shù)來保證一個類無法類外實(shí)例化,并提供相應(yīng)的實(shí)例訪問接口給 其它程序模塊訪問,該接口只能獲取該類的唯一實(shí)例。在C++11標(biāo)準(zhǔn)[21]中,對局部靜態(tài)變量的初始化作出以下要 求: “Otherwise such a variable is initialized the first time control passes through
14、 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 c
15、oncurrently 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)變量的初始化 是具備線程平安性的。單例類可以通過在實(shí)例訪問接口中定義該類
16、的局部靜態(tài)對象來定義唯一實(shí)例。這種方法是單例模式中的懶漢模式,因?yàn)镃++中的局部靜態(tài)對象只有在第一次訪 問時才會被初始化。 實(shí)例接口代碼如下所示。 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ì)運(yùn)行過程,在服務(wù)器實(shí)際運(yùn)行時不使用。
17、 INFO:記錄服務(wù)器當(dāng)前狀態(tài),如當(dāng)前的執(zhí)行流程、接收信息、連接數(shù)量等。該級別的信息用于記錄服務(wù)器實(shí)際 運(yùn)行時的狀態(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”來進(jìn)行級別檢查,不同的 接口調(diào)用“
18、LOG_BASE”時傳入不同的記錄等級參數(shù)。 “LOG—BASE”的偽代碼如圖4. 2所示。 4.3.3 分日期、分記錄數(shù)量創(chuàng)立日志文件 日志記錄寫入日志文件時日志系統(tǒng)對當(dāng)前翻開的日志文件的日期、記錄數(shù)量進(jìn)行檢查,日志系統(tǒng)根據(jù)日期、記 錄數(shù)量對日志文件進(jìn)行分類。如果當(dāng)前日期與日志系統(tǒng)翻開日志文件的日期不一致,那么日志系統(tǒng)新建日志文件,日 志名稱為當(dāng)前日期;如果當(dāng)前翻開的日志文件的記錄數(shù)到達(dá)單個日志文件的最大記錄數(shù),那么日志系統(tǒng)將創(chuàng)立一個日志名稱帶有當(dāng)前日期和計數(shù)后綴的新日志文件[22] o 檢查日志文件日期、記錄數(shù)量的偽代碼如圖4. 3所示。 4.3.4 同步模式、異步模式日志系統(tǒng)的
19、模式在服務(wù)器初始化中決定:阻塞隊列長度等于零為同步模式,阻塞隊列長度大于零為異步模式。日志 系統(tǒng)根據(jù)不同的記錄級別、日志信息生成相應(yīng)的日志記錄,并寫入日志文件。同步模式中記錄寫入日志文 件的I/O操作與處理業(yè)務(wù)的工作線程串行執(zhí)行,會阻塞工作線程;異步模式創(chuàng)立一個日志寫入線程,工作線程把日志 記錄插入阻塞隊列,由日志寫入線程異步地從阻塞隊列獲取日志記錄并執(zhí)行I/O操作。、日志寫入的偽代碼如圖4. 4 所示。 Algorithm 1: LOG_BASEInput: level, loginfo if level》Instance.level thenWirteLog(level, login
20、fo); flush;end 圖4.2 L0G_BASEAlgorithm 2: CheckLog if log. date * today or (count % maxCount) = 0 thenif log. date 盧 today then create new log, name is today;log. date = today; count = 1;else create new log, name is today,(count / maxCount);end end圖4. 3檢查日志文件 Algorithm 3: WriteLogInput: level
21、, loginfo CheckLog;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)系,
22、即半同步/半異步模式。工作線程的執(zhí)行流程偽代碼如圖4. 5所示。 Algorithm 4: Workmutex lock; while threadpool is not closed doif BlockQueue is not empty then get task from BlockQueue;mutex unlock: processing the task;mutex lock; elsethread is blocked by condition variable; endend mutex unlock;圖4.5工作線程工作線程初始化后對線程池中的mutex進(jìn)行加
23、鎖,然后訪問臨界區(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ù)庫連接池的實(shí)現(xiàn)方法
24、比線程池更簡單,本質(zhì)是使用一個阻塞隊列存儲空閑的數(shù)據(jù)庫連接。工 作線程向數(shù)據(jù)庫連接池申請和歸還數(shù)據(jù)庫連接實(shí)際是對阻塞隊列的出隊和入隊操作。但阻塞隊列的入隊操作如果交給程序員處理 可能會存在遺漏入隊的情況,導(dǎo)致空閑的數(shù)據(jù)庫連接沒有重新進(jìn)池,從而浪費(fèi)空閑資源,甚至最后會導(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,資源獲取就是初始化)機(jī)制,程序通過定義一個封裝了從數(shù)據(jù)
25、庫連 接池獲取和歸還連接的RAU類來管理連接的分配和回收[23]。RAH類在構(gòu)造函數(shù)中獲取數(shù)據(jù)庫連接,在析構(gòu)函數(shù)中 歸還數(shù)據(jù)庫連接。通過RAU機(jī)制,工作線程只能通過定義一個RAH實(shí)例獲取數(shù)據(jù)庫連接。同時工作線程無需主動歸 還數(shù)據(jù)庫連接,因?yàn)榫€程對數(shù)據(jù)庫連接的所有權(quán)周期就是RAH實(shí)例的生命周期,當(dāng)線程完成數(shù)據(jù)庫訪問后退出相應(yīng) 作用域,RAH實(shí)例被系統(tǒng)自動銷毀,RAH實(shí)例的析構(gòu)函數(shù)釋放數(shù)據(jù)庫連接。數(shù)據(jù)庫連接RAH類的構(gòu)造函數(shù)和析構(gòu)函 數(shù)的偽代碼如圖4. 6所示。 Algorithm 5: Construct SqlPoolRAIIOutput: sqlConnection get sqlCon
26、nection from sqlConnectionQueue;mySqlConnection = sqlConnection; Algorithm 6: Destruct SqlPoolRAIIif mySqlConnection is not empty then sqlConnectionQueue.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請求行主要解析請求報文的請求方
27、法、URI、HTTP協(xié)議版本,請求頭部主要解析關(guān)于連接和報文的各種信息,請求體主要解析某些報文的參數(shù) (POST報文)。解析請求體前逐行解析行、請求頭部。本工程HTTP請求報文解析模塊從HTTP請求中解析得到的信息 ,包含:請求方法,URL協(xié)議版本,連接類型 (Connection,表示短連接或長連接),長連接信息(keep-alive)請求體編碼方式,請求體長度,表單參數(shù)(用 戶名、密碼)。 4. 6. 2解析請求行 請求行由請求方法、URI和HTTP協(xié)議版本組成,以空格分隔,整行格式為“請求方法URI HTTP/協(xié)議版本”。請 求行可以通過正那么表達(dá)式進(jìn)行匹配。由于請求行的三個元
28、素由空格隔開,并且版本協(xié)議前帶有“HTTP/",所以匹配 正那么表達(dá)式為: 乂廠]*)(廠]*) HTTP/(1]*)$通過正那么表達(dá)式匹配可得到請求報文的請求方法、URI和HTTP協(xié)議版本。URI作為 唯一資源標(biāo)識符,本工程可以通過URI和自定義的“URI-資源路徑”映射表得知請求資源的路徑。 4. 6. 3解析請求頭部 請求頭部包含許多連接信息,以鍵值對的形式表示,每個鍵值對占一行。STL提供了以鍵值對形式存儲的模板 類:map、unordered_mapo其中map底層由紅黑樹實(shí)現(xiàn),unorderedjnap底層由哈希表實(shí)現(xiàn)。由于HTTP請求頭部中的 信息無順序意義,因此本工程使用
29、時間復(fù)雜度更低的unorderecUnap存儲請求頭部信息。 請求頭部中的鍵值對以冒號和空格(“:”)進(jìn)行分割,因此可以使用正那么表達(dá)式對鍵值對進(jìn)行匹配。匹配請 求頭部信息的正那么表達(dá)式: ”[:]*): ?(.*)$如果匹配失敗,說明解析到了空白行,結(jié)束解析請求頭部。解析請求體 請求體的長度和編碼方式在解析請求首部中得知,鍵的名稱分別為"Content-Length"和"Content-Type' o 本工程對編碼方式為uapplication/x-www-form-(JRIencodeclv (大多數(shù)主流瀏覽器提交表單的默認(rèn)編碼方式)的 POST請求進(jìn)行解析。 “applicati
30、on/x-www-form-URIencoded”的數(shù)據(jù)參數(shù)是鍵值對,表現(xiàn)形式為“key=value”,因此可以使用 unorderedjnap存儲鍵值對參數(shù)。多個參數(shù)之間由別離。編碼規(guī)那么為:參數(shù)中的空格使用“ + ”替換,非數(shù)字、 字母的特殊字符使用三個字符“%xy”替換,其中“xy”表示該字符的十六進(jìn)制表示形式。 請求體的整體解析過程:根據(jù)"app 1 i cat i on/x-w wf orm-UR I encoded v編碼方式對請求體進(jìn)行反編碼,別離鍵 值對參數(shù)并存入哈希表中。判斷請求報文是否請求注冊或登錄,如果是那么根據(jù)相應(yīng)的參數(shù)判斷請求是否合法,如參 數(shù)中否含有用戶名、用戶密
31、碼。 本工程的登陸與注冊校驗(yàn)過程由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 pas
32、sword are legal then path = welcome; elsepath = error; endend end圖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é)果得到的資源文件。本工程的
33、HTTP響應(yīng)報文生成 模塊中,因?yàn)槊總€連接的報文信息都可能各不相同,因此響應(yīng)行、響應(yīng)頭部、空白行存儲在各個連接的響應(yīng)報文緩沖區(qū)中。為了加快發(fā)送報文時對資源文件的讀取速率,響應(yīng)體對應(yīng)的資源文件通過 內(nèi)存映射存放到內(nèi)存中。“內(nèi)存映射 文件提供了一種獨(dú)特的內(nèi)存管理特征,它允許應(yīng)用程序與通過指針訪問動態(tài)內(nèi)存相同的方式訪問磁盤上的文件。因 此,可以在進(jìn)程地址空間中將磁盤上的文件局部或者全部映射到特定地址范圍,然后通過指針就可以訪問內(nèi)存映射 文件中的內(nèi)容。一旦該文件被映射,就可以訪問它,就像整個文件已經(jīng)加載內(nèi)存一樣,從而可以不必對文件執(zhí)行I/O 操作,這對大數(shù)據(jù)量文件來說存取效率較高[24]?!? 圖4
34、. 8響應(yīng)報文存儲關(guān)系 4.7. 2生成狀態(tài)碼 根據(jù)圖3. 9可知,能夠成功請求資源的請求報文需要經(jīng)過三次檢查:成功解析請求報文、客戶端請求的資源合 法、客戶端擁有足夠權(quán)限訪問資源。每個階段出錯都會生成相應(yīng)的狀態(tài)碼,只有三次檢查都通過才會生成表示成功 體框架,包括框架中的事件別離器、事件處理器;其中事件處理器是核心模塊,重點(diǎn)分析了其HTTP請求報文解析模 塊和HTTP響應(yīng)報文生成模塊;還分析了日志系統(tǒng)的同步模式和異步模式。在完成需求分析后,對服務(wù)器的各個模塊 進(jìn)行設(shè)計和實(shí)現(xiàn),包括阻塞隊列、日志系統(tǒng)、線程池、數(shù)據(jù)庫連接池、HTTP請求報文解析、HTTP響應(yīng)報文生成以及 管控HTTP長連接的定
35、時器。各模塊通過面向?qū)ο蟮乃枷雽?shí)現(xiàn)了相應(yīng)的功能接口,降低了模塊間的耦合度。最后,本 文對服務(wù)器進(jìn)行了壓力測試和穩(wěn)定性測試,并對應(yīng)用層面的注冊功能、登錄功能和大文件傳輸功能進(jìn)行了測試。本 文涉及了Socket的監(jiān)聽與連接、網(wǎng)絡(luò)I/O管理、線程池設(shè)計和HTTP協(xié)議分析,對解決Web服務(wù)器中遇到的問題具有很 好的工程參考價值。 關(guān)鍵詞:Linux, C++,高并發(fā),epoll, Reactor Abstract With the rapid development of information technology, the Internet has become an indispensabl
36、e 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
37、 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 o
38、f 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 mul
39、tiplexing 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,
40、 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 frame
41、work; 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
42、 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 t
43、hrough 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 monit
44、oring 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ù)介紹 2 2. 1 Socket,22.2 I/O多路復(fù)用技術(shù)EPOLL.4 1. 2
45、.1 五種 I/O 模型 ..42. 2 EPOLL4 2. 3 Reactor事件處理模式...7的狀態(tài)碼“200”。能否成功解析請求報文是由請求報文解析模塊進(jìn)行判斷的。如果HTTP請求報文格式出錯(如請 求行格式出 錯),那么狀態(tài)碼設(shè)置為“400”。該階段檢查的“出錯”僅表示請求報文格式出錯,而登錄或注冊請求中的用戶信息 出錯不屬于該階段的檢查范圍,僅屬于應(yīng)用層面上的出錯。所以用戶信息錯誤的登錄或注冊請求也是一次成功的請 求,服務(wù)器發(fā)送的響應(yīng)報文依然是狀態(tài)碼為“200”的成功響應(yīng)報文,只是頁面資源是表示用戶信息出錯的頁面,而 不是成功頁面。 客戶端請求資源合法表示客戶端請求的資源應(yīng)
46、該存在并且是有效資源,不能是某個文件夾。客戶端擁有足夠權(quán)限訪 問資源表示客戶端請求的資源在服務(wù)器的權(quán)限是中是“其它用戶可讀"。Linux中的文件權(quán)限分為“可讀”、“可寫”、“可執(zhí)行”,本工程主要檢查客戶端是否有權(quán)限讀資源,在開發(fā)中使用SJR0TH (表 示其他用戶可讀的權(quán)限值,與文件的權(quán)限值進(jìn)行與運(yùn)算可知文件能否被其他用戶讀)對資源文件的權(quán)限進(jìn)行檢查。 生成狀態(tài)碼的偽代碼如圖4. 9所示。 Algorithm 8: CreateStatusCode Output: Status Code if Parse Post = FALSE thenStatus Code = 400; endels
47、e if resource does not exist or resource is a folder then Status Code = 404;end else if resource is not readable thenStatus Code = 403; endelse Status 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ù)資源的文件類型向
48、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ū)進(jìn)
49、行修改時會執(zhí)行“寫時拷貝”獲得一份私有的文件拷貝,對文件的修改都是對這篇私有內(nèi)存的修改,不寫回原文件 O4. 8定時器 本工程通過定時器對HTTP長連接進(jìn)行管控。服務(wù)器在初始化時定義連接的生存時間,接收到請求報文后為連接 設(shè)置定時器。 定時器使用小頂堆實(shí)現(xiàn),每個節(jié)點(diǎn)存儲某個連接的定時器信息。定時器信息包括Socket的文件描述符、超時時 間點(diǎn)、回調(diào)函數(shù),其中超時時間點(diǎn)為定時器設(shè)置時間加上連接的生存時間,回調(diào)函數(shù)為關(guān)閉連接函數(shù)。各個信息的 作用是:主線程設(shè)置或重置連接的定時器時根據(jù)Socket的文件描述符找到指定的定時器節(jié)點(diǎn);主線程根據(jù)定時器的 超時時間點(diǎn)判斷該連接是否超時,如果超時那么調(diào)
50、用回調(diào)函數(shù)關(guān)閉連接。 小頂堆的底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,根據(jù)節(jié)點(diǎn)的超時時間點(diǎn)排序建堆。主線程在重置定時器時需要根據(jù)文件描述符 找到定時器節(jié)點(diǎn),因此還需要定義一個“文件描述符-節(jié)點(diǎn)下標(biāo)”映射表,可以使用unorderedjnap實(shí)現(xiàn)。 新增連接時判斷堆中是否存在含有該Socket文件描述符的節(jié)點(diǎn)。如果不存在,主線程向堆尾中插入新的定時器 節(jié)點(diǎn),并根據(jù)超時時間點(diǎn)對節(jié)點(diǎn)向上調(diào)整;如果存在,說明之前使用該文件描述符的連接雖然已經(jīng)被關(guān)閉但目前事 件還到達(dá)該連接的超時時間點(diǎn),主線程重置該節(jié)點(diǎn)的超時時間點(diǎn),并對節(jié)點(diǎn)向下調(diào)整。 某個連接有新的事件到達(dá),主線程重置該連接定時器的超時時間點(diǎn):通過文件描述符和“文件
51、描述符-節(jié)點(diǎn)下 標(biāo)”的映射表找到定時器節(jié)點(diǎn)的下標(biāo),修改定時器節(jié)點(diǎn)的超時時間點(diǎn)并對節(jié)點(diǎn)向下調(diào)整。 調(diào)整過程中定時器需要維護(hù)“文件描述符-節(jié)點(diǎn)下標(biāo)”的映射表。向上調(diào)整如圖4. 10所示,向下調(diào)整如圖4. 11所/Js o 圖4.10定時器節(jié)點(diǎn)向上調(diào)整 國弱陸禁漁IIR延您腐 圖4.11定時器節(jié)點(diǎn)向下調(diào)整清除超時節(jié)點(diǎn)只需要判斷根節(jié)點(diǎn)是否超時,如果超時那么刪除根節(jié)點(diǎn),調(diào)整堆:交換根 節(jié)點(diǎn)與最后一個節(jié)點(diǎn),刪 除最后節(jié)點(diǎn)并對新的根節(jié)點(diǎn)向下調(diào)整。主線程不斷清除直到根節(jié)點(diǎn)不超時或堆為空。對于連接已經(jīng)關(guān)閉的節(jié)點(diǎn)無需 管理。因?yàn)槿绻行碌倪B接使用該節(jié)點(diǎn)的文件描述符,該節(jié)點(diǎn)會析構(gòu)舊連接的信息,存儲新連
52、接的信息,并調(diào)整節(jié) 點(diǎn)位置;如果時間到達(dá)了舊連接的超時時間點(diǎn),該節(jié)點(diǎn)會與其它超時節(jié)點(diǎn)一起被清除。 為了能夠有效地對超時連接進(jìn)行關(guān)閉,當(dāng)堆不為空時主線程應(yīng)有限地等待到達(dá)事件,并且等待時間為定時器根 節(jié)點(diǎn)的超時時間點(diǎn)減去當(dāng)前時間。在此期間內(nèi)如果沒有事件到達(dá)那么根節(jié)點(diǎn)對應(yīng)的連接一定超時,需要關(guān)閉。 |清輻時節(jié)點(diǎn)|—"葉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ù)庫訪問端口)、
53、工作線程數(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ù)器運(yùn)行主線程流程如圖4. 13所示。 error圖4. 13主線程流程工作線程 流程如圖4.
54、14所示。 圖4. 14工作線程流程 5服務(wù)器測試測試環(huán)境 服務(wù)器系統(tǒng): ubuntul8. 04服務(wù)器處理器內(nèi)核總數(shù):4服務(wù)器內(nèi)存:8GB 5.1 測試工具本工程使用WebBench對服務(wù)器進(jìn)行壓力測試和穩(wěn) 定測試[25]。 WebBench是VeriTest公司開發(fā)的一款測試工具,其原理是通過父進(jìn)程fork多個子進(jìn)程,由子進(jìn)程對目標(biāo)URI發(fā)起 實(shí)際請求并記錄請求結(jié)果。子進(jìn)程把結(jié)果返回給父進(jìn)程,由父進(jìn)程整理和統(tǒng)計子進(jìn)程記錄的信息,反應(yīng)于用戶。用 戶能夠通過WebBench向目標(biāo)Web服務(wù)器發(fā)起一定數(shù)量的并發(fā)請求,并發(fā)連接數(shù)和持續(xù)時間可由用戶決定,但并發(fā)數(shù)量 不能超過三萬。 5
55、.2 壓力測試和穩(wěn)定測試的服務(wù)器參數(shù)關(guān)閉方式:優(yōu) 雅退出。 線程數(shù)量:6O日志系統(tǒng):關(guān) 閉。 epoll模式:偵聽Socket設(shè)為LT模式,連接Socket分LT模式和ET模式進(jìn)行測試。 5.3 壓力測試 單次測試時長為5秒,并發(fā)連接數(shù)從1000開始,以2000為步長進(jìn)行增長,直到服務(wù)器支持上萬并發(fā)。LT模式、ET 模式各進(jìn)行十次測試,測試結(jié)果見附錄。結(jié)果平均值如表5.1、5.2所示。 表5. 1 LT模式壓力測試 并發(fā)連接數(shù) 數(shù)據(jù)傳輸速率bytes/s 成功次數(shù) 每秒成功次數(shù) 1000 5464886. 4 202652.2 6754. 6 3000 44812
56、09.4 214422.6 7146.8 5000 4441323.4 221291.7 7375. 9 7000 4556732 229431. 5 7647. 3 9000 4461308.4 227311 7586. 6 11000 4292933.3 222241.8 7407. 7 表5. 2 ET模式壓力測試 并發(fā)連接數(shù) 數(shù)據(jù)傳輸速率bytes/s 成功次數(shù) 每秒成功次數(shù) 1000 5368129.2 199063. 8 6635 3000 4447417. 8 213078.5 7104. 7 5000 43648
57、42. 2 215823.2 7193. 7 7000 4424853. 2 223747. 1 7457. 8 9000 4196370. 8 215830.3 7193.9 11000 4193782. 7 218356.8 7278. 1 從表中可知LT模式和ET模式均能支持上萬并發(fā),并且每秒處理的連接請求數(shù)(qps)約為7000。 5.4 穩(wěn)定測試測試時長為10分鐘,并發(fā)連接數(shù)11000。對ET模式、LT模式各進(jìn)行3次測試,測試結(jié) 果如下。 11000 clients, running 600 sec. Speed=452658 pages/min,
58、 -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. Reque
59、sts: 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, 2832
60、2 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ù)是因?yàn)閿?shù)據(jù)過大造成了整型溢出。 5.5 注冊、登錄功能測試用戶表初始為空。 rrysql> select * fr
61、om user; Empty set (0.00 sec) 圖5.7用戶表初始內(nèi)容注冊 用戶。 C O A Not secure 192.168.3.1... ☆* y : 首頁 圖5.8首頁 圖5. 9注冊 圖5.10注冊成功,進(jìn)入功能界面 mysql> select * from user;+++ | username|password|+++ | 123456|123456|+++ 1 row inset(0.00 sec)圖5.11數(shù)據(jù)庫存入用戶名、用戶密碼 登錄需要對用 戶名、用戶密碼進(jìn)行校驗(yàn)。 <--> C O A Not secure 192
62、.16...所 ☆★ y登錄 用戶名 用戶密碼確定 用戶名、用戶密碼錯誤=== 圖5. 12用戶信息錯誤,返回錯誤信息 注冊對用戶名 進(jìn)行校驗(yàn),防止重新注冊。 圖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++服
63、務(wù)器開發(fā)的相關(guān)技術(shù),分析了服務(wù)器的整體需求,并設(shè)計了一個結(jié)合 Reactor模式、epoll、非阻塞I/O以及線程池的高并發(fā)Web服務(wù)器。其中主要對服務(wù)器的高并發(fā)相關(guān)技術(shù)進(jìn)行了詳細(xì) 探討:epoll模式選擇、阻塞隊列實(shí)現(xiàn)原理、主線程與線程池的半同步/半異步模型、日志系統(tǒng)的同步/異步模式。 通過實(shí)驗(yàn)測試,可以得知本文設(shè)計的服務(wù)器在主流PC中運(yùn)行可以支持上萬并發(fā),并且可以保證服務(wù)器穩(wěn)定運(yùn)行。 同時,本文設(shè)計的服務(wù)器還支持用戶登錄、注冊功能。工作線程通過數(shù)據(jù)庫連接池和RAH機(jī)制完成多線程模式 下對數(shù)據(jù)庫的有序訪問,并對客戶端的用戶名、用戶密碼進(jìn)行校驗(yàn)。對于文件傳輸,服務(wù)器通過內(nèi)存映射把資源文 件拷
64、貝進(jìn)內(nèi)存,減少了程序?qū)ξ募x取的I/O操作,加快了文件傳輸速率。對于長連接,服務(wù)器通過小頂堆實(shí)現(xiàn)了定 時器,完成了對超時連接的主動釋放。 本文設(shè)計的服務(wù)器雖然保證了高并發(fā)場景下的穩(wěn)定運(yùn)行,但依然存在一些應(yīng)用場景問題。本文設(shè)計的服務(wù)器處 理的請求都是無狀態(tài)的,因此登錄功能會失去實(shí)際意義。有狀態(tài)場景需要服務(wù)器生成session并向客戶端返回 cookie, cookie的生成和session的保存在高并發(fā)場景下會變成一個新的難題。我將在后續(xù)工作中繼續(xù)改進(jìn),為服務(wù) 器的可用性提供更多支持。 參考文獻(xiàn) [1]中國互聯(lián)網(wǎng)絡(luò)信息中心.第46次中國互聯(lián)網(wǎng)絡(luò)開展?fàn)顩r統(tǒng)計報告[R].北京:中共中央網(wǎng)絡(luò)平安
65、和信息化委員會 辦公室,中華人民共和國國家互聯(lián)網(wǎng)信息辦公室,2020. [2]周炎濤,李立明.TCP/IP協(xié)議下網(wǎng)絡(luò)編程技術(shù)及其實(shí)現(xiàn)[J].航空計算技術(shù),2002(03):126-128+132. [3]W. RichardStevens, BillFenner, AndrewM. Rudoff. UNIX網(wǎng)絡(luò)編程,第 1 卷,套接口API [M].清華大學(xué)出版 社,2006. [4]W. RICHARDSTEVENS. TCP/IP詳解.卷1,協(xié)議機(jī)械工業(yè)出版社,2000. [5]MichaelKerrisk,凱利斯克,孫劍,等.Linux/UNIX系統(tǒng)編程手冊[M].人民郵電出版社
66、,2014. [6]胥 光輝,徐永森.同步阻塞線程的喚醒問題研究[J].計算機(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. [8]Linux下基于EPOLL機(jī)制的海量網(wǎng)絡(luò)信息處理模型[J].強(qiáng)激光與粒子束,2013, 25(Ozl):46-50. [9]游 雙.Linux高性能服務(wù)器編程[加.機(jī)械工業(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模式的研究與實(shí)現(xiàn)[J].網(wǎng)絡(luò)新媒體技術(shù)
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 第七章-透射電子顯微鏡
- 群落的結(jié)構(gòu)(課件)
- 焊接基礎(chǔ)知識
- 水文地質(zhì)學(xué)課件
- 某公司員工工傷安全管理規(guī)定
- 消防培訓(xùn)課件:安全檢修(要點(diǎn))
- 某公司安全生產(chǎn)考核與獎懲辦法范文
- 安全作業(yè)活動安全排查表
- 某公司危險源安全辨識、分類和風(fēng)險評價、分級辦法
- 某公司消防安全常識培訓(xùn)資料
- 安全培訓(xùn)資料:危險化學(xué)品的類別
- 中小學(xué)寒假學(xué)習(xí)計劃快樂度寒假充實(shí)促成長
- 紅色插畫風(fēng)輸血相關(guān)知識培訓(xùn)臨床輸血流程常見輸血不良反應(yīng)
- 14.應(yīng)急救援隊伍訓(xùn)練記錄
- 某公司各部門及人員安全生產(chǎn)責(zé)任制