這篇文章主要寫一下如何實(shí)現(xiàn)一個(gè)簡(jiǎn)單的http服務(wù)器渊季,并且借由這個(gè)問題討論一下別的相關(guān)問題。首先實(shí)現(xiàn)一個(gè)http服務(wù)器是一件很難的事嗎档冬?這個(gè)問題不好回答,如果是一個(gè)demo級(jí)的http服務(wù)器印荔,答案是:很簡(jiǎn)單假抄,可以說是JAVA剛?cè)腴T水平就可以做到的。如果是一個(gè)可供實(shí)際生產(chǎn)的俱饿、性能優(yōu)良撮珠,架構(gòu)優(yōu)雅的服務(wù)器沮脖,答案是:很不容易,對(duì)大部分的人來說可能很難芯急。不過不管是demo還是成熟的生產(chǎn)用的http服務(wù)器勺届,他們核心的部分應(yīng)該都是相似的,下面我們來分析一下服務(wù)器的工作過程:
首先何謂“服務(wù)”娶耍?服務(wù)就是按照客戶的要求來完成客戶的需求免姿。服務(wù)器更具體的表現(xiàn)形式是按照客戶的的請(qǐng)求來執(zhí)行某種操作,返回指定數(shù)據(jù)榕酒,這里的數(shù)據(jù)和請(qǐng)求更具體的表現(xiàn)形式通常是字符串胚膊。也就是說客戶端發(fā)給服務(wù)器一個(gè)包含客戶端需求的字符串,服務(wù)端通過解析客戶端發(fā)來的字符串想鹰,獲取客戶端的需求紊婉,然后完成需求。那么問題來了辑舷,服務(wù)端如何解析客戶端發(fā)來的字符串呢喻犁?他們之間可是素不相識(shí)的,每個(gè)客戶端按何種組織方式來發(fā)送自己的需求對(duì)服務(wù)器來說完全是不可預(yù)期的何缓。于是這就需要一個(gè)統(tǒng)一的規(guī)范來統(tǒng)一客戶端的請(qǐng)求和服務(wù)端的返回肢础,以及一些別的行為規(guī)范,于是http協(xié)議合情合理的出現(xiàn)了「柩辏現(xiàn)在事情就變成客戶端發(fā)給服務(wù)器一個(gè)滿足http協(xié)議的乔妈、包含客戶端需求的字符串蝙云,服務(wù)端根據(jù)http協(xié)議來解析客戶端發(fā)來的字符串獲取客戶端的需求氓皱,然后完成需求,返回符合http協(xié)議的字符串給客戶端勃刨。再然后這里的“發(fā)送”波材,“返回”又具體是什么呢?它們就是客戶端和服務(wù)器之間通過socket連接執(zhí)行的一些IO操作身隐。這樣分析之后我們大概知道整個(gè)的工作流程:客戶端建立一個(gè)連接到服務(wù)端廷区,執(zhí)行IO操作,把滿足http協(xié)議的字符串發(fā)送給服務(wù)器贾铝,服務(wù)器根據(jù)http協(xié)議來解析客戶端發(fā)來的字符串的含義隙轻,然后執(zhí)行對(duì)應(yīng)操作埠帕,最后把作為返回結(jié)果的、滿足http協(xié)議的字符串執(zhí)行IO操作發(fā)送給客戶端玖绿。
通過上面簡(jiǎn)單的分析我們大概知道http服務(wù)器具體干了啥(實(shí)際比較復(fù)雜)以及我們需要哪些基礎(chǔ)前置知識(shí):
- http協(xié)議(編程語(yǔ)言無關(guān),核心):參見RFC2616
- IO操作(編程語(yǔ)言有關(guān)):各大編程語(yǔ)言的IO模塊
- 字符串操作:這就是各大公司考算法題的原因吧(望天==)
后續(xù)當(dāng)然還有:
- 多線程并發(fā)優(yōu)化處理
- 設(shè)計(jì)模式
- ......
下面是我用JAVA實(shí)現(xiàn)一個(gè)HTTP服務(wù)器敛瓷,我這個(gè)服務(wù)器不是簡(jiǎn)單的小demo(demo只需兩個(gè)JAVA 類即可搞定==),當(dāng)然也不是可以生產(chǎn)用的(你可以把它寫成可以生成用的)斑匪,先導(dǎo)知識(shí)為Java NIO編程和Java 多線程編程呐籽,代碼太長(zhǎng)不貼,放在github蚀瘸。代碼地址:Crab
項(xiàng)目截圖:
項(xiàng)目的目的是什么呢狡蝶?最重要的目的是希望可以寫出規(guī)范化的、工程化的代碼以及項(xiàng)目贮勃,特別是與入門者來說常常只寫一些玩具式的demo贪惹,或者盲目的去看一下大型項(xiàng)目的源碼,我覺得這樣對(duì)自己水平的提升幫助有限衙猪,事實(shí)上我認(rèn)為對(duì)一個(gè)人提升最大的是從最開始就接觸某個(gè)項(xiàng)目或領(lǐng)域馍乙,從它萌芽的時(shí)候開始參與,一步步由項(xiàng)目和問題驅(qū)動(dòng)著來學(xué)習(xí)垫释,在遇到問題的時(shí)候可以想辦法來解決它丝格,想不出來可以去別的項(xiàng)目看看別人是如何解決的,這樣既提高了自己的水平棵譬,也對(duì)別的項(xiàng)目有了更深的理解显蝌,知道別人為何這樣做,而不是去記憶別人是怎么做的订咸。這里引出的一個(gè)問題是:當(dāng)我們?cè)陂喿x源碼時(shí)我認(rèn)為至少要帶著這樣幾個(gè)問題:1.這個(gè)東西是干什么的曼尊,解決了什么問題。2脏嚷。這里作者這里為什么要這樣做骆撇,他的目的是什么,他想干什么父叙。3.我現(xiàn)在想要做的東西需要它嗎神郊?需要到什么程度(會(huì)用?會(huì)魔改趾唱?)涌乳?以項(xiàng)目驅(qū)動(dòng)學(xué)習(xí),把從書上甜癞,別人源碼里的技巧立馬用到自己的項(xiàng)目里夕晓,才可以讓知識(shí)真的化為己用。
題外話:當(dāng)我們學(xué)習(xí)時(shí)我們通常實(shí)際上在學(xué)習(xí)什么悠咱?
我的觀點(diǎn)是我們?cè)趯W(xué)習(xí)時(shí)通常實(shí)際上更多的在學(xué)習(xí)各種規(guī)范蒸辆,比如JavaWeb其實(shí)通常就是Java語(yǔ)言規(guī)范+各種框架的使用規(guī)范+網(wǎng)絡(luò)協(xié)議規(guī)范征炼,因?yàn)橛?jì)算機(jī)科學(xué)以及很多工程科學(xué)實(shí)際是一個(gè)人造的體系,支撐這個(gè)體系的就是各種規(guī)范躬贡,修補(bǔ)和發(fā)展這個(gè)體系也是依賴于各種規(guī)范柒室,由于規(guī)范可以人造,因此規(guī)范可以說是學(xué)不完的逗宜,因?yàn)闀?huì)不停的有新的規(guī)范出來雄右,所以說學(xué)無止境。說起學(xué)無止境好像每門科學(xué)都是學(xué)無止境的纺讲,我認(rèn)為科學(xué)大致可以分成兩種擂仍,一直是研究的是基于一種人造的體系,一直是基于自然的體系(當(dāng)然人造的最后也是基于自然的)熬甚。前者的學(xué)無止境是由于人類創(chuàng)造的無止境逢渔,不斷地會(huì)有新的問題和規(guī)范被創(chuàng)造出來,后者的學(xué)無止境更多的是由于大自然的無止境乡括,大到宇宙星辰肃廓,小到原子夸克,浩瀚無邊地大自然的規(guī)范就在那里等待人們?nèi)グl(fā)現(xiàn)诲泌。