gpt4 book ai didi

java - 阻止应用程序绑定(bind)到已绑定(bind)的套接字

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:29:36 25 4
gpt4 key购买 nike

如何防止 Java 应用程序绑定(bind)到另一个进程已在 Windows 上绑定(bind)到的套接字?

我遇到一个问题,我的 Java 应用程序正在监听端口 80。该应用程序可以正常启动并且没有报告任何异常。我不明白为什么我无法连接到端口 80。其他端口工作正常。我检查了 netstat 是否有其他进程在 80 上监听并找到了 Skype。我不认为这是可能的,但经过一些研究,我猜 Skype 正在使用 SO_REUSEADDR 选项进行监听。在这种状态下,接受申请是不确定的。我希望我的 Java 应用程序在此实例中因绑定(bind)异常(或其他)而失败。

如果我可以通过 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]

这就是我假设 Skype 使用 SO_REUSEADDR 的原因

进程似乎没有在不同的接口(interface)上监听。

这是代码片段。端口为80:

    myServerSocket = new ServerSocket(myTcpPort);
while (true) {
new HTTPSession( myServerSocket.accept(), threadPool );
}

作为进一步的信息,我创建了一个示例程序以尽量减少任何副作用或错误处理的消息。

    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();
}
}

}

在运行此示例程序 (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)

最佳答案

socket = new ServerSocket(0);

会自动为您选择一个空闲端口。

此外,此代码将告诉您端口是否可用:

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
}
}

检查 portAvaliable 中的 boolean 值以确定端口状态。

关于java - 阻止应用程序绑定(bind)到已绑定(bind)的套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16591973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com