【问题标题】:Python Socket gives "[Errno 24] Too many open files"Python Socket 给出“[Errno 24] 打开的文件太多”
【发布时间】:2014-09-04 20:49:12
【问题描述】:

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

我一直在寻找解决方案。 This Stack Overflow answer suggests increasing the number of possible 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)

【问题讨论】:

  • 你仍然缺少一些代码——send_data 实际上并没有发送任何东西,只是设置一个局部变量并返回。
  • 您发布的代码不会出现您描述的问题。请发布您实际使用的代码。
  • 我的代码基本上是这样的......但是,为了证明你错了,我基本上使用了这段代码,几分钟后它仍然没有崩溃。我会说我可能已经找到了我的错误的原因,一秒钟
  • “基本上这个”和“这个”是有区别的。
  • 非常感谢,相应地更新了我的问题

标签: python sockets


【解决方案1】:

您可能正在为while(True): 的每次迭代创建一个新套接字。进程受限于它们可以打开的文件描述符的数量(套接字是 fds。)您可以检查 /etc/security/limits.conf 以查看您的限制设置。

您应该在使用完套接字后关闭它,或者理想情况下,只打开一个并在可能的情况下重复使用它。

您说您的其他模块“可能看起来像这样”。那段代码 sn-p 是不是和它的样子一模一样?

我对此表示怀疑,因为如果是这样,那应该只制作一个套接字。如果您在 while 中实例化 UDP 对象,那么上述问题肯定是您的问题。

【讨论】:

  • 你完全正确,我只是犯了一个初学者的编码错误。非常感谢!
【解决方案2】:
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)

希望它有所帮助!

【讨论】:

    猜你喜欢
    • 2016-04-21
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多