最近在做乙個對時間要求比較高的掃瞄器,需要封裝一下socket模擬http發包的一些常用函式。簡單的說,就是重寫一下requests中的get、post方法。
今天在寫的時候,遇到一枚很奇怪的問題,對同乙個url,post請求能正常返回資訊,而一旦切到get,socket time out。
偽**如下:
get_str = ''post_str = '
'def
get(url,port):
sock =socket.connect(url,port)
sock.send(get_str %(url, port))
response = ''
temp = sock.recv(4096)
while
temp:
temp = sock.recv(4096)
response +=temp
return response
心煩意亂的調了很久無果,出去吃了個飯,回來查查資料,從頭開始順了一遍,找到了bug點。原因是http 1.1協議中,預設connection: keep-alive。
connection: keep-alive 當乙個網頁開啟完成後,客戶端和伺服器之間用於傳輸http資料的tcp連線不會關閉,如果客戶端再次訪問這個伺服器上的網頁,會繼續使用這一條已經建立的連線
connection: close 代表乙個request完成後,客戶端和伺服器之間用於傳輸http資料的tcp連線會關閉, 當客戶端再次傳送request,需要重新建立tcp連線。
而python中的sock.recv如果接收不到資料,會等到tcp連線down掉,才會返回null。如果在程式中沒有設定超時時間,會等到伺服器主動斷開連線,一般是30s~60s。
這就是造成socket timeout的原因。在http request裡新增connection: close即可解決問題。但是為什麼只有get受到影響,post卻沒有問題呢?
做了個簡單的測試:
post 很快就返回了結果:
而get用了很久才返回結果,其中connection為keep-alive:
所以,之前所說的http 1.1協議中,所有的請求都預設為connection: keep-alive是錯誤的認識。
只有get請求會預設採取connection: keep-alive
python socket 模擬 FTP處理檔案
解析 的思路 首先,先將伺服器和客戶端的建立連線,連線成功後,客戶端要先將自己的請求傳送至server,因為ftp的get是處理檔案的,所以採用cmd.startwith get 作為判斷條件,這個時候必須收到server的應答,server response,表示server已經準備可以接受資料了...
Python Socket 程式設計
client import socket,sys if name main 處理引數 argv sys.argv if len argv 3 or len argv 2 and argv 1 print useage argv 0 sys.exit 0 host argv 1 server ip位址...
python socket程式設計
python 編寫server的步驟 1.第一步是建立socket物件。呼叫socket建構函式。如 socket socket.socket family,type family引數代表位址家族,可為af inet或af unix。af inet家族包括internet位址,af unix家族用於...