“java.net.SocketTimeoutException:连接超时”我的客户端无法调用 Web 服务

我正在尝试调用 Web 服务并向其发送一些 xml 数据。托管 Web 服务的公司向我提供了证书,我已将它们导入我的密钥库,并且还在我的代码中设置了密钥库。

该公司表示我的 IP 已列入白名单,并且他们的服务器已启动并正在运行,但我不断收到此异常:

17:18:00,255 ERROR [stderr] (DefaultQuartzScheduler_Worker-1) java.net.SocketTimeoutException: connect timed out
17:18:00,255 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.PlainSocketImpl.socketConnect(Native Method)
17:18:00,256 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
17:18:00,256 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
17:18:00,257 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
17:18:00,257 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
17:18:00,258 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.Socket.connect(Socket.java:579)
17:18:00,258 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:618)
17:18:00,258 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
17:18:00,259 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)
17:18:00,259 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)
17:18:00,259 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:275)
17:18:00,260 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:371)
17:18:00,260 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)
17:18:00,260 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:932)
17:18:00,261 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
17:18:00,261 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
17:18:00,261 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
17:18:00,262 ERROR [stderr] (DefaultQuartzScheduler_Worker-1)   at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:

这是我使用的一些代码:

   //Start connection
    URL url = new URL(address);
    HttpURLConnection con  = (HttpURLConnection) url.openConnection();

    //Set HTTP header properties
    con.setConnectTimeout(60000);   
    con.setRequestMethod("POST");
    con.setUseCaches(true);
    con.setRequestProperty("Content-type", "text/xml");
    con.setRequestProperty("Content-Length", Integer.toString(xml.length()));
    con.setRequestProperty("SOAPAction", address);
    con.setDoOutput(true);
    con.setDoInput(true);

    userPass = username + ":" + password;
    byte[] encodeBytes = Base64.encodeBase64(userPass.getBytes());
    String encode = new String(encodeBytes);
    con.setRequestProperty("Authorization", "Basic " + encode);

    //Set up HTTPS
    HttpsURLConnection httpsConnection = (HttpsURLConnection) con;
    try {
        SSLContext context = SSLContext.getInstance("TLS");
        KeyManagerFactory kmFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        KeyStore kStore = KeyStore.getInstance("JKS");
        FileInputStream fis = new FileInputStream(new File(ERPGetProperty.erpGetProperty("pathToKeyStore")));
        TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        try {
            kStore.load(fis, keyStorePass);
            kmFactory.init(kStore, keyStorePass);
            tmFactory.init(kStore);

            context.init(kmFactory.getKeyManagers(), tmFactory.getTrustManagers(), new SecureRandom());
            httpsConnection.setSSLSocketFactory(context.getSocketFactory());
            httpsConnection.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }

            });

        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            fis.close();
        }

    } catch(Exception e) {
        e.printStackTrace();
    }

    out = httpsConnection.getOutputStream();

这可能是我端或托管 Web 服务的服务器的问题吗?我有一个快速的互联网连接,也没有运行任何防火墙。拜托,我真的需要帮助,我已经被这个问题困扰了将近一个星期。

更新:我使用 openssl 客户端来测试主机

openssl s_client -connect <ip>:port (where ip is the IP address of the host im trying to reach)

我从终端得到这个输出:

连接:操作超时连接:errno = 60

但是,使用他们测试环境的IP地址,我可以与他们通信,openssl可以显示他们的证书链,所以连接成功。生产 IP 地址是我似乎遇到的问题。

UPDATE_2:使用带有 -P0 标志的 nmap 来测试主机服务器的端口 80 和 443,它们似乎都被过滤了。这是否意味着我的 IP 地址未成功列入白名单?

stack overflow "java.net.SocketTimeoutException: connect timed out" My client is not able to invoke web service
原文答案

答案:

作者头像

您收到的信息非常模糊。您可以假设主机在那里并且还活着,但它没有响应。您已经完成了足够的简单连接,但还需要更多。如果是身份验证问题,它通常会给出警告/错误,但并非总是如此。我的猜测?错误/错误的连接/协议。

端口或主机/IP 不是您认为的或应该的,或者(更有可能),存在防火墙或其他此类问题(代理)。

我还看到与 Google 和其他服务器通信的此类问题。如果您没有使用正确的协议,他们可能不会响应。他们可能正在等待您的某些信息。基本上,我说嗨,你说“我能帮你什么?你是谁?”然后我做出回应并提出请求。我没有深入研究您的代码,但这是我的经验。希望能帮助到你。

这是我遇到的那种东西的一个很好的参考。也许它比您的代码更手动,但对我来说效果很好。 http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/

最后一点建议,检查所有抛出的异常。如果您没有得到这些,请假设情况并非如此,并缩小问题范围。也检查所有的 Http 错误代码。例如,“找不到主机”和“禁止”是您没有得到的两个错误。您应该能够从 Http 套接字事务中获取错误代码。