<menu id="ycqsw"></menu><nav id="ycqsw"><code id="ycqsw"></code></nav>
<dd id="ycqsw"><menu id="ycqsw"></menu></dd>
  • <nav id="ycqsw"></nav>
    <menu id="ycqsw"><strong id="ycqsw"></strong></menu>
    <xmp id="ycqsw"><nav id="ycqsw"></nav>
  • 服務器的作用是什么,個人服務器用途介紹


    有一天,一位女士散步時經過一個工地,看見有三個工人在干活。她問第一個人,“你在做什么?”第一個人有點不高興,吼道“難道你看不出來我在砌磚嗎?”女士對這個答案并不滿意,接著問第二個人他在做什么。第二個人回答道,“我正在建造一堵磚墻?!比缓?,他轉向第一個人,說道:“嘿,你砌的磚已經超過墻高了。你得把最后一塊磚拿下來?!迸繉@個答案還是不滿意,她接著問第三個人他在做什么。第三個人抬頭看著天空,對她說:“我在建造這個世界上有史以來最大的教堂”。就在他望著天空出神的時候,另外兩個人已經開始爭吵多出的那塊磚。他慢慢轉向前兩個人,說道:“兄弟們,別管那塊磚了。這是一堵內墻,之后還會被刷上石灰的,沒人會注意到這塊磚。接著砌下層吧?!?/p>

    這個故事的寓意在于,當你掌握了整個系統的設計,明白不同的組件是以何種方式組合在一起的(磚塊,墻,教堂)時候,你就能夠更快地發現并解決問題(多出的磚塊)。

    但是,這個故事與從頭開發一個網絡服務器有什么關系呢?

    在我看來,要成為一名更優秀的程序員,你必須更好地理解自己日常使用的軟件系統,而這就包括了編程語言、編譯器、解釋器、數據庫與操作系統、網絡服務器和網絡開發框架。而要想更好、更深刻地理解這些系統,你必須從頭重新開發這些系統,一步一個腳印地重來一遍。

    孔子曰:不聞不若聞之,聞之不若見之,見之不若知之,知之不若行之。

    不聞不若聞之

    Python 高手之路:從零開始打造一個Web服務器

    聞之不若見之

    Python 高手之路:從零開始打造一個Web服務器

    見之不若知之,知之不若行之。

    Python 高手之路:從零開始打造一個Web服務器

    譯者注:上面原作者所引用的那段話在國外的翻譯是:I hear and I forget, I see and I remember, I do and I understand。外國人普遍認為出自孔子,但在查找這句英文的出處時,查到有篇博文稱這句話的中文實際出自荀子的《儒效篇》,經查確實如此。

    我希望你讀到這里的時候,已經認可了通過重新開發不同軟件系統來學習其原理這種方式。

    《自己動手開發網絡服務器》會分為三個部分,將介紹如何從頭開發一個簡易網絡服務器。我們這就開始吧。

    首先,到底什么是網絡服務器?

    Python 高手之路:從零開始打造一個Web服務器

    簡而言之,它是在物理服務器上搭建的一個網絡連接服務器(networking server),永久地等待客戶端發送請求。當服務器收到請求之后,它會生成響應并將其返回至客戶端。客戶端與服務器之間的通信,是以HTTP協議進行的。客戶端可以是瀏覽器,也可以是任何支持HTTP協議的軟件。

    那么,網絡服務器的簡單實現形式會是怎樣的呢?下面是我對此的理解。示例代碼使用Python語言實現,不過即使你不懂Python語言,你應該也可以從代碼和下面的解釋中理解相關的概念:

    :::pythonimport 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 ...' % PORTwhile True:client_connection, client_address = listen_socket.acceptrequest = 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倉庫下載,然后通過命令行運行該文件:

    $ python webserver1.pyServing HTTP on port 8888 …

    接下來,在瀏覽器的地址欄輸入這個鏈接:http://localhost:8888/hello,然后按下回車鍵,你就會看見神奇的一幕。在瀏覽器中,應該會出現“Hello, World!”這句話:

    Python 高手之路:從零開始打造一個Web服務器

    是不是很神奇?接下來,我們來分析背后的實現原理。

    首先,我們來看你所輸入的網絡地址。它的名字叫URL(Uniform Resource Locator,統一資源定位符),其基本結構如下:

    Python 高手之路:從零開始打造一個Web服務器

    通過URL,你告訴了瀏覽器它所需要發現并連接的網絡服務器地址,以及獲取服務器上的頁面路徑。不過在瀏覽器發送HTTP請求之前,它首先要與目標網絡服務器建立TCP連接。然后,瀏覽器再通過TCP連接發送HTTP請求至服務器,并等待服務器返回HTTP響應。當瀏覽器收到響應的時候,就會在頁面上顯示響應的內容,而在上面的例子中,瀏覽器顯示的就是“Hello, World!”這句話。

    那么,在客戶端發送請求、服務器返回響應之前,二者究竟是如何建立起TCP連接的呢?要建立起TCP連接,服務器和客戶端都使用了所謂的套接字(socket)。接下來,我們不直接使用瀏覽器,而是在命令行使用 telnet手動模擬瀏覽器。

    在運行網絡服務器的同一臺電腦上,通過命令行開啟一次 telnet會話,將需要連接的主機設置為localhost,主機的連接端口設置為8888,然后按回車鍵:

    $ telnet localhost 8888Trying 127.0.0.1 …Connected to localhost.

    完成這些操作之后,你其實已經與本地運行的網絡服務器建立了TCP連接,隨時可以發送和接收HTTP信息。在下面這張圖片里,展示的是服務器接受新TCP連接所需要完成的標準流程。

    Python 高手之路:從零開始打造一個Web服務器

    在上面那個 telnet會話中,我們輸入GET/hello HTTP/1.1,然后按下回車:

    $ telnet localhost 8888Trying 127.0.0.1 …Connected to localhost.GET /hello HTTP/1.1
    HTTP/1.1 200 OKHello, World!

    你成功地手動模擬了瀏覽器!你手動發送了一條HTTP請求,然后收到了HTTP響應。下面這幅圖展示的是HTTP請求的基本結構:

    Python 高手之路:從零開始打造一個Web服務器

    HTTP請求行包括了HTTP方法(這里使用的是 GET方法,因為我們希望從服務器獲取內容),服務器頁面路徑(/hello)以及HTTP協議的版本。

    為了盡量簡化,我們目前實現的網絡服務器并不會解析上面的請求,你完全可以輸入一些沒有任何意義的代碼,也一樣可以收到”Hello, World!”響應。

    在你輸入請求代碼并按下回車鍵之后,客戶端就將該請求發送至服務器了,服務器則會解析你發送的請求,并返回相應的HTTP響應。

    下面這張圖顯示的是服務器返回至客戶端HTTP響應詳情:

    Python 高手之路:從零開始打造一個Web服務器

    我們來分析一下。響應中包含了狀態行 HTTP/1.1200OK,之后是必須的空行,然后是HTTP響應的正文。

    響應的狀態行 HTTP/1.1200OK中,包含了HTTP版本、HTTP狀態碼以及與狀態碼相對應的原因短語(Reason Phrase)。瀏覽器收到響應之后,會顯示響應的正文,這就是為什么你會在瀏覽器中看到“Hello, World!”這句話。

    這就是網絡服務器基本的工作原理了。簡單回顧一下:網絡服務器首先創建一個偵聽套接字(listening socket),并開啟一個永續循環接收新連接;客戶端啟動一個與服務器的TCP連接,成功建立連接之后,向服務器發送HTTP請求,之后服務器返回HTTP響應。要建立TCP連接,客戶端和服務器都使用了套接字。

    現在,你已經擁有了一個基本可用的簡易網絡服務器,你可以使用瀏覽器或其他HTTP客戶端進行測試。正如上文所展示的,通過 telnet命令并手動輸入HTTP請求,你自己也可以成為一個HTTP客戶端。

    下面給大家布置一道思考題:如何在不對服務器代碼作任何修改的情況下,通過該服務器運行Djando應用、Flask應用和Pyramid應用,同時滿足這些不同網絡框架的要求?

    答案將在《自己動手開發網絡服務器》系列文章的第二部分揭曉。

    版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。

    發表評論

    登錄后才能評論
    国产精品区一区二区免费