抛出套接字超时以便恢复

时间:2013-06-05 15:26:59

标签: python network-programming timeout

所以我一直在寻找,How to set timeout on python's socket recv method?

和其他人一样,但我似乎无法让它像我想要的那样工作。我正在编写一个traceroute脚本,并希望程序抛出一个超时异常,如果它已经等待超过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

先谢谢了。 =)

1 个答案:

答案 0 :(得分:0)

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