我编写了一些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>
答案 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()