我有以下UDP类以大约100Hz的发送数据数组
from six import string_types
import socket
import struct
def convert_data(iterable):
if isinstance(iterable, string_types):
return str(iterable)
data = tuple(iterable)
format = "{0}H".format(len(data))
print("Sending data:", format, data)
if max(data) > 2**16 - 1:
raise ValueError(max(data))
if min(data) < 0:
raise ValueError(min(data))
return struct.pack(format, *data)
class UDP(object):
def __init__(self, ip, port):
self._ip = ip
self._port = port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.connect((ip, port))
def send_data(self, data):
message = convert_data(data)
return self.socket.sendall(message)
成功发送大约一分钟后,它会出现以下错误:
Traceback (most recent call last):
File "take_analogue_data.py", line 13, in <module>
File "take_analogue_data.py", line 8, in main
File "/home/pi/nio-integration/hardware/raspi/UDP.py", line 22, in __init__
File "/usr/lib/python2.7/socket.py", line 187, in __init__
socket.error: [Errno 24] Too many open files
我一直在寻找解决方案。此堆栈溢出答案建议增加可能的文件数量。我真的不认为这是我正在寻找的解决方案。
有什么我能做的吗?我想每次都关闭连接可能会奏效,但我已经玩过很多东西了。(我试过send
、sendall
和sendto
——都不起作用)
注意:我在Raspberry Pi上运行Raspbian Wheezy上的Python2.6
编辑另一个模块正在发送数据。它可能看起来像
import UDP
udp = UDP.UDP(IP, PORT)
while(True):
udp.send_data(range(8))
sleep(0.01)
很可能,您正在为while(True):
的每一次迭代创建一个新的套接字。进程被限制为可以打开的文件描述符的数量(套接字是fds。)您可以检查/etc/security/limits.conf
以查看您的限制设置为多少。
你应该在用完插座后关闭它,或者,理想情况下,只打开一个,如果可能的话,再使用它。
你说你的另一个模块"可能看起来像这样"。这个代码片段正是它看起来的样子吗?
我对此表示怀疑,因为如果是这样的话,那就只能制作一个插座。如果您在while
中实例化UDP对象,那么上述问题肯定是您的问题。
class UDP(object):
def __init__(self, ip, port):
self._ip = ip
self._port = port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.connect((ip, port))
关于UDP,您需要知道的是,它是一个无会话、无连接的协议,这意味着:self.socket.connect((ip,int(port)))
不正确,因此您应该删除它。
如果您想连接到服务器,请使用Tcp:
class TCP(object):
def __init__(self, ip, port):
self._ip = ip
self._port = port
self.socket = socket.socket() #Here is the change
self.socket.connect((ip, port))
def send_data(self, data):
message = convert_data(data)
return self.socket.sendall(message)
希望它能有所帮助!