2016-01-26 5 views
0

У меня возникли проблемы с запуском следующего кода в Windows 7 и версии Python 3.4.3. Код:Python 3.4.3 socket.sendto

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. Любая помощь более чем приветствуется. Спасибо заранее, Томислав.

ответ

0

Вы не имеете тайм-аут во время ожидания ответа ICMP:

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

Вы не должны считать, что каждый узел на вашем пути будет включен ответ ICMP.

Также кажется, что ваше условие завершения скрипта является ошибочным. Вы установите для параметра tracert.finished значение true, когда вы получите ответ ICMP от вашего адресата. Почему ваш пункт назначения отвечает вам, используя ICMP при отправке пакетов ping UDP?

EDIT: Если вы собираетесь работать больше с сетевым программированием, то я сильно рекомендуем скачать и изучить Wireshark.

Смежные вопросы