2015-11-05 179 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