【问题标题】:Python 3.4.3 socket.sendtoPython 3.4.3 socket.sendto
【发布时间】:2016-05-02 17:06:48
【问题描述】:

我在 Windows 7 和 Python 3.4.3 版本上运行以下代码时遇到了一些问题。代码是:

import socket
import sys

class TraceRoute(object):

    BADDR = "0.0.0.0" # default bind address - (all IPs)
    PORT = 33434 # default port
    ICMP = socket.getprotobyname('icmp')
    UDP = socket.getprotobyname('udp')

    desternation = ""
    ttl = 0 # we inrecement this by one each time.    

    # sockets
    reciever = None
    sender = None

    # finished?
    finished = False

    def __init__(self, desternation):
        self.desternation = socket.gethostbyname(desternation)

        self.reciever = socket.socket(socket.AF_INET, socket.SOCK_RAW, self.ICMP)
        self.sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, self.UDP)

        # bind to reciever so we can listen for replies
        self.reciever.bind((self.BADDR, self.PORT))

    def next_server(self):
        """ Connects to next server 1 hop away from current server (i.e. server[ttl + 1]) """
        if self.finished:
            # we have nothing to do, just return
            return

        # first job increment the ttl on the socket
        self.ttl += 1
        self.sender.setsockopt(socket.SOL_IP, socket.IP_TTL, self.ttl)

        self.sender.sendto(bytes("", "UTF-8"), (self.desternation, self.PORT))
        current_server = self.reciever.recvfrom(512)[1][0] # get 512 bytes from the reciever
        self.display(current_server)

        if current_server == self.desternation:
            self.finished = True

    def display(self, address):
        """ Gets the hostname (if we can) and displays """
        try:
            name = socket.gethostbyaddr(address)[0]
            print "%s) %s (%s)" % (self.ttl, name, address)
        except socket.error:
            # we couldn't - we'll just tell them the IP address
            print "%s) %s" % (self.ttl, address)

    def __del__(self):
        """ Be good and close our sockets """
        try:
            self.reciever.close()
        except socket.error:
            # already closed
            pass

        try:
            self.sender.close()
        except socket.error:
            # already closed
            pass

if __name__ == "__main__":
    # lets get the address from the commandline args
    if len(sys.argv) <= 1:
        # nothing been specified
        print "You need to give an address"
        print "%s <server>" % sys.argv[0]
        sys.exit() # we can't do anything.

    tracert = TraceRoute(sys.argv[1])
    while not tracert.finished:
        tracert.next_server()

一旦我启动脚本,什么都没有发生,它看起来就像是在无限循环中。阻止它的唯一方法是使用 CTRL+BREAK 组合键。任何形式的帮助都非常受欢迎。提前致谢,Tomislav。

【问题讨论】:

    标签: sockets python-3.x network-programming udp icmp


    【解决方案1】:

    等待 ICMP 回复时没有任何超时:

    current_server = self.reciever.recvfrom(512)[1][0] # get 512 bytes from the reciever
    

    您不应假设路径中的每个节点都启用了 ICMP 回复。

    您的脚本完成条件似乎也有缺陷。当您从目的地获得 ICMP 回复时,您将设置 tracert.finished 为 true。为什么在您发送 UDP ping 数据包时,您的目的地会使用 ICMP 回复您?

    编辑:如果您打算更多地使用网络编程,我强烈建议您下载并学习 Wireshark。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-12
      相关资源
      最近更新 更多