【问题标题】:How can I get a SocketServer in Java to Block the port in use?如何让 Java 中的 SocketServer 阻止正在使用的端口?
【发布时间】:2011-05-27 09:30:30
【问题描述】:

这是我在这里的第一个问题,我会尽力提供尽可能多的信息。

我的 PC 上安装了 Apache 2.2 的本地安装。我默认绑定到端口 100(不要问我为什么)。当我运行 Apache 时,我无法创建端口为 100 的套接字服务器,因为该端口已在使用中。我想要做的是在我正在编写的 Java 服务器中复制此功能。

目前,我创建了一个这样的套接字服务器:

ServerSocket srv = new ServerSocket(100);

问题是,这不会阻止其他应用程序使用此端口。我可以运行我的 Java 应用程序的多个副本,甚至在此之后启动我的 Apache 服务器。我希望 java Server Socket 模仿 Apache 的行为并阻止其他应用程序绑定到所选端口。

我尝试使用 Google,我唯一能找到的是 http://www.dreamincode.net/forums/topic/124376-block-port/,这意味着创建如上所示的套接字服务器应该阻止该端口在其他应用程序中使用。

我使用的是 Windows 7 Ultimate-64bit、NetBeans IDE 6.9.1 和 Java 1.6.0_23。

感谢用户658991,

似乎在客户端连接后或除非我调用 ServerSocket.accept(); 后端口才会被阻塞;

try
{
    ServerSocket server = new ServerSocket(12345);
    System.out.println("Socket Server Established on port " + server.getLocalPort());
    server.accept(); // Code Stops here until connection is completed. 

    // Do Stuff
}
catch(IOException e)
{
    System.out.println("Socket Server Connection Failed!");
    System.out.println(e);
    System.exit(-1);
}

【问题讨论】:

  • 你真的确定服务器套接字被创建并打开了吗?一旦打开,操作系统会负责防止其他应用程序重用该端口。
  • 在 Unix 中只有 root 可以绑定到端口号

标签: java port bind serversocket


【解决方案1】:

创建一个 ServerSocket 本身应该阻塞端口。看看你的代码,哪里可能出错了。

【讨论】:

    【解决方案2】:

    您确定您的程序正在运行吗?我猜它可能已经跑完了。请发布您的完整代码。下面的代码肯定会阻塞端口。

    ServerSocket server = new ServerSocket(3000);
    
    while(true){
        Socket socket = server.accept();
        socket.close();
    }
    

    【讨论】:

    • 是的。我绝对确定程序正在运行。似乎该网站上的其他人也认为简单地创建服务器会阻塞端口。情况似乎并非如此。似乎默认行为是非阻塞连接。一旦客户端连接到服务器,或者服务器调用 server.accept() 强制侦听连接,该端口将被阻止。
    【解决方案3】:

    不应该是这样的。

    ServerSocket ss = new ServerSocket(9987);

    如果我有另一个进程试图 ServerSocket ss = new ServerSocket(9987);

    它会给我这个错误。

    java.net.BindException:地址已在使用中:JVM_Bind 在 java.net.PlainSocketImpl.socketBind(本机方法) 在 java.net.PlainSocketImpl.bind(未知来源) 在 java.net.ServerSocket.bind(未知来源) 在 java.net.ServerSocket.(未知来源) 在 java.net.ServerSocket.(未知来源) 在 MainDriver.main(MainDriver.java:15)

    【讨论】:

    【解决方案4】:

    ServerSocket ctor 是否真正绑定到端口,还是仅当您稍后调用“listen”时才会发生这种情况?我怀疑 ctor 只是将“100”存储在某个字段中。

    Rgds, 马丁

    【讨论】:

      【解决方案5】:

      如果您正在调用ServerSocket 对象的close() 方法,该端口将不再被阻塞,并且可以被其他应用程序绑定使用。

      如果您希望长时间运行的应用程序在特定端口上侦听,就像 Apache 所做的那样,那么您应该让您的 ServerSocket 对象在一个线程中接受连接,并为每个接收到的单个连接生成线程。

      这是通过调用 ServerSocket 类的accept() 方法来完成的,这样每个请求都会创建一个唯一的Socket 对象,然后读取和写入该对象。

      【讨论】:

        【解决方案6】:

        请记住,您的主机上可能有多个网络接口。通常你会有一个物理接口和(可选的)环回接口(127.0.0.1)。

        ServerSocket 允许绑定到所有 (0.0.0.0) 或使用ServerSocket#bind() 绑定到特定的一个。

        因此,在同一台主机上,您可以侦听同一端口,但在不同的网络接口上。

        【讨论】:

          【解决方案7】:

          要查看套接字是否成功绑定,请使用srv.isBound() 方法。这可以验证@biziclop 的评论。

          【讨论】:

          • 在 OP 的代码中始终为真,除非构造函数抛出 BindException,在其中 CA 中您根本无法调用 isBound()。
          【解决方案8】:

          你错了。只要 ServerSocket 存在,创建 ServerSocket 就会阻止其他程序绑定到该端口号。 Apache 没有任何特殊的魔法,这是 TCP 的基本属性。也许您的套接字正在被垃圾收集?

          【讨论】:

            猜你喜欢
            • 2014-10-21
            • 2022-07-08
            • 2023-01-20
            • 1970-01-01
            • 2020-02-24
            • 2018-09-17
            • 2011-12-09
            • 1970-01-01
            • 2013-07-30
            相关资源
            最近更新 更多