需要在調用socket的connect方法之前設置settimeout(time)
方法,另外在設置之后要將再次調用settimeout(None)
來設置socket進入阻塞模式。
如下代碼示例:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(10) sock.connect(address) sock.settimeout(None) fileobj = sock.makefile('rb', 0)
原來,socket 一旦設置了timeout, 就進入了 non-blocking 工作模式,原來的 send() 和 recv() 等的用法就完全不同了,可能會只發送或者接收了部分數據,需要檢查返回值並多次重試。甚至,makefile() 是完全不允許使用的,它已經在 socket 模塊的文檔中明確聲明,不過如果不是在這里栽過跟頭很少會注意到這點。
明確了這一點,就可以寫出在 non-blocking 模式工作的正確代碼,會復雜不少,尤其處理一開始不能確定數據長度的文本協議。
阻塞和非阻塞是完全兩種不同的使用方法,並不是添加一個socket.settimeout() 那么簡單。