2013-07-25 25 views
0

我有一个应用程序X可以在两台计算机上运行,​​但一次只能运行一个。我有另一个应用程序Y,用Python编写,给出了两个可能的IP地址需要找出哪台计算机正在运行应用程序X(如果有的话)。我已经部分解决了这个问题,只要有一个UDP服务在端口上侦听,并且每当它接收到一些数据时都会响应'Hello'。客户端可以尝试将数据发送到每个地址上的应用程序X端口,如果得到响应,我知道应用程序正在该计算机上运行。同时测试一对网络套接字

到目前为止我的代码看起来是这样的:

def ipaddress(self): 
    """Test which side responds on the status port.""" 
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
    try: 
     s.settimeout(5) 
     s.sendto("status", (ADDR_A, PORT)) 
     s.recvfrom(1024) 
    except socket.timeout: 
     try: 
      s.sendto("status", (ADDR_B, PORT)) 
      s.recvfrom(1024) 
     except: 
      pass 
     else: 
      return ADDR_B 
    else: 
     return ADDR_A 
    finally: 
     s.close() 
    return None 

具有这种功能的问题是,它定期调用每当我想谈谈在计算机上运行的应用程序X.它总是首先测试ADDR_A,如果它不运行应用程序X,那么在尝试ADDR_B之前,我必须等待套接字超时。尽管不会经常发生,但是当我再次尝试时,应用程序X可能会切换计算机。

有没有更好的方法?我想知道是否可以并行连接到两台计算机,并尽快返回响应?或者我应该缓存哪个ip地址上次首次响应函数被调用?我将如何编码这些或其他想法?

谢谢。

编辑:下面是一个使用选择我修改后的代码:

def ipaddress(addr_a, addr_b, timeout=5): 
    """Test which side responds on the status port.""" 

    # Create UDP sockets for each address 
    socks = [ socket.socket(socket.AF_INET, socket.SOCK_DGRAM), 
       socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
       ] 

    # Send some data to each socket 
    for sock, addr in zip(socks, (addr_a, addr_b)): 
     sock.connect(addr) # do explicit connect so getpeername works 
     sock.send("status") 

    # Wait for the first to respond if any 
    while socks: 
     waiting = select.select(socks, [], socks, timeout)[0] 
     if waiting: 
      for sock in waiting: 
       try: 
        data = sock.recv(1024) 
        if data: 
         return sock.getpeername()[0] 
       except Exception, e: 
        # Occasionally get [Errno 10054] which means socket isn't really 
        # available, so see if other responds instead... 
        socks.remove(sock) 
     else: 
      break # timeout occurred 
    return None 

回答

1

你应该看看select.select()提供正是你正在寻找来看看两台计算机并行的能力。

+0

是的,这很好,谢谢你! – dwxw