Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;java.net.BindException:地址已在使用中;在尝试为负载测试快速创建和销毁套接字时_Java_Sockets_Networking_Tcp - Fatal编程技术网

&引用;java.net.BindException:地址已在使用中;在尝试为负载测试快速创建和销毁套接字时

&引用;java.net.BindException:地址已在使用中;在尝试为负载测试快速创建和销毁套接字时,java,sockets,networking,tcp,Java,Sockets,Networking,Tcp,我试图通过打开大量到服务器的套接字连接,进行身份验证,关闭连接,然后重复来加载测试Java服务器。我的应用程序在一段时间内运行良好,但最终我得到: java.net.BindException:地址已在使用中:connect 根据我阅读的文档,这是因为关闭的套接字在调用close()后的一段时间内仍然占用分配给它们的本地地址。这取决于操作系统,但可能以分钟为单位。我尝试在套接字上调用setReuseAddress(true),希望调用close()后,它的地址可以立即重用。不幸的是,情况似乎并非

我试图通过打开大量到服务器的套接字连接,进行身份验证,关闭连接,然后重复来加载测试Java服务器。我的应用程序在一段时间内运行良好,但最终我得到:

java.net.BindException:地址已在使用中:connect

根据我阅读的文档,这是因为关闭的套接字在调用close()后的一段时间内仍然占用分配给它们的本地地址。这取决于操作系统,但可能以分钟为单位。我尝试在套接字上调用
setReuseAddress(true)
,希望调用
close()
后,它的地址可以立即重用。不幸的是,情况似乎并非如此

我创建套接字的代码是:

Socket socket = new Socket();
socket.setReuseAddress(true);
socket.connect(new InetSocketAddress(m_host, m_port));
但我仍然得到这个错误:

java.net.BindException:地址已在使用中:稍后连接

有没有其他方法来完成我想做的事情?我想举个例子:打开100个插座,全部关闭,打开200个插座,全部关闭,打开300个,等等,最多2000个左右的插座


任何帮助都将不胜感激

我认为您应该计划要使用的端口,以便连接到要使用的端口。我的意思是尝试使用给定的端口连接。如果连接失败(或者在您的情况下引发异常),请尝试使用下一个端口号打开连接

尝试将
connect
语句包装在
Try/catch

下面是一些伪代码,它传达了我认为可行的东西:

portNumber = x //where x is the first port number you will try
numConnections = 200 // or however many connections you want to open
while(numConnections > 0){
    try{
        connect(host, portNumber)
        numConnections--
    }catch(){}
    portNumber++
}
这段代码没有涵盖一些特殊情况,例如“当所有端口都在使用时会发生什么?”

没有使用bind(),但是setReuseAddress(true)很奇怪,我希望您理解setReuseAddress的含义(以及它的意义)。100-2000并不是一个需要打开的大量套接字,但是您尝试连接的服务器(因为它看起来是同一个addr/端口对)可能只是删除它们,而正常的积压工作是50个

编辑: 如果需要快速打开多个套接字(ermm端口扫描?),我强烈建议使用NIO和connect()/finishConnect()+选择器。在同一个线程中打开1000个套接字非常缓慢。
忘记了您的代码中可能需要finishConnect()。

在两分钟的等待时间内打开那么多出站套接字,这样就耗尽了出站端口的空间。您应该问自己的第一个问题是,这是否代表了一个真实的负载测试?真正的客户真的会这么做吗?如果没有,您只需要修改您的测试方法


顺便说一句,SO_LINGER是应用程序在close()期间等待刷新数据的秒数。它通常为零。如果这是发出关闭的结束,端口将在等待时间间隔内挂起。这不是一回事。有可能滥用SO_LINGER选项来修补问题。但是,这也会导致对等端出现异常行为,这也不是测试的目的。

引发异常的是服务器还是客户端?连接数一致后会发生这种情况吗?您可能需要更改机器的TCP设置,请确认您的正确性,因为没有真正的客户端会打开那么多连接。在我的应用程序中,真正的客户端只会打开一个到服务器的TCP连接。我想做的是模拟真实的客户端,我希望在同一台机器上运行尽可能多的模拟客户端。你的回答也帮了我的忙!:-)这里我想补充的是,如果使用setSoLinger()方法,它会给已经连接的对等方带来问题,有时它们也会断开连接!我真的不知道是什么导致了这种行为,但我花了整整45分钟才弄清楚@M2X SO_LINGER off是默认值,这会导致
close()
表现得像我们现在所爱的那样。如果将其设置为“开”,并且超时时间为零,则会导致
close()
shutdown()
发出重置,而不是正确关闭。我甚至不想提及这一点,因为这是一种不受欢迎的行为。如果有任何正当的理由在一个普通的TCP/IP应用程序中乱来,那么我还没有遇到它们。。。在将近三十年的时间里。所以内核重新分配套接字,即使它们仍然处于时间等待状态?@rogerdpack“重新分配套接字”毫无意义。没有这样的行动。我不知道你在问什么,这没有任何意义。他正在尝试连接到一个以固定端口号侦听的服务,而不是一个可以递增的端口号,他的问题是本地端口空间,而不是远程端口空间。如果你真的非常绝望,这样做可能会有所帮助:该端口仍在使用中有问题吗?再试一次!:)@rogerdpack只有在您不知道目标端口,并且不知道自己什么都不知道的情况下,它才有帮助。这里提供的代码是端口扫描程序,而不是传统的TCP客户端。无论如何,这个答案与被问到的问题无关。