كيف يمكنني اكتشاف حالة الخادم في تطبيق Java الماسح الضوئي المنفذ

StackOverflow https://stackoverflow.com/questions/2776729

  •  03-10-2019
  •  | 
  •  

سؤال

أنا أكتب ماسح ضوئي للمنفذ في جافا وأريد أن أكون قادرًا على تمييز حالات الاستخدام الأربعة التالية:

  • المنفذ مفتوح
  • المنفذ مفتوح وتم قراءة لافتة الخادم
  • ميناء مغلق
  • الخادم ليس مباشرًا

لدي الرمز التالي:

    InetAddress address = InetAddress.getByName("google.com");
    int[] ports = new int[]{21, 22, 23, 80, 443};
    for (int i = 0; i < ports.length; i++) {
        int port = ports[i];
        Socket socket = null;
        try {
            socket = new Socket(address, port);
            socket.setSoTimeout(500);
            System.out.println("port " + port + " open");
            BufferedReader reader = new BufferedReader(
                 new InputStreamReader(socket.getInputStream()));
            String line = reader.readLine();
            if (line != null) {
                System.out.println(line);
            }
            socket.close();
        } catch (SocketTimeoutException ex) {
            // port was open but nothing was read from input stream
            ex.printStackTrace();
        } catch (ConnectException ex) {
            // port is closed
            ex.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null && !socket.isClosed()) {
                try {
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

المشكلة هي أن أحصل على اتصال ConnectionException على حد سواء عند إغلاق المنفذ ولا يمكن الوصول إلى الخادم ولكن مع رسالة استثناء مختلفة:

java.net.connectexception: انتهت مهلة الاتصال: اتصال

عندما لم يتم إنشاء الاتصال و

java.net.connectexception: رفض الاتصال: اتصل

عندما تم إغلاق الميناء

لذلك لا يمكنني التمييز بين حالتي الاستخدام دون الحفر في رسالة الاستثناء الفعلية.

يحدث نفس الشيء عندما أحاول نهجًا مختلفًا لإنشاء المقبس. إذا استخدمت:

socket = new Socket();
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(address, port), 1000);

لدي نفس المشكلة ولكن مع SockettimeOutException بدلاً من ذلك. أحصل على

java.net.sockettimeoutexception: الوقت المخصص للقراءة انتهى

إذا كان الميناء مفتوحًا ولكن لم يكن هناك لافتة للقراءة و

java.net.sockettimeoutexception: ربط مهلة

إذا لم يكن الخادم مباشرًا أو ميناء مغلق.

أيه أفكار؟ شكرا مقدما!

هل كانت مفيدة؟

المحلول

لا أعتقد أن لديك أي خيارات إلى جانب تحليل رسالة الاستثناء. هل هناك سبب أنك لا تفضل القيام بذلك؟

نصائح أخرى

ConnectException يحتوي فقط على مُنشئ فارغ ومُنشئ خاطئ. لا توجد فئات فرعية من ConnectException في API. لذلك أخشى أن جافا لا تفعل طريقة مناسبة للوصول إلى السبب. يبدو أن تحليل رسالة الاستثناء هو الطريقة الوحيدة ، على الرغم من أنها فوضوية حقًا مع الترجمات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top