【轉(zhuǎn)載】一起寫一個(gè) Web 服務(wù)器(1)

有天一個(gè)女士出門散步狸眼,路過一個(gè)建筑工地泌射,看到三個(gè)男人在干活。她問第一個(gè)男人,“你在干什么呢钧大?”读规,第一個(gè)男人被問得很煩宜咒,咆哮道幌绍,“你沒看到我在碼磚嗎?”趾牧。她對回答不滿意检盼,然后問第二個(gè)男人他在干什么。第二個(gè)男人回答翘单,“我正在砌墻”吨枉,然后轉(zhuǎn)移注意力到第一個(gè)男人,他說哄芜,“嘿貌亭,你碼過頭了,你要把最后一塊磚拿掉认臊∑酝ィ”。她還是對回答不滿意,然后問第三個(gè)男人在干什么剧腻。第三個(gè)男人仰望著天空對她說拘央,“我正在建造世界上最大的教堂∈樵冢”灰伟。當(dāng)他站在那里仰望天空的時(shí)候,另外兩個(gè)男人開始爭論磚位置不對的問題儒旬。第三個(gè)男人轉(zhuǎn)向前兩個(gè)男人說栏账,“嘿,伙計(jì)們栈源,別擔(dān)心那塊磚了挡爵,那是里面的墻,它會(huì)被灰泥堵塞起來凉翻,然后沒人會(huì)看到那塊磚了讨。去另一層干活吧捻激≈坪洌“

故事的寓意是說,當(dāng)你了解整個(gè)系統(tǒng)胞谭,理解不同的部分如何組織到一起的(磚垃杖、墻、教堂)丈屹,你就能找出問題并快速解決之(磚位置不對)调俘。

這跟從零開始搭建你的WEB服務(wù)器有什么關(guān)系呢?

我相信旺垒,要成為優(yōu)秀的開發(fā)者彩库,你必須對你每天都用的底層的軟件系統(tǒng)有進(jìn)一步的理解,包括編程語言先蒋、編譯器和解釋器骇钦、數(shù)據(jù)庫和操作系統(tǒng)、WEB服務(wù)器和WEB框架竞漾。為了更好更深入的理解這些系統(tǒng)眯搭,你可以從零開始一塊磚地,一面墻地业岁,重建它們鳞仙。

子曰:聞之我也野,視之我也饒笔时,行之我也明

image

“我看過的棍好,我還記得。”

image

“我做過的借笙,我都理解了爹梁。”

image

(子曰:聞之我也野提澎,視之我也饒姚垃,行之我也明)

此時(shí)我希望你能夠相信,從重建不同的軟件系統(tǒng)來開始來學(xué)習(xí)它們是如何工作的盼忌,是一個(gè)好主意积糯。

在這個(gè)由3部分組成的系列文章中,我會(huì)向你展示怎樣搭建一個(gè)基本的WEB服務(wù)器谦纱。咱們開始吧看成。

重中之重,什么是WEB服務(wù)器跨嘉?

image

簡而言之川慌,它是一個(gè)位于一個(gè)物理服務(wù)器上的網(wǎng)絡(luò)服務(wù)器(呀,服務(wù)器上的服務(wù)器)祠乃,它等待客戶端發(fā)送請求梦重。當(dāng)它接收到一個(gè)請求,就會(huì)生成一個(gè)響應(yīng)并回發(fā)給客戶端亮瓷∏倥。客戶端和服務(wù)器使用HTTP協(xié)議通信≈鲋В客戶端可以是瀏覽器或者別的使用HTTP協(xié)議的軟件蚓胸。

一個(gè)非常簡單的WEB服務(wù)器實(shí)現(xiàn)長什么樣呢?以下是我寫的一個(gè)除师。例子是用Python語言寫的沛膳,但是即使你不會(huì)Python(它是一個(gè)非常易學(xué)的語言,試試Q淳邸)锹安,你仍然可以通過代碼和下面的解釋理解相關(guān)概念:

import socket
 
HOST, PORT = '', 8888
 
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
print 'Serving HTTP on port %s ...' % PORT
while True:
    client_connection, client_address = listen_socket.accept()
    request = client_connection.recv(1024)
    print request
 
    http_response = """
HTTP/1.1 200 OK
 
Hello, World!
"""
    client_connection.sendall(http_response)
    client_connection.close()

把上面的代碼保存到webserver1.py或者直接從GitHub下載,然后像下面這樣在命令行運(yùn)行它

$ python webserver1.py
Serving HTTP on port 8888 …

現(xiàn)在在你的WEB瀏覽器地址欄里輸入以下URL http://localhost:8888/hello贞岭,敲回車八毯,見證奇跡的時(shí)刻。你會(huì)看到瀏覽器顯示”Hello, World!“瞄桨,像這樣:

image

認(rèn)真做一下吧话速,我會(huì)等你的。

做完了芯侥?很好〔唇唬現(xiàn)在我們討論一下它到底怎么工作的乳讥。

首先我們從你剛才鍵入的WEB地址開始。它叫URL廓俭,這是它的基本結(jié)構(gòu):

image

這個(gè)就表示怎樣告訴瀏覽器要查找和連接的WEB服務(wù)器地址云石,和你要獲取的服務(wù)器上的頁面(路徑)。但是在瀏覽器發(fā)送HTTP請求前研乒,瀏覽器需要先和WEB服務(wù)器建立TCP連接汹忠。然后瀏覽器在TCP連接上發(fā)送HTTP請求,然后等待服務(wù)器回發(fā)HTTP響應(yīng)雹熬。當(dāng)瀏覽器接收到響應(yīng)后宽菜,顯示響應(yīng),在本次例子中竿报,瀏覽器顯示“Hello, World!”铅乡。

我們再詳細(xì)探索一下客戶端和服務(wù)器在發(fā)送HTTP請求和響應(yīng)前如何建立TCP連接的。在建立連接烈菌,它們必須使用所謂的sockets阵幸。用你命令行下的telnet手動(dòng)模擬瀏覽器吧,而不是直接使用瀏覽器芽世。

在運(yùn)行WEB服務(wù)器的同一臺(tái)電腦上挚赊,在命令行啟動(dòng)一個(gè)telnet會(huì)話,指定連接到localhost主機(jī)捂襟,連接端口為8888咬腕,然后按回車:

$ telnet localhost 8888
Trying 127.0.0.1 …
Connected to localhost.

此時(shí)欢峰,你已經(jīng)和運(yùn)行在你本地主機(jī)的服務(wù)器建立了TCP連接葬荷,已經(jīng)準(zhǔn)備好發(fā)送并接收HTTP消息了。下圖中你可以看到一個(gè)服務(wù)器要經(jīng)過的標(biāo)準(zhǔn)步驟纽帖,然后才能接受新的TCP連接宠漩。

image

在同一個(gè)telnet會(huì)話中,輸入 GET /hello HTTP/1.1然后敲回車:

$ telnet localhost 8888
Trying 127.0.0.1 …
Connected to localhost.
GET /hello HTTP/1.1

HTTP/1.1 200 OK
Hello, World!

你完成了手動(dòng)模擬瀏覽器懊直!你發(fā)送了一個(gè)HTTP請求并得到了一個(gè)HTTP響應(yīng)扒吁。這是HTTP請求的基本結(jié)構(gòu):

image

HTTP請求由行組成。行指示了HTTP方法(GET室囊,因?yàn)槲覀冋埱笪覀兊姆?wù)器返回給我們一些東西)雕崩、代表我們想要的服務(wù)器上的“頁面”的路徑 /hello和協(xié)議版本。

為了簡單起見融撞,此時(shí)我們的WEB服務(wù)器完全忽略了上面的請求行盼铁。你也可以輸入任何垃圾字符取代“GET /hello HTTP/1.1”,你仍然會(huì)得到“Hello, World!”響應(yīng)尝偎。

一旦你輸入了請求行饶火,敲了回車鹏控,客戶端就發(fā)送請求給服務(wù)器,服務(wù)器讀取請求行肤寝,打印出來然后返回相應(yīng)的HTTP響應(yīng)当辐。

以下是服務(wù)器回發(fā)給客戶端(這個(gè)例子中是telnet)的HTTP響應(yīng):

image

咱們分析一下它,響應(yīng)包含了狀態(tài)行HTTP/1.1 200 OK鲤看,隨后一個(gè)必須的空行缘揪,和HTTP響應(yīng)body。

響應(yīng)狀態(tài)行TTP/1.1 200 OK包含了HTTP版本义桂,HTTP狀態(tài)碼和HTTP狀態(tài)碼理由短語OK寺晌。瀏覽器得到響應(yīng)時(shí),它就顯示響應(yīng)的body澡刹,所以你就看到了“Hello, World呻征!”

這就是WEB瀏覽器怎么工作的基本模型“战剑總結(jié)來說:WEB服務(wù)器創(chuàng)建一個(gè)監(jiān)聽socket然后開始循環(huán)接受新連接陆赋。客戶端初始化一個(gè)TCP連接嚷闭,在連接成功后攒岛,客戶端發(fā)送HTTP請求到服務(wù)器,服務(wù)器響應(yīng)一個(gè)顯示給用戶的HTTP響應(yīng)胞锰≡志猓客戶端和服務(wù)器都使用socket建立TCP連接。

你現(xiàn)在你擁有了一個(gè)非承衢牛基礎(chǔ)的WEB服務(wù)器顺饮,你可以用瀏覽器或其他的HTTP客戶端測試它。正如你看到的凌那,使用telnet手動(dòng)輸入HTTP請求兼雄,你也就成了一個(gè)人肉 HTTP 客戶端。

對你來說有一個(gè)問題:“怎樣在你的剛完成的WEB服務(wù)器下運(yùn)行 Django 應(yīng)用帽蝶、Flask 應(yīng)用和 Pyramid 應(yīng)用赦肋?在不單獨(dú)修改服務(wù)器來適應(yīng)這些不同的 WEB 框架的情況下±龋”

我會(huì)在本系列的第 2 部分秀給你看的佃乘。請保持關(guān)注哦。

順便說下驹尼,我在寫一本書《一起構(gòu)建WEB服務(wù)器:第一步》趣避,它解釋了從零開始寫一個(gè)基本的WEB服務(wù)器,還更詳細(xì)地講解了我上面提到的話題扶欣。訂閱郵件組來獲取關(guān)于書籍和發(fā)布時(shí)間和最近更新鹅巍。


靈感來自于 Lead with a Story: A Guide to Crafting Business Narratives That Captivate, Convince, and Inspire

本文轉(zhuǎn)載地址:http://python.jobbole.com/81524/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末千扶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子骆捧,更是在濱河造成了極大的恐慌澎羞,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敛苇,死亡現(xiàn)場離奇詭異妆绞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)枫攀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門括饶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人来涨,你說我怎么就攤上這事图焰。” “怎么了蹦掐?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵技羔,是天一觀的道長。 經(jīng)常有香客問我卧抗,道長藤滥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任社裆,我火速辦了婚禮拙绊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泳秀。我一直安慰自己标沪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布晶默。 她就那樣靜靜地躺著谨娜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪磺陡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天漠畜,我揣著相機(jī)與錄音币他,去河邊找鬼。 笑死憔狞,一個(gè)胖子當(dāng)著我的面吹牛蝴悉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瘾敢,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拍冠,長吁一口氣:“原來是場噩夢啊……” “哼尿这!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庆杜,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤射众,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后晃财,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叨橱,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年断盛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了罗洗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钢猛,死狀恐怖伙菜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情命迈,我是刑警寧澤仇让,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站躺翻,受9級特大地震影響丧叽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜公你,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一踊淳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陕靠,春花似錦迂尝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至税肪,卻和暖如春溉躲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背益兄。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工锻梳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人净捅。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓疑枯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蛔六。 傳聞我的和親對象是個(gè)殘疾皇子荆永,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355