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

问题描述 投票:0回答:1

我正在尝试调用 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地址没有成功列入白名单?

java web-services ssl keystore
1个回答
0
投票

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.