2015-11-05 178 views
1

我試圖實現一個超時,在沒有連接收到定義的時間間隔時終止python腳本。到目前爲止,我管理使用下面的代碼來實現超時:套接字等待連接超時

import sys 
import socket 

# Create a TCP/IP socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# Bind the socket to the port 
server_address = ('192.168.43.112', 5001) 
print >>sys.stderr, 'starting up on %s port %s' % server_address 
sock.bind(server_address) 

# Listen for incoming connections 
sock.listen(1) 

while True: 
    try: 
     # Wait for a connection 
     print >>sys.stderr, 'waiting for a connection' 
     connection, client_address = sock.accept() 

     try: 
      print >>sys.stderr, 'connection from', client_address 

      # Receive the data in small chunks and retransmit it 
      while True: 
       data = connection.recv(16) 
       print >>sys.stderr, 'received "%s"' % data 
       if data: 
        print >>sys.stderr, 'Do stuff here' 
       else: 
        print >>sys.stderr, 'no more data from', client_address 
        sock.settimeout(5) 
        break 

     finally: 
      # Clean up the connection 
      connection.close() 

    except socket.timeout: 
     break 

的代碼在這個意義上正常工作,建立一個連接,並結束了非常相同的連接,5秒後腳本終止後。但是,如果超時窗口中我儘量讓另一個方面,我有以下錯誤:

starting up on 192.168.43.112 port 5001 
waiting for a connection 
connection from ('192.168.43.1', 47550) 
received "Data 0 
" 
Do stuff here 
received "" 
no more data from ('192.168.43.1', 47550) 
waiting for a connection 
connection from ('192.168.43.1', 39010) 
--------------------------------------------------------------------------- 
error          Traceback (most recent call last) 
/Users/location/Desktop/sandbox/data_fetcher.py in <module>() 
    24    # Receive the data in small chunks and retransmit it 
    25    while True: 
---> 26     data = connection.recv(16) 
    27     print >>sys.stderr, 'received "%s"' % data 
    28     if data: 

error: [Errno 35] Resource temporarily unavailable 

回答

1

我不完全知道你想怎麼這一切的工作,我覺得有點令人驚訝的是它發生這種方式現在(我沒有想到超時會產生這種效果),但是基於EAGAIN錯誤(errno 35),發生的情況是主套接字上的超時 - 只有你有一個第一次連接 - 導致接受的套接字也處於非阻塞模式。這意味着當您撥打connection.recv並且沒有數據時,就會得到OSError

我懷疑其中的一些可能會在操作系統之間有所不同,但我可以在FreeBSD上重現這一點(您可能在Linux上運行)。

,圍繞工作的最小變化是,我不認爲這是必然的代碼的最佳方式,但它確實工作是接受套接字明確設置爲阻止:

 # Wait for a connection 
     print >>sys.stderr, 'waiting for a connection' 
     connection, client_address = sock.accept() 

     connection.setblocking(1) 

隨着這樣,代碼的表現會好得多(我添加了一個小型測試框架,它將您的代碼作爲一個獨立的進程分離出來,然後以不同的延遲進行多次連接)。

+0

這實際上是訣竅。我在OS X上運行這個。感謝你的解釋。 – dudas