首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.net.BindException:打开太多连接时无法分配请求的地址

java.net.BindException:打开太多连接时无法分配请求的地址
EN

Stack Overflow用户
提问于 2015-08-07 11:17:15
回答 1查看 4.8K关注 0票数 3

我正在运行以下代码,它只是在无限循环中连接和关闭一个套接字:

代码语言:javascript
复制
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;

public class Main {
    public static void main(String[] args) throws Exception {
        Thread.sleep(1000);
        InetAddress localhost = InetAddress.getByName("127.0.0.1");
        InetSocketAddress localhostRpcbind = new InetSocketAddress(localhost, 111);
        SelectorProvider selectorProvider = SelectorProvider.provider();
        long iterations = 0;
        while (true) {
            try {
                SocketChannel socketChannel = selectorProvider.openSocketChannel();
                socketChannel.connect(localhostRpcbind);
                socketChannel.finishConnect();
                socketChannel.close();
                iterations ++;
            } catch (Exception e) {
                System.err.println("after " + iterations + " iterations");
                e.printStackTrace(System.err);
                throw e;
            }
        }
    }
}

端口111是rpcbind的端口(在我的机器上启动并运行)。在代码的第一次运行中,我将得到如下内容:

代码语言:javascript
复制
after 28239 iterations
java.net.BindException: Cannot assign requested address
    at sun.nio.ch.Net.connect0(Native Method)
    at sun.nio.ch.Net.connect(Net.java:458)
    at sun.nio.ch.Net.connect(Net.java:450)
    at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:648)
    at Main.main(Main.java:16)

随后的运行将立即失败(0次迭代),直到过一段时间我再次获得第一个结果(~26-28k迭代,然后失败)。

发生了什么,如何才能让这个连接/断开循环无限期地正常运行?

我在linux x64 (fedora 22)上运行。

注意:是的,我知道代码是无用的,什么也不做,这是一个更大问题的SSCCE,我正在试图调查。

UPDATE --看起来我在我的机器上遇到了短暂的端口耗尽:

代码语言:javascript
复制
$ cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000

因此,我有~28k临时端口可用于连接,这与我的错误相匹配。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-07 11:49:40

在绑定到大约28K不同的端口之后,系统已经耗尽了用于绑定套接字的临时端口。

造成此问题的原因是,为了打开TCP连接,操作系统分配一个临时端口(用于源端口)。它将套接字绑定到分配的端口。在TCP连接关闭后,由于历史原因(new.svg),连接处于TIME_WAIT状态,通常为2分钟,从我的观点来看,在今天的大多数系统中,这一次可以减少.其他讨论的主题。

作为一种解决方案,您可以使用sysctl减少这个超时:

将net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait的值更改为1这样的低值,情况会有所改善。但是,您的应用程序足够快地在不到1秒内消耗~28K端口,您仍然会看到这个异常。

可以调优的其他TCP参数:增加临时端口的范围: net.ipv4.ip_local_port_range net.ipv4.tcp_tw_reuse net.ipv4.tcp_tw_recycle

看:http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.htmlhttp://www.lognormal.com/blog/2012/09/27/linux-tcpip-tuning/

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31876441

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档