为什么这个python UDP套接字被重置为'无'?

时间:2014-10-22 11:27:39

标签: python sockets udp

我编写了一些python代码,用于设置包含udp套接字的类UDPServer。我初始化套接字并将其绑定到localhost和构造函数中的特定端口。它报告成功。我有一个单独的成员函数,然后侦听此套接字上的传入数据。但它报告说套接字是“无”。我的问题是为什么?如果我将套接字的初始化移出构造函数并进入监听功能(即init和listen都在一个函数中),则套接字不会变为“无”。我能够收到关于它的数据。

代码如下:

import socket

class UDPServer:
    def __init__(self, dst_ip, rcv_port, snd_port):
        self._dstip = dst_ip
        self._rcv_port = rcv_port
        self._snd_port = snd_port
        self._sock = self._create_socket()

    def _create_socket(self):

        # Create Datagram (udp) socket
        try :
            self._sock = socket.socket(socket.AF_INET, # Internet
                                       socket.SOCK_DGRAM) # UDP
            print 'Socket created.'
        except socket.error, msg :
            print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
            sys.exit()

        # Bind socket to local host and port
        try:
            self._sock.bind(("", self._rcv_port))
        except socket.error , msg:
            print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
            sys.exit()

        if(self._sock == None):
            print "self._sock is None after bind!!"

        print 'Socket bind complete.'

    def _receive_msg(self):     
        print "waiting on port:", self._rcv_port
        while True:
            if(self._sock == None):
                print "self._sock is None!"
            data, addr = self._sock.recvfrom(1024) # buffer size is 1024 bytes
            print "received message:", data     

def main():
    DST_IP = "100.1.11.275"
    UDP_RCV_PORT = 30001
    UDP_SND_PORT = 30002

    # Create UDP Server
    udpServer = UDPServer(DST_IP, UDP_RCV_PORT, UDP_SND_PORT)
    udpServer._receive_msg()

if __name__ == "__main__":
    main()

输出低于(我在Windows dos提示符下运行此命令):

d:\python_tests>python udp_server.py
Socket created.
Socket bind complete.
waiting on port: 30001
self._sock is None!
Traceback (most recent call last):
  File "udp_server.py", line 51, in <module>
    main()
  File "udp_server.py", line 48, in main
    udpServer._receive_msg()
  File "udp_server.py", line 38, in _receive_msg
    data, addr = self._sock.recvfrom(1024) # buffer size is 1024 bytes
AttributeError: 'NoneType' object has no attribute 'recvfrom'

d:\python_tests>

3 个答案:

答案 0 :(得分:2)

_create_socket方法中,创建一个套接字:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

RETURN ,以便self._sock方法中的__init__返回实际袜子。 因为self._sock的值被赋予None的值,因为如果没有指定其他值,那就是函数的默认返回值。

例如:

def _create_socket(self):

        # Create Datagram (udp) socket
        try :
            sock = socket.socket(socket.AF_INET, # Internet
                                 socket.SOCK_DGRAM) # UDP
            print 'Socket created.'
        except socket.error, msg :
            print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
            sys.exit()

        # Bind socket to local host and port
        try:
            sock.bind(("", self._rcv_port))
        except socket.error , msg:
            print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
            sys.exit()

        if sock == None:
            print "sock is None after bind!!"

        print 'Socket bind complete.'

        return sock ### try this

<强>可替换地: 不要首先编写self._sock = self._create_socket,并且您的代码可以正常工作。

答案 1 :(得分:1)

在构造函数中,您将self._sock分配给self._create_socket()的返回值。问题是,self._create_socket()没有返回任何内容,或者它返回默认值None

如果你只是更改了self._sock,或者从函数中返回它,它就可以了:

import socket

class UDPServer:
    def __init__(self, dst_ip, rcv_port, snd_port):
        self._dstip = dst_ip
        self._rcv_port = rcv_port
        self._snd_port = snd_port
        self._create_socket()

    def _create_socket(self):

        # Create Datagram (udp) socket
        try :
            self._sock = socket.socket(socket.AF_INET, # Internet
                                       socket.SOCK_DGRAM) # UDP
            print 'Socket created.'
        except socket.error, msg :
            print 'Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
            sys.exit()

        # Bind socket to local host and port
        try:
            self._sock.bind(("", self._rcv_port))
        except socket.error , msg:
            print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
            sys.exit()

        if(self._sock == None):
            print "self._sock is None after bind!!"
        print 'Socket bind complete.'

    def _receive_msg(self):     
        print "waiting on port:", self._rcv_port
        while True:
            if not self._sock:
                print "self._sock is None!"
            data, addr = self._sock.recvfrom(1024) # buffer size is 1024 bytes
            print "received message:", data     

def main():
    DST_IP = "100.1.11.275"
    UDP_RCV_PORT = 30001
    UDP_SND_PORT = 30002

    # Create UDP Server
    udpServer = UDPServer(DST_IP, UDP_RCV_PORT, UDP_SND_PORT)
    udpServer._receive_msg()

if __name__ == "__main__":
    main()

答案 2 :(得分:1)

_create_socket(self)不返回新创建的套接字,实际上该函数没有显式返回任何值。在Python中,如果没有遇到显式的return语句,则函数返回None(并且return语句本身不返回None)。在您的情况下,这意味着self._create_socket()正在返回None,并且已在self._sock方法中将其分配给__init__(),并覆盖self._create_socket()中设置的值}。

因此,在__init__()中,只需调用self._create_socket()而不将返回值绑定到self._sock

class UDPServer:
    def __init__(self, dst_ip, rcv_port, snd_port):
        self._dstip = dst_ip
        self._rcv_port = rcv_port
        self._snd_port = snd_port
        self._create_socket()