2016-09-15 114 views
1

我目前正在創建一個python套接字http服務器,並且正在處理我的GET和POST請求。我的GET實現工作正常,但POST請求的body元素不會顯示出來。 代碼片段:http POST消息正文沒有收到

self.host = '' 
self.port = 8080 

self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
self.listener.bind((self.host, self.port)) 
self.listener.listen(1) 

while True: 

     client_connection, client_address = self.listener.accept() 
     request = client_connection.recv(2048) 
     print request 

此代碼產生的HTTP報頭處理從網頁發佈請求後:

POST /test.txt HTTP/1.1 
Host: localhost:8080 
Content-Type: application/x-www-form-urlencoded 
Origin: http://localhost:8080 
Content-Length: 21 
Connection: keep-alive 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17 
Referer: http://localhost:8080/ 
Accept-Language: nb-no 
Accept-Encoding: gzip, deflate 

但是沒有身體,所以,問題是爲什麼我沒有接收到HTTP身體,當我知道它被髮送?

謝謝!

+0

問題是:爲什麼不顯示客戶端代碼,最初構建POST的地方? –

+0

hi @MarcB該項目用於類的分配,並且客戶端已經實現。我只是爲了實現服務器端來處理GET和POST請求。所以我假設它的服務器端出現錯誤 – mmoe

+0

有什麼錯誤?服務器只是吐出它收到的東西。如果它沒有收到帖子正文,也許你應該檢查客戶端是否確實工作正常。 –

回答

0
while True: 

     client_connection, client_address = self.listener.accept() 
     request = client_connection.recv(2048) 
     print request 

recv不準確地讀取2048個字節,但是其讀取長達2048個字節。如果某些數據到達recv將隨數據一起返回,即使更多的數據可能會跟隨。我的猜測是,在你的情況下,客戶端首先發送HTTP頭,然後發送正文。如果NAGLE算法在客戶端(通用)處於關閉狀態,那麼很可能您的第一個recv將僅顯示標題,而您需要另一個recv作爲正文。這可以解釋你的情況會發生什麼:因爲你沒有做另一個recv,所以你得到的是標題而不是身體。

但即便如此,這太簡單了,遲早會出錯。爲了使它正確,你應該正確地實現HTTP協議:首先讀取可能需要多個recv的HTTP頭,如果頭很大。然後你應該解析標題,找出正文的大小(Content-length標題)並讀取其餘字節。

+0

完美!事實證明,服務器停止接收數據後,通過調用一個新的socket.recv與內容長度做了詭計!謝謝 – mmoe

+0

@mmoe:但是再次。不要指望你會得到第一個recv和身體與下一個完整的標題。基於HTTP的協議是TCP,這是一個沒有隱式消息邊界的流協議。正確的方法是隻要您沒有找到標題的結尾(即空行)就讀取數據, –