我正在研究ICMP pinger程序并遇到了问题。当我运行程序时,我首先在终端中进行sudo su
,因此我有root权限,因为我们需要使用原始套接字,然后当我运行程序时,我得到了这个回溯
sh-3.2# python3 icmp.py
Pinging 31.13.66.112 using Python:
Traceback (most recent call last):
File "icmp.py", line 149, in <module>
ping("www.facebook.com")
File "icmp.py", line 141, in ping
delay = doOnePing(dest,timeout)
File "icmp.py", line 123, in doOnePing
sendOnePing(mySocket,destAddr,myID)
File "icmp.py", line 111, in sendOnePing
mySocket.sendto(packet,(destAddr,1))
OSError: [Errno 56] Socket is already connected
这是我正在运行的代码
import os
from socket import *
from sys import *
from struct import *
from time import *
from select import *
from binascii import *
ICMP_ECHO_REQUEST = 8
def checksum (val):
csum = 0
countTo = (len(val) // 2) * 2
count = 0
while count < countTo:
thisVal = val[count+1] * 256 + val[count]
csum = csum + thisVal
csum = csum & 0xffffffff
count = count + 2
if countTo < len(val):
csum = csum + val[len(val) - 1]
csum = csum & 0xffffffff
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):
timeLeft = timeout
while 1:
startedSelect = time()
whatReady = select([mySocket],[],[],timeLeft)
howLongInSelect = (time() - startedSelect)
if whatReady[0] == []: #Timeout
return "Request timed out."
timeReceived = time()
recPacket, addr = mySocket.recvfrom(1024)
icmpHeader = recPacket[20:28]
kind,code,checksum,idNum,sequence = unpack("bbHHh",icmpHeader)
if idNum == ID:
sizeofdouble = calcsize("d")
timeSent = unpack("d",recPacket[28:28+sizeofdouble])[0]
print(("TYPE: %d CODE: %d CHECKSUM: 0x%08x ID: %d SEQ: %d TIME: %d ms\n" % (kind,code,checksum,idNum,sequence,timeReceived - timeSent)*1000))
timeLeft = timeLeft - howLongInSelect
if timeLeft <= 0:
return "Request timed out."
else:
return "Reply from %s successfully." % destAddr
def sendOnePing(mySocket, destAddr, ID):
myChecksum = 0
header = pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
data = pack("d",time())
myChecksum = checksum(header + data)
if platform == 'darwin':
myChecksum = htons(myChecksum) & 0xffff
else:
myChecksum = htons(myChecksum)
header = pack("bbHHh", ICMP_ECHO_REQUEST,0,myChecksum,ID,1)
packet = header + data
mySocket.sendto(packet,(destAddr,1))
def doOnePing(destAddr,timeout):
icmp = getprotobyname("icmp")
mySocket = socket(AF_INET,SOCK_RAW,icmp)
mySocket.connect((destAddr,80))
myID = os.getpid() & 0xFFFF
sendOnePing(mySocket,destAddr,myID)
delay = receiveOnePing(mySocket,myID,timeout,destAddr)
mySocket.close()
return delay
def ping(host,timeout = 1):
dest = gethostbyname(host)
print("Pinging " + dest + " using Python:")
print()
while 1:
delay = doOnePing(dest,timeout)
print(delay)
sleep(1)
return delay
ping("www.facebook.com")
我们获得了一个带有“骨架”程序的实验表,我们不得不填写缺失的部分Here is the lab sheet where the skeleton code was given
注意:骨架和我的程序不会完全匹配,因为我必须更改内容以修复在此之前发生的其他错误。
我提前感谢你的帮助,
泰勒
答案 0 :(得分:1)
你应该使用“bind”而不是“connect”。那么这个程序应该像root用户一样运行,如Linux或Mac OS的“sudo python3 icmp.py”。 希望这有帮助。 感谢
答案 1 :(得分:0)
所以,你connect
套接字(即告诉它发送数据的对等地址),然后再次调用sendto
提供对等地址。即使这两个地址相同,套接字也会混淆。
要么不connect
,要么致电send
。