2012-08-22 62 views
1

我粘貼整個代碼,因爲我認爲它儘可能短;爲什麼這個程序掛起?

import socket 

def recv_all(sock): 
    parts = [] 
    while True: 
     msg = "" 
     msg = sock.recv(4096) 
     print "recieved", len(msg), "bytes." 
     if not msg: 
      break 
     parts.append(msg) 
    return "".join(parts) 

http_request = """GET/HTTP/1.1 
Host: {} 
User-Agent: Opera/9.80 (Windows NT 6.1; WOW64; U; tr) Presto/2.10.229 Version/11.64 
Accept: text/html, application/xml;q=0.9, application/xhtml xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 
Accept-Language: en 
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1 
Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0 
Connection: Keep-Alive, TE 
TE: deflate, gzip, chunked, identity, trailers 


""" 
site = "www.google.com.tr" 
print "creating connection" 
conn = socket.create_connection((site,80)) 
print "sending data" 
conn.sendall(http_request.format(site)) 
print "recieving response" 
response = recv_all(conn) 
print "closing connection" 
conn.close() 

print response 

當我運行這個,我得到這個輸出;

 
creating connection 
sending data 
recieving response 
recieved 3743 bytes. 
recieved 4096 bytes. 
recieved 4096 bytes. 
recieved 4096 bytes. 
recieved 3472 bytes. 
recieved 1648 bytes.

我期望它做的是在讀取最後一個塊(本例中爲1648)後讀取0個字節。但它一直在等待。

我在Windows 7上使用Python 2.7。

我在這裏做錯了什麼?我該怎麼做才能按預期工作?

+0

關於保持活性的具體答案已經給出,它們是好的,但是你做錯的重大事情是實施貨運邪教的HTTP而不是閱讀[RFC](http://www.ietf.org /rfc/rfc2616.txt) –

+0

@AlanCurry對不起,我不是母語的人。貨物邪教意味着什麼? – yasar

+0

http://en.wikipedia.org/wiki/Cargo_cult_programming - 這意味着你正試圖在沒有理解的情況下重用一大堆代碼(或者在這種情況下是一大堆HTTP標頭)。 –

回答

5

你發送:

Connection: Keep-Alive, TE 

...和服務器做完全按照自己的要求 - 保持在最後活着的連接。因此,您的讀取呼叫阻止,等待更多數據 - 而服務器正在等待同一連接上的另一個請求。

要麼關閉keep-alive找一個Content-Length頭,並停止閱讀,當你讀過那麼多的數據。

(或者,使用HTTP客戶端庫,而不是試圖自己做:)

+0

+1使用HTTP客戶端庫(特別是,看看[urllib2](http://docs.python.org/library/urllib2.html)) –

+0

對不起,錯過了,我從opera複製請求頭,但刪除保持活動不起作用。我想了解套接字是如何工作的,所以使用HTTP客戶端不是我的選擇。 – yasar

+0

但是,作爲@MikkoJuola建議添加「Connection:Close」作品。 – yasar

1

的關鍵是你發送的HTTP請求。看到這一行:

連接:保持活動,TE

這說明對對方服務器保持連接。

嘗試:

連接:關閉

,看看會發生什麼。

0

編輯:我誤讀你的問題。雖然這不會導致您的掛起行爲,但我認爲您打算將最後的msg添加到parts,這在最終的運行中不會發生,因爲您的if ... break聲明位於.append之前。

+0

沒關係,只要msg不爲空就不會中斷。 – yasar