Python,socket。 或没有套接字(调试帮助)

Python, socket. or no socket (Debugging help)

还在弄清楚这个python的东西。 我一直在搞乱pinger协议。 它还没有完全按照我的要求完成,但它正在实现。

mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, icmp)
AttributeError: type object '_socketobject' has no attribute 'socket'

这是我得到的错误,问题似乎完全存在于"doOnePing"中。 我还将在下面添加完整的代码,任何人都想知道其他地方发生了什么。 我在用

from socket import *

谢谢您的帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def doOnePing(destAddr, timeout):

    icmp = getprotobyname("icmp")

    try:
        mySocket = socket(AF_INET, SOCK_STREAM, icmp)
    except error, (errno,msg):
        if errno == 1:
            msg = msg +(" - ICMP messages can only be sent when running as root")
            raise error(msg)
        raise

    myID = os.getpid() & 0xFFFF  # Return the current process i

    sendOnePing(mySocket, destAddr, myID)
    delay = receiveOnePing(mySocket, myID, timeout, destAddr)

    mySocket.close()
    return delay

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from socket import *
import os
import sys
import struct
import time
import select
import binascii

ICMP_ECHO_REQUEST = 8


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):
    timeLeft = timeout

    while 1:
        startedSelect = time.time()
        whatReady = select.select([mySocket], [], [], timeLeft)
        howLongInSelect = (time.time() - startedSelect)
        if whatReady[0] == []:  # Timeout
            return"Request timed out."

        timeReceived = time.time()
        recPacket, addr = mySocket.recvfrom(1024)

        # Fill in start
        icmpHeader = recPacket[20:28]
        type, code, checksum, packetID, sequence = struct.unpack("bbHHh", icmpHeader)

        if packetID == ID:
                bytesInDouble = struct.calcsize("d")
                timeSent = struct.unpack("d", recPacket[28:28 + bytesInDouble])[0]
                return timeReceived-timeSent

        timeLeft = timeLeft - howLongInSelect
        if timeLeft <= 0:
            return"Request timed out."


def sendOnePing(mySocket, destAddr, ID):
    # 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':
        # Convert 16-bit integers from host to network  byte order
        myChecksum = htons(myChecksum) & 0xffff
    else:
        myChecksum = htons(myChecksum)

    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, myChecksum, ID, 1)
    packet = header + data

    mySocket.sendto(packet, (destAddr, 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 = getprotobyname("icmp")

    try:
        mySocket = socket(AF_INET, SOCK_STREAM, icmp)
    except error, (errno,msg):
        if errno == 1:
            msg = msg +(" - ICMP messages can only be sent when running as root")
            raise error(msg)
        raise

    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,
    # the client assumes that either the client's ping or the server's pong is lost
    dest = gethostbyname(host)
    print"Pinging" + dest +" using Python:"
    print""

# Fill in start

    count = 100
    for i in xrange(count):
        delay = doOnePing(host, timeout)

        if delay == None:
            print"failed. (timeout within %ssec.)" % timeout
        else:
            delay = delay * 1000
            print"get ping in %0.4fms" % delay
    print

# Send 100 ping requests to a server separated by approximately one second.
# Report the minimum, maximum, and average RTTs at the end of all pings from the client.
# In addition, calculate the packet loss rate (in percentage).



ping("google.com")

更新:
谢谢你的帮助。 我删除了插座。 当我创建我的套接字时,现在我收到了错误

1
_sock = _realsocket(family, type, proto)

socket.error: [Errno 41] Protocol wrong type for socket


from socket import *更改为import socket

当您执行from socket import *时,socket.socket将使用名为socket的相同包遮蔽包。 一般来说,更好地了解您要导入的内容。


您已将类socket导入到没有模块前缀的命名空间中,但是当您在doOnePing中执行socket.socket时,您尝试使用模块前缀来访问它。

对于记录,您应该对from import *导入持怀疑态度,因为当您使用它们时,您不再明确您的命名空间中的内容。