2013-06-05 40 views
0

所以我一直在寻找,在这里:How to set timeout on python's socket recv method?掷插座超时的recv

等人,但我似乎无法得到它的工作像我想要的。我正在编写一个跟踪路由脚本,并希望程序在它刚刚发送的数据包已经等待超过10秒钟的时间内发出超时异常,以便它可以移动到下一个跃点。除了尝试捕获超时之外,我还有一些额外的东西,但它永远不会捕获(甚至抛出)异常。

try: 
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) 
    #setup receive socket 
    recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) 
    recv_socket.bind(("", 8888)) 
    #recv_socket.settimeout(10) 
    recv_socket.setblocking(0) 
    ready = select.select([recv_socket], [], [], 10) 
except socket.error , msg: 
    print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] 
    sys.exit() 

# tell kernel not to put in headers, when using IPPROTO_RAW this is not necessary 
# s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 

# Get usable hostname 
destination_address = socket.gethostbyname('www.google.com') 
max_ttl = 50 
ttl = 1 

while(1): 
    # Timer 
    t_start = time.time() 

    s.sendto(constructPacket(ttl,'129.196.196.163',destination_address), (destination_address , 0)) 

    # Receive and output 
    # need to add, if no receive, timeout and increase ttl by one 
    curr_addr = None 
    curr_name = None 
    try: 
     if ready[0]: 
      _, curr_addr = recv_socket.recvfrom(512) 
      curr_addr = curr_addr[0] 
     else: 
      print 'Timeout' 
     try: 
      curr_name = socket.gethostbyaddr(curr_addr)[0] 
     except socket.error: 
      curr_name = curr_addr 
    except timeout, e: 
     print 'Timeout' 
    except socket.error, e: 
     print 'Socket Error. Error Code : ' + str(e[0]) + ' Message ' + e[1] 
     sys.exit() 

    if curr_addr is not None: 
     curr_host = "%s (%s)" % (curr_name, curr_addr) 
    else: 
     curr_host = "*" 
    print "%d | %s | %dms" % (ttl, curr_host,(time.time()-t_start)*1000) 

    ttl = ttl + 1 

    if curr_addr == destination_address or ttl == max_ttl: 
     s.close() 
     recv_socket.close() 
     break 

在先进的感谢。 =)

回答

0

在非阻塞模式下没有超时异常。使用select()的超时参数,并检测select()在没有任何就绪套接字的情况下返回的情况。