基于Python編寫一個簡單的http服務(wù)器
本篇文章的python
版本為:
什么是http
http
是一個應(yīng)用層協(xié)議,準(zhǔn)確的來說是基于TCP/IP
4層網(wǎng)絡(luò)協(xié)議中的傳輸層中的TCP
應(yīng)用層協(xié)議。
額,4層模型大概是這樣的:
在網(wǎng)絡(luò)通信中,用戶的數(shù)據(jù)是以報文來傳輸?shù)模窃趯?shí)際通信中,每一層都會對包進(jìn)行封裝,從而形成段、數(shù)數(shù)據(jù)報、幀,最后是以比特流(二進(jìn)制)進(jìn)行傳輸,到了目標(biāo)主機(jī)后,會對每一層又進(jìn)行拆解,從而得到最后的報文。
http
就在最上層,就是應(yīng)用層那里。
http
到底離我們多近呢? 甚至于你現(xiàn)在看到的文章,使用的就是http
協(xié)議,它還有一個名字,叫做超文本傳輸協(xié)議,為什么叫超文本呢? 因?yàn)樽铋_始的是時候,http
是被用來傳輸Hypertext
文檔的,所以被叫做超文本協(xié)議,當(dāng)然現(xiàn)在可以傳輸其他類型的數(shù)據(jù),如: 視頻、音頻、圖片等,但是它依然被稱之為超文本協(xié)議。
很難理解吧,沒關(guān)系,繼續(xù)往下看。
分析http請求報文和響應(yīng)報文格式
通過上面的簡介,我們知道http
是應(yīng)用層協(xié)議,它在網(wǎng)絡(luò)協(xié)議中,是被稱之為報文的,讓我們來看一下http
的請求報文 和 響應(yīng)報文吧。
http
報文由4部分組成,分別是起始行、首部行、空白行 以及 實(shí)體組成。以\r\n
(也稱之為CRLF
)進(jìn)行分割。
讓我們來看一下實(shí)際的報文呢。
在linux
中,我們可以使用curl -v 網(wǎng)址
來打印詳細(xì)的請求信息,其中就包括了報文。
命令:
curl -v http://juejin.cn
請求信息:
其中輸出的結(jié)果中>
代表我們發(fā)出的報文,而<
代表服務(wù)器發(fā)送給我們的響應(yīng)信息。下面我們將結(jié)合報文來看上面的數(shù)據(jù)信息。
請求報文格式如下:
其中請求行會指定http
的請求方法,如: GET
、POST
、HEAD
等, URL
則是請求的文件路徑,協(xié)議版本需要指定http
的版本,最后是以CRLF
結(jié)束。
首部行可以有多個,以 (字段名: 值) 的方式出現(xiàn),每一個首部行同樣是以CRLF
結(jié)束。
而后是空行??招袆t代表http
報文頭結(jié)束了,接下來該是發(fā)送的報文主體了,接下來,我們將上述請求http://juejin.cn
的例子,填入表格來看下:
上述是我們使用curl
工具請求的http://juejin.cn
請求報文整體形式,我們可以看到,我們使用了GET
方法,獲取服務(wù)器的/
信息,使用的協(xié)議是HTTP/1.1
,而后攜帶了3個首部行,分別是User-Agent
、Host
以及Accept
。
響應(yīng)報文格式如下:
將響應(yīng)報文和請求報文進(jìn)行對比,我們不難發(fā)現(xiàn),除了第一行以外,其他的格式都是一樣的,所以,我們僅介紹響應(yīng)行的信息,在響應(yīng)報行中,第一個是協(xié)議的版本,這個是服務(wù)器的協(xié)議版本,而后便是狀態(tài)碼,用于告知客戶端,服務(wù)器響應(yīng)的信息,最后是短語,短語的作用是告知使用者,這個返回信息大概是什么意思。
好了,我們將上述juejin.cn
響應(yīng)給我們的報文,我們填到表格中呢:
上述是我們使用curl
請求http://juejin.cn/
,服務(wù)器返回的信息,我們逐行來看下,響應(yīng)行,告知了我們http
版本是HTTP/1.1
,狀態(tài)碼是301
,短語是 鏈接被轉(zhuǎn)移了。
上述我們?nèi)魞H通過狀態(tài)碼的話,是很難get
到整個報文的意思的,不過有短語,就可以猜一下了。
首部行,告知了我們服務(wù)器 、時間 、 報文類型 以及 報文長度。還記得我們第一段落介紹過得,http
現(xiàn)在除了發(fā)送超文本以外,還可以發(fā)送圖片、視頻等,就是通過首部行Content-Type
來確定的。
接著是空白行,最后是報文主體,哎,有沒有感覺奇怪呢?為什么請求報文主體是空的呢?這是因?yàn)閳笪闹黧w長度是由首部行Content-Length
來定義的,如上報文展示的是,我們報文主體有262個字符。
手寫一個簡單的http服務(wù)器
上述,我們介紹了,什么是http
以及初略的看了一下 http
的請求報文和響應(yīng)報文,那么,我們?nèi)绾螛?gòu)建一個http
服務(wù)器呢?
我們知道,http
是應(yīng)用層協(xié)議,是基于傳輸層tcp
來實(shí)現(xiàn)的,所以,我們?nèi)粝霕?gòu)建一個http
服務(wù)器,那么應(yīng)該寫一個socket
程序出來吧。
import socket import threading def handle(client , addr): print("from " , addr) data = client.recv(1024) for k,v in enumerate(data.decode().split("\r\n")): print(k ,v) def main(): s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind(("127.0.0.1",8080)) s.listen() while True: client , addr = s.accept() t = threading.Thread(target=handle,args=(client,addr)) t.start() if __name__ == '__main__' main()
上述,我們寫了一個tcp
程序,它將監(jiān)聽本地回環(huán)地址的8080
端口,若此時我們使用curl -v 127.0.0.1:8080
請求一下該接口,我們將會得到請求報文了,如下:
我們得到請求報文后,可以構(gòu)建一個響應(yīng)報文發(fā)送回去,例如: Hello, Destined Person.
,我們就可以這樣來構(gòu)建http
請求報文信息:
import socket import threading def handle(client , addr): print("from " , addr) data = client.recv(1024) #請求報文 for k,v in enumerate(data. decode() .split("\r\n")): print(k ,v) bodyText = "He1lo,Destined Person." #響應(yīng)報文 #響應(yīng)行 client.send(b"HTTP/1.1 200 OK\r\n") #首部行 client. send(b"Server: pdudo_web_sites\r\n") client. send(b"Content-Type: text/html\r\n") client. send(("Content-Length: %s\r\n" % (len(bodyText) + 2)).encode()) client. send(b"\r\n") client. send(("%s\r\n" %(bodyText)).encode()) def main(): try: s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s .bind(("127.0.0.1"8080)) s .listen() while True: client,addr = s.accept() t = threading.Thread(target=handle,args=(client,addr)) t.start() finally: s.close() if __name__ == '__main__': main()
最后我們使用curl
再來測試一下,是可以得到消息的。
總結(jié)
該篇文章,我們僅介紹了什么是http
,http
的請求報文以及響應(yīng)報文,最后我們使用python
,創(chuàng)建了一個tcp
服務(wù)器來發(fā)送響應(yīng)客戶的響應(yīng)報文。總體而言,http
的報文還是非常簡單的。我們只是寫了一個非常簡單的http
服務(wù)器,其實(shí)在python
中,web
是有一個標(biāo)準(zhǔn)的,它稱之為WSGI
,哎,扯遠(yuǎn)了。
到此這篇關(guān)于基于Python編寫一個簡單的http服務(wù)器的文章就介紹到這了,更多相關(guān)Python http服務(wù)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python不到50行代碼完成了多張excel合并的實(shí)現(xiàn)示例
這篇文章主要介紹了python不到50行代碼完成了多張excel合并的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05VTK與Python實(shí)現(xiàn)機(jī)械臂三維模型可視化詳解
這篇文章主要介紹了VTK與Python實(shí)現(xiàn)機(jī)械臂三維模型可視化詳解,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12Python3之外部文件調(diào)用Django程序操作model等文件實(shí)現(xiàn)方式
這篇文章主要介紹了Python3之外部文件調(diào)用Django程序操作model等文件實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04python實(shí)現(xiàn)npy格式文件轉(zhuǎn)換為txt文件操作
這篇文章主要介紹了python實(shí)現(xiàn)npy格式文件轉(zhuǎn)換為txt文件操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Python使用pymssql連接SQL?SEVER數(shù)據(jù)庫全流程
SQL Server是微軟推出的重量級的數(shù)據(jù)庫,目前有多個版本,如2000、2008、2012等,下面這篇文章主要給大家介紹了關(guān)于Python使用pymssql連接SQL?SEVER數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下2023-12-12Python在Windows和在Linux下調(diào)用動態(tài)鏈接庫的教程
這篇文章主要介紹了Python在Windows和在Linux下調(diào)用動態(tài)鏈接庫的教程,在進(jìn)行Python的CS端編程時經(jīng)常需要用到,需要的朋友可以參考下2015-08-08python去除字符串中的空格、特殊字符和指定字符的三種方法
本文主要介紹了python去除字符串中的空格、特殊字符和指定字符的三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02