简体   繁体   中英

How to fix socket.timeout and receiving data

I write that Program a while ago and now it stopped working. Every time I run it say "timed out". This Error also occurs when I set the timeout higher for example to 10sec.

import sys
import socket

def traceroute(dest_addr, max_hops=30, timeout=0.2):
    proto_icmp = socket.getprotobyname('icmp')
    proto_udp = socket.getprotobyname('udp')
    port = 33434

    for ttl in range(1, max_hops+1):
        rx = socket.socket(socket.AF_INET, socket.SOCK_RAW, proto_icmp)
        rx.settimeout(timeout)
        rx.bind(('', port))

        tx = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, proto_udp)
        tx.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
        tx.sendto(bytes('', 'utf-8'), (dest_addr, port))

        try:
            data, curr_addr = rx.recvfrom(512)
            curr_addr = curr_addr[0]
        except socket.error as err:
            print (err)
            curr_addr = None
        finally:
            rx.close()
            tx.close()

        yield curr_addr

        if (curr_addr == dest_addr):
            break

if __name__ == "__main__":
    dest_name = "www.google.de"
    dest_addr = socket.gethostbyname(dest_name)

    print("traceroute to %s (%s)" % (dest_name, dest_addr))

    for i, v in enumerate(traceroute(dest_addr)):
        print("%d\t%s" % (i+1, v))

presumably some router between your computer and Google isn't sending an ICMP "host unreachable" message which your code is unconditionally waiting for.

the code you've posted is very "fragile" and it'll tend to break in weird and wonderful ways on the internet. eg the example here is that you always wait for an ICMP message immediately after sending your UDP packet, but you might also get a UDP packet back (if the port happens to be open) or nothing back if a router in the middle is silently dropping packets on TTL expiry.

I'd suggest using select (or similar ) to handle waiting for multiple (ie both UDP and ICMP) sockets concurrently, or you could use an async library to keep track of everything

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM