2012-07-25 136 views
6
sock.setblocking(0) 
try: 
    data = sock.recv(1024) 
except socket.error, e: 
    if e.args[0] == errno.EWOULDBLOCK: 
      print 'EWOULDBLOCK' 
else:    
    if not data: #recv over 
     sock.close() 
     print 'close================='  
    else: 
     print 'recv ---data---------' 
     poem += data 

所有上面的代碼是在loop.using non-blocking socket(只是想測試「非阻塞套接字」)來獲取數據。但總是打印'EWOULDBLOCK',我不知道爲什麼?非阻塞套接字,錯誤總是

+0

添加所有代碼,包括設置套接字以及您正在運行的Python版本和操作系統。 – StefanE 2012-07-25 10:41:48

+1

僅供參考:'os.strerror(e.args [0])'會輸出錯誤字符串。 – Alex 2015-10-21 08:40:31

回答

9

該套接字是非阻塞的,所以recv()將在沒有數據要讀取時引發異常。請注意,errno.EWOULDBLOCK = errno.EAGAIN = 11。這是Python的(確實是操作系統)告訴你稍後再試一次recv()的方法。

我注意到,每次得到這個異常時關閉套接字。這根本不會有幫助。你的代碼應該是這樣的:

import socket, errno, time 

sock = socket.socket() 
sock.connect(('hostname', 1234)) 
sock.setblocking(0) 

while True: 
    try: 
     data = sock.recv(1024) 
     if not data: 
      print "connection closed" 
      sock.close() 
      break 
     else: 
      print "Received %d bytes: '%s'" % (len(data), data) 
    except socket.error, e: 
     if e.args[0] == errno.EWOULDBLOCK: 
      print 'EWOULDBLOCK' 
      time.sleep(1)   # short delay, no tight loops 
     else: 
      print e 
      break 

對於這樣的事情,在select模塊通常是要走的路。

+0

謝謝。我發現問題是我想'time.sleep(1)'。沒有它的打印都是''EWOULDBLOCK''。那麼爲什麼'沒有緊密循環'是必不可少的? – zhenyuyang 2012-07-25 13:04:26

+0

@zhenyuyang我不明白'我錯過了',但緊密的循環只是浪費了CPU週期,當它可以做其他事情時,比如運行其他線程或進程。如果你不斷收到EWOULDBLOCK,那麼沒有數據要讀取。如果你不想這種情況,你爲什麼要使用非阻塞模式? – EJP 2012-07-26 02:21:34

+0

'socket.timeout'異常是否在這裏重要? – CMCDragonkai 2016-10-27 20:07:09

3

由設計引發的例外,因爲您正在使用non-blocking IO

主要的機械差異是發送,接收,連接和接受可以返回沒有做任何事情。你有(當然)有很多選擇。你可以檢查返回代碼和錯誤代碼,通常讓自己瘋狂。

Python doc

引用如果您運行man errno 3,你將看到的EWOULDBLOCK描述。這個例外是合理的,因爲還沒有數據可讀。