Java-“没有可用的缓冲区空间”;套接字错误原因? [英] Java - "no buffer space available" socket error cause?

查看:207
本文介绍了Java-“没有可用的缓冲区空间”;套接字错误原因?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Java编写网络程序。我使用ServerSocket和Socket对象通过TCP发送和接收消息。如果短时间运行,我的程序可以正常运行,但是如果运行较长时间,则会出现以下错误:

I'm writing a networking program in Java. I use ServerSocket and Socket objects to send and receive messages using 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)

我认为是这样可能是因为我没有关闭所有套接字,但是我改变了代码:我有一个类,当我想要一个新的套接字时创建了一个类,并添加了一个finalize方法来关闭它。我也有一个finalize方法来关闭ServerSocket,所以我不知道问题出在哪里。

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. I also have a finalize method to close the ServerSocket so I don't know what the problem is.

同样在我收到错误消息后,如果我再次直接运行程序它比以前更快地遇到了问题。然后,如果我等待一会儿再运行它,它可以恢复为原始时间。

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?

谢谢!

更新:

所以我已经弄清了错误的出处,这真的很奇怪。我有以下导致问题的代码:

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真的不知道为什么会这样。该程序是多线程的,每个线程都使用上述方法定期创建对象并对其进行调用。当创建和关闭套接字的行被删除时,我不再得到错误,但是当它们在那里时,即使套接字被打开然后立即关闭,我也会收到错误。

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?

非常感谢。

推荐答案



当我想要一个新套接字时,我创建了一个类,并添加了 finalize 方法将其关闭。我也有一个 finalize 方法来关闭ServerSocket,所以我不知道问题出在哪里。

I have one class that I create when I want a new socket and have added a finalize method to close it. I also have a finalize method to close the ServerSocket so I don't know what the problem is.


Bzzt。停止。检查一下终结器在运行时是不确定的(除非无法再访问该对象,尽管Java应用程序即使终止也可能无法访问!)-请参见销毁并完成。确保您使用的是显式合同,例如 Closable 并不断调用它(不要等待GC出现!)。

Bzzt. 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. 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!).

此问题最能说明外部资源的泄漏-因为GC主要关心内存和内存压力,如果压力很小和/或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). In general, finalizer are a safety-net (that doesn't always work), but are not a replacement for other forms of external resource management.

来自上面的链接:



Java不保证何时进行垃圾收集或以什么顺序收集对象。因此, Java无法保证何时(甚至是否)调用终结器,终结器以什么顺序被调用,或者哪个线程将执行终结器。

Java makes no guarantees about when garbage collection will occur or in what order objects will be collected. 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.


快乐编码。

编辑:请参阅以下相关问题:为什么要实施finalize()?。我喜欢史蒂夫·杰索普(Steve Jessop)的第二个回应。

See this related question: Why would you ever implement finalize()?. I like the 2nd response from Steve Jessop.

这篇关于Java-“没有可用的缓冲区空间”;套接字错误原因?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆