Python Socket给出了“[Errno 24]太多打开的文件”

时间:2014-09-04 20:49:12

标签: python sockets

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

2 个答案:

答案 0 :(得分:5)

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

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

你说你的其他模块“可能看起来像这样。”该代码片段究竟是它的样子吗?

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

答案 1 :(得分:1)

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)

希望它有所帮助!