簡體   English   中英

如何修復socket.timeout和接收數據

[英]How to fix socket.timeout and receiving data

我之前寫過該程序,現在它停止工作了。 每次我運行它時,都說“超時”。 當我將超時設置為更高(例如10秒)時,也會發生此錯誤。

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))

大概是您的計算機和Google之間的某個路由器未發送ICMP“主機無法訪問”消息,您的代碼無條件等待該消息。

您發布的代碼非常“脆弱”,並且會在互聯網上以奇怪而奇妙的方式打破。 例如,這里的示例是,您總是在發送UDP數據包后立即等待ICMP消息,但是如果中間的路由器無聲地丟棄,您也可能會返回UDP數據包(如果端口恰好是打開的),或者什么也沒有回來TTL到期的數據包。

我建議使用select (或類似方法 )來同時處理多個(即UDP和ICMP)套接字,或者您可以使用異步庫來跟蹤所有內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM