如何防止Java应用程序绑定到另一个进程已在Windows上绑定的套接字?
我有一个问题,我有一个正在侦听端口80的Java应用程序.应用程序启动正常并且报告没有异常.我无法弄清楚为什么我无法连接端口80.其他端口工作正常.我检查了netstat上其他正在监听80的进程并找到了Skype.我不认为这是可能的,但经过一些研究,我猜测Skype正在使用SO_REUSEADDR选项进行监听.在这种状态下,接受申请是不确定的.我希望我的Java应用程序在此实例中使用绑定异常(或其他)失败.
看起来如果我可以通过Java访问该选项,我可以使用SO_EXCLUSIVEADDRUSE,但我不认为这是可能的.围绕SO_REUSEADDR有很多问题和答案,但我找不到任何问题和答案.这不仅仅是关于Skype(我可以关闭收听部分),我希望我的程序在这种情况下更加强大.
这是来自Windows 7盒子上netstat -abn的片段:
Proto Local Address Foreign Address State
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING [java.exe]
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING [Skype.exe]
Run Code Online (Sandbox Code Playgroud)
这就是为什么我假设Skype正在使用SO_REUSEADDR
这些进程似乎没有在不同的接口上侦听.
这是代码的片段.端口是80:
myServerSocket = new ServerSocket(myTcpPort);
while (true) {
new HTTPSession( myServerSocket.accept(), threadPool );
}
Run Code Online (Sandbox Code Playgroud)
作为进一步的信息,我创建了一个示例程序,以尽量减少任何副作用或错误处理的消息
import java.net.ServerSocket;
public class PortTest
{
public static void main(String[] args)
{
System.out.println( "Hit Ctrl-C to stop.\n" );
try {
ServerSocket myServerSocket = new ServerSocket(80);
System.out.println( "Before the accept() call.");
myServerSocket.accept();
System.out.println( "After the accept() call." );
}
catch (Exception ex ) {
System.out.println("Error listening.");
ex.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行此示例程序(PortTest)时以及当Skype正在运行并侦听端口80时,我仍然没有异常.为了进一步测试,我执行了第二个实例PortTest,我确实看到了正在使用的端口消息.
Error listening.
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at PortTest.main(PortTest.java:10)
Run Code Online (Sandbox Code Playgroud)
socket = new ServerSocket(0);
Run Code Online (Sandbox Code Playgroud)
会自动为您选择一个空闲端口。
此外,此代码将告诉您端口是否可用:
boolean portAvaliable = true;
ServerSocket s = null;
try {
s = new ServerSocket(yourPort);
}
catch (IOException e) {
portAvaliable = false;
}
finally {
if (s != null)
try {
s.close();
}
catch (IOException e) {
//handle the exception
}
}
Run Code Online (Sandbox Code Playgroud)
检查布尔值portAvaliable以识别端口状态。
| 归档时间: |
|
| 查看次数: |
1447 次 |
| 最近记录: |