2011-08-24 130 views
32

從測試中,我得出結論,在以下三種情況下,socket.recv(recv_size)將返回。什麼時候socket.recv(recv_size)返回?

  1. 連接關閉後。例如,客戶端端 調用socket.close()或發生任何套接字錯誤,它將返回 空字符串。

  2. 有些數據來了,數據的大小大於recv_size

  3. 有些數據來了,數據的大小小於recv_size,短時間內沒有更多的數據(我發現0.1s會工作)。

更多關於#3的細節:

#server.py 

while True: 
    data = sock.recv(10) 
    print data, 'EOF' 

#client1.py 

sock.sendall("12345") 
sock.sendall("a" * 50) 

#client2.py 

sock.sendall("12345") 
time.sleep(0.1) 
sock.sendall("a" * 50) 

當我運行client1.py,在server.py回聲:

12345aaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaa EOF 

當我運行client2.pyserver.py回聲:

12345 EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 

我的結論是否正確?我在哪裏可以看到有關#3的官方說明?

+0

http://docs.python.org/library/socket.html#socket.socket.recv – mouad

+7

謝謝,但手冊沒有回答我的問題。 – redice

+3

這裏怎麼樣:http://linux.die.net/man/2/recv – mouad

回答

18

是的,你的結論是正確的。 socket.recv是一個阻塞呼叫。

socket.recv(1024)最多可以讀取1024個字節,如果沒有數據正在等待讀取,則會被阻止。如果您沒有讀取所有數據,則不會阻止對socket.recv的其他呼叫。

socket.recv如果連接關閉或出現錯誤,也將以空字符串結尾。

如果你想要一個無阻塞的套接字,你可以使用select模塊(比使用套接字更復雜一點),或者你可以使用socket.setblocking

我在過去有過socket.setblocking的問題,但如果您願意,可隨時嘗試。

+0

我沒有看到關於我的結論3)的任何官方描述。 – redice

+0

socket.recv將讀取準備好在recv調用時讀取的內容。無論讀取的數量是否小於最大大小,套接字只要能夠讀取數據就會解除阻塞。 – Martin

+1

如果您給出正確的標誌,您也可以調用recv()作爲非阻塞: 'socket.recv(10240,0x40)#0x40 = MSG_DONTWAIT aka O_NONBLOCK' 請注意,您必須趕上 '[Errno 11 ]資源暫時不可用 當沒有輸入數據時發生異常。 – Ray

相關問題