Python Socket 提供"[Errno 24] Too many open files"



我有以下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

我一直在寻找解决方案。此堆栈溢出答案建议增加可能的文件数量。我真的不认为这是我正在寻找的解决方案。

有什么我能做的吗?我想每次都关闭连接可能会奏效,但我已经玩过很多东西了。(我试过sendsendallsendto——都不起作用)

注意:我在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)

希望它能有所帮助!

最新更新