2017-12-06 3 views
0

Ich schreibe gerade ein relativ einfaches Socket-Programm in Python, das eine Ping-Anwendung ist, die ICMP-Anfrage- und Antwortnachrichten verwendet. Ich habe den Großteil des Codes fertig, aber dennoch bekomme ich einige Fehler, wenn ich meine Python-Datei ausführe. Kann mir jemand helfen? Dies ist ein Screenshot von dem, was die Ausgabe sollte wie folgt aussehen:ICMP Pinger Socket Programmanwendung

enter image description here

from socket import * 
import os 
import sys 
import struct 
import time 
import select 
import binascii 
import socket 

ICMP_ECHO_REQUEST = 8 
timeRTT = [] 
packageSent =0; 
packageRev = 0; 

def checksum(str): 
    csum = 0 
    countTo = (len(str)/2) * 2 
    count = 0 
    while count < countTo: 
     thisVal = ord(str[count+1]) * 256 + ord(str[count]) 
     csum = csum + thisVal 
     csum = csum & 0xffffffffL 
     count = count + 2 
    if countTo < len(str): 
     csum = csum + ord(str[len(str) - 1]) 
     csum = csum & 0xffffffffL 
    csum = (csum >> 16) + (csum & 0xffff) 
    csum = csum + (csum >> 16) 
    answer = ~csum 
    answer = answer & 0xffff 
    answer = answer >> 8 | (answer << 8 & 0xff00) 
    return answer 
def receiveOnePing(mySocket, ID, timeout, destAddr): 
    global packageRev,timeRTT 
    timeLeft = timeout 
    while 1: 
     startedSelect = time.time() 
     whatReady = select.select([mySocket], [], [], timeLeft) 
     howLongInSelect = (time.time() - startedSelect) 
     if whatReady[0] == []: # Timeout 
      return "0: Destination Network Unreachable," 
     timeReceived = time.time() 
     recPacket, addr = mySocket.recvfrom(1024) 
     #Fill in start 
     #Fetch the ICMP header from the IP packet 
     icmpHeader = recPacket[20:28] 
     requestType, code, revChecksum, revId, revSequence = struct.unpack('bbHHh',icmpHeader) 
     if ID == revId: 
      bytesInDouble = struct.calcsize('d') 
      timeData = struct.unpack('d',recPacket[28:28 + bytesInDouble])[0] 
      timeRTT.append(timeReceived - timeData) 
      packageRev += 1 
      return timeReceived - timeData 
     else: 
      return "ID is not the same!" 
     #Fill in end 
     timeLeft = timeLeft - howLongInSelect 
     if timeLeft <= 0: 
      return "1: Destination Host Unreachable." 
def sendOnePing(mySocket, destAddr, ID): 
    global packageSent 
    # Header is type (8), code (8), checksum (16), id (16), sequence (16) 
    myChecksum = 0 
    # Make a dummy header with a 0 checksum. 
    # struct -- Interpret strings as packed binary data 
    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1) 
    data = struct.pack("d", time.time()) 
    # Calculate the checksum on the data and the dummy header. 
    myChecksum = checksum(header + data) 
    # Get the right checksum, and put in the header 
    if sys.platform == 'darwin': 
     myChecksum = socket.htons(myChecksum) & 0xffff 
     #Convert 16-bit integers from host to network byte order. 
    else: 
     myChecksum = socket.htons(myChecksum) 
    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1) 
    packet = header + data 
    mySocket.sendto(packet, (destAddr, 1)) 
    packageSent += 1 
    # AF_INET address must be tuple, not str 
    #Both LISTS and TUPLES consist of a number of objects 
    #which can be referenced by their position number within the object 
def doOnePing(destAddr, timeout): 
    icmp = socket.getprotobyname("icmp") 
#SOCK_RAW is a powerful socket type. For more details see:http://sock-raw.org/papers/sock_raw 
    #Fill in start 
    #Create Socket here 
    try: 
     mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) 
    except socket.error, (errno, msg): 
     if errno == 1: 
      raise socket.error(msg) 
    #Fill in end 
    myID = os.getpid() & 0xFFFF #Return the current process i 
    sendOnePing(mySocket, destAddr, myID) 
    delay = receiveOnePing(mySocket, myID, timeout, destAddr) 
    mySocket.close() 
    return delay 
def ping(host, timeout=1): 
    #timeout=1 means: If one second goes by without a reply from the server, 
    dest = socket.gethostbyname(host) 
    print "Pinging " + dest + " using Python:" 
    print "" 
    #Send ping requests to a server separated by approximately one second 
    while 1 : 
     delay = doOnePing(dest, timeout) 
     print "RTT:",delay 
     print "maxRTT:", (max(timeRTT) if len(timeRTT) > 0 else 0), "\tminRTT:", (min(timeRTT) if len(timeRTT) > 0 else 0), "\naverageRTT:", float(sum(timeRTT)/len(timeRTT) if len(timeRTT) > 0 else float("nan")) 
     print "Package Lose Rate:", ((packageSent - packageRev)/packageSent if packageRev > 0 else 0) 
     time.sleep(1)# one second 
    return delay 
# ping("www.google.com") 
# ping("www.poly.edu") 
ping("127.0.0.1") 

Dies ist, was ich zur Zeit als Ausgabe:

[[email protected]:31]> python ICMPPinger.py 
Pinging 54.209.255.182 using Python: 

Traceback (most recent call last): 
    File "ICMPPinger.py", line 111, in <module> 
    ping("www.poly.edu") 
    File "ICMPPinger.py", line 104, in ping 
    delay = doOnePing(dest, timeout) 
    File "ICMPPinger.py", line 90, in doOnePing 
    raise socket.error(msg) 
socket.error: Operation not permitted 
+0

sudo python ICMPPinger.py – Martin

+0

einige Operationen können nur eine machen dmin. – furas

+0

@furas Wie kann ich meinen Python-Code als Administrator in Windows ausführen? Ich benutze gerade Git Bash, aber es gibt keinen 'sudo' Befehl darin. –

Antwort

1

Dieser aus folgenden Gründen sein könnte:

1. Lack of privileges try with root user. 
2. A previous run version of your application is still holding the port in the background. Just check running processes and kill it & remember port is not instantly available after the socket is closed (server having been killed). 
+0

Wie kann ich als root Benutzer laufen? Ich bin in Windows mit Git Bash gibt es keine "Sudo" -Befehl –

+0

mit der rechten Maustaste auf die Eingabeaufforderung und wählen Sie als Administrator ausführen –