简体   繁体   English

Java-“没有可用的缓冲区空间”套接字错误原因?

[英]Java - “no buffer space available” socket error cause?

I'm writing a networking program in Java. 我正在用Java编写网络程序。 I use ServerSocket and Socket objects to send and receive messages using TCP. 我使用ServerSocket和Socket对象使用TCP发送和接收消息。 My program runs fine if run for a short time however if I run it for a longer time, I get the following error: 如果运行时间短,我的程序可以正常运行,但是如果运行时间长,则出现以下错误:

java.net.SocketException: No buffer space available (maximum connections reached?): connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)

I thought it might be because I do not close all sockets but I've changed my code: I have one class that I create when I want a new socket and have added a finalize method to close it. 我以为可能是因为我没有关闭所有套接字,但是我改变了代码:我有一个类,当我想要一个新的套接字时创建了一个类,并添加了一个finalize方法来关闭它。 I also have a finalize method to close the ServerSocket so I don't know what the problem is. 我也有一个finalize方法来关闭ServerSocket,所以我不知道问题出在哪里。

Also after I get the error, if I run the program again straight away, it runs into the problem quicker than before. 同样,在收到错误消息后,如果立即再次运行该程序,它比以前更快地遇到了问题。 Then if I wait for a while and run it, it goes back to like the original time. 然后,如果我稍等片刻然后运行它,它可以恢复为原始时间。

I really cannot work out the problem and I've been trying to figure it out for ages. 我真的无法解决这个问题,而且我已经尝试了很长时间了。 Does anyone have any idea what the problem is? 有谁知道这是什么问题吗?

Thanks in advance! 提前致谢!

UPDATE: 更新:

So I've figured out where the error is coming from and it's really weird. 因此,我已经弄清了错误的出处,这真的很奇怪。 I have the following code which is causing the problem: 我有以下导致问题的代码:

try {
        sock = new Socket(InetAddress.getByName(ipaddr), port);
        sock.close();

        // os = sock.getOutputStream();
        // byte[] arr = s.getBytes();
        // os.write(arr);
        // os.close();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            sock.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

As you can see, the code should open a socket and write to it. 如您所见,代码应打开一个套接字并对其进行写入。 However even when all the functional code is commented out as above, so the socket is just opened then immediately closed, I still get the "no buffer space" error. 但是,即使如上所述所有功能代码都已注释掉,因此套接字只是打开然后立即关闭,我仍然会收到“无缓冲区空间”错误。

I really cannot work out why this is. 我真的不知道为什么会这样。 The program is multi threaded and each thread creates objects periodically with the above method in and call it. 该程序是多线程的,每个线程都使用上述方法定期创建对象并对其进行调用。 When the lines to create and close the socket are removed, I no longer get the error but when they are there, even though the socket is opened then closed immediately, I get the error. 当创建和关闭套接字的行被删除时,我不再得到错误,但是当它们在那里时,即使套接字被打开然后立即关闭,我也得到了错误。

Does anyone have any clue why this is happening? 有谁知道为什么会这样吗?

Many thanks. 非常感谢。

I have one class that I create when I want a new socket and have added a finalize method to close it. 当我想要一个新的套接字并添加一个finalize方法来关闭它时,我创建了一个类。 I also have a finalize method to close the ServerSocket so I don't know what the problem is. 我也有一个finalize方法来关闭ServerSocket,所以我不知道问题出在哪里。

Bzzt. zz Stop. 停止。 Check. 校验。 Finalizers are non-deterministic when they run (except some time after the object is no longer reachable, although perhaps not even if the Java app terminates!) -- see Destroying and Finalizing . 终结器在运行时是不确定的(除非无法再访问该对象,尽管Java应用程序即使终止也可能无法访问!)-请参见销毁和终结 Make sure you are using a explicit contract such as Closable and invoking it through and through (don't wait for the GC to come about!). 确保您使用的是显式合同(例如Closable并不断地调用它(不要等待GC出现!)。

This problem is most indicative of "leaking" external resources -- since the GC cares mostly about memory and memory pressure, if there is little pressure and/or the GC is not aggressive it is very easy to run out of the external resources first because the finalizers are not run (yet). 这个问题最能说明外部资源的“泄漏”-因为GC主要关心内存和内存压力,所以如果压力很小和/或GC不具有攻击性,则很容易首先用尽外部资源,因为终结器尚未运行。 In general, finalizer are a safety-net (that doesn't always work), but are not a replacement for other forms of external resource management. 通常,终结器是一个安全网(并不总是起作用),但是不能替代其他形式的外部资源管理。

From the link above: 从上面的链接:

Java makes no guarantees about when garbage collection will occur or in what order objects will be collected. Java不保证何时进行垃圾收集或以什么顺序收集对象。 Therefore, Java can make no guarantees about when (or even whether) a finalizer will be invoked , in what order finalizers will be invoked, or what thread will execute finalizers. 因此, Java无法保证何时(甚至是否)将调用终结器 ,将以何种顺序调用终结器或将由哪个线程执行终结器。

Happy coding. 快乐的编码。

Edit: See this related question: Why would you ever implement finalize()? 编辑:看到此相关问题: 为什么要实现finalize()? . I like the 2nd response from Steve Jessop. 我喜欢史蒂夫·杰索普(Steve Jessop)的第二反应。

Don't use finalize to close resources. 不要使用finalize关闭资源。 It won't work reliably. 它不能可靠地工作。

(There is a chance that the resource objects won't be finalized soon enough and you will run out of resources. You have no control of when the finalizers get run, and it is possible that they will never get run.) (有可能资源对象无法尽快完成,并且资源将用完。您无法控制终结器何时运行,并且有可能永远不会运行。)

What you should be doing is something like this: 您应该做的是这样的:

    Resource resource = // allocate resource
    try {
        // Use the resource ...
    } 
    catch (SomeException ...) {
        // Deal with errors from using the resource
    } 
    finally {
        try {
            resource.close()}
        }
        catch (SomeException ...) {
            // Deal with errors from closing the resource
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java SocketException:没有可用的缓冲区空间 - Java SocketException: No buffer space available Java套接字服务器提供java.net.SocketException:没有可用的缓冲区空间(已达到最大连接数?):connect异常 - Java socket server gives java.net.SocketException: No buffer space available (maximum connections reached?): connect exception Java IOException:在Linux上发送UDP数据包时没有可用的缓冲区空间 - Java IOException: No buffer space available while sending UDP packets on Linux Java套接字:没有可用的缓冲区空间(达到最大连接数?) - Java Sockets: No buffer space available (maximum connections reached?) 搜索java.net.SocketException:没有可用的缓冲区空间 - Hunt down java.net.SocketException: No buffer space available Alfresco共享:java.net.SocketException:没有可用的缓冲区空间 - Alfresco Share: java.net.SocketException: No buffer space available 从Tomcat发送SMTP消息时出错:没有可用的缓冲区空间 - Error sending SMTP message from Tomcat: No buffer space available jmeter给出错误没有可用的缓冲区空间(已达到最大连接数?):connect - jmeter give an error No buffer space available (maximum connections reached?): connect Android VpnService 写数据包错误 - 没有可用的缓冲区空间 - Android VpnService write packet error - no buffer space available java错误-如何解决缓冲区中的\\ n(如果这是导致错误的原因) - java error - how to solve the \n in the buffer (if that is the cause of the error)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM