简体   繁体   English

检查端口是否绑定并以Java侦听; “重置”一个SocketChannel?

[英]Checking if a port is bound & listening in Java; 'resetting' a SocketChannel?

class CheckServerStarted implements Closeable
    {
        private final SocketChannel channel;
        private final InetSocketAddress address;
        private boolean connStarted = false;

        public CheckServerStarted(InetSocketAddress address) throws IOException
        {
            channel = SocketChannel.open();
            channel.configureBlocking(false);

            this.address = address;
        }

        /**
         * @throws IOException 
         * 
         */
        private void startConn() throws IOException
        {
            channel.connect(address);
            connStarted = true;
        }

        private boolean check(int timeout, boolean retry)
        {
            for (int i = 0; i < timeout; i++)
            {
                try
                {
                    final boolean justStarted = !connStarted;
                    if (justStarted)
                    {
                        startConn();
                    }

                    if (justStarted || (i > 0))
                    {
                        // Wait a second between attempts/give the connection some time to get established.
                        try
                        {
                            Thread.sleep(1000);
                        }
                        catch (InterruptedException e)
                        {
                            throw new RuntimeException(e);
                        }
                    }

                    if (channel.finishConnect())
                    {
                        System.out.println("Server started - accepting connections on " + address.toString());
                        return true;
                    }
                }
                catch (IOException e)
                {
                    System.out.println("Connect attempt failed : " + e.getMessage());
                    if (!retry)
                    {
                        break;
                    }

                    // Try to start the connection again if it failed.
                    connStarted = false;
                }
            }

            System.out.println("Connect attempt to " + address.toString() + " failed, ran out of time/attempts");
            return false;
        }

        /* (non-Javadoc)
         * @see java.io.Closeable#close()
         */
        public void close()
        {
            try
            {
                channel.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

I have the following code, which is intended to be used to wait/check for a server to start & be listening on a given address/port. 我有以下代码,旨在用于等待/检查服务器是否启动并正在侦听给定的地址/端口。

The idea is that I can, for example, call 我的想法是,例如,我可以打电话

new CheckServerStarted(addr).check(60, true);

to try to connect to it for up to 60 seconds (retrying if the connection fails since the server hasn't bound the socket yet) 尝试最多连接60秒(如果由于服务器尚未绑定套接字而导致连接失败,请重试)

or 要么

new CheckServerStarted(addr).check(1, false);

to check that the server is currently accepting connections. 检查服务器当前是否正在接受连接。

When I run that first example now, I get output like 现在运行第一个示例时,输出如下

Connect attempt failed : Connection refused: no further information
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt failed : null
14-Jun-2018 10:55:42    Connect attempt to /192.168.223.68:59695 failed, ran out of time/attempts

It's obviously not waiting 1 second between attempts. 显然,两次尝试之间没有等待1秒。

I'm guessing I need to 'reset' channel in between attempts? 我猜我需要在两次尝试之间“重置”频道吗? Do I need to create a new one every time? 每次都需要创建一个新的吗?

You can't reconnect a socket that has been connected, even if the connect attempt failed. 即使连接尝试失败,也无法重新连接已连接的套接字。 Have to close it and create a new one. 必须关闭它并创建一个新的。

Other problems: 其他问题:

  • You are leaking the socket. 您正在泄漏套接字。
  • Get rid of the sleeps and use a Selector . 摆脱睡眠,使用Selector
  • print e instead of e.getMessage() . 打印e而不是e.getMessage() If you had done this properly in the first place, instead of just staring at 'null' all day, you would probably have solved the problem yourself. 如果您一开始就正确地做到了这一点,而不仅仅是整天盯着'null',那么您可能会自己解决问题。
  • an IOException calling finishConnect() is fatal, not a signal for a retry. 调用finishConnect()IOException是致命的,不是重试的信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM