java https网络问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5002130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 09:00:32  来源:igfitidea点击:

java https networking issue

java

提问by Mykhaylo Adamovych

I'm trying to implement simplest HTTPS communication program. There are a lot of examples on the web, but I fail to run them successfully.
Here is one example:

我正在尝试实现最简单的 HTTPS 通信程序。网络上有很多示例,但我无法成功运行它们。
这是一个例子:

public class ReadHttpsURL1 {
   static final int HTTPS_PORT = 443; 

   public static void main(String argv[]) throws Exception {
       String url = "www.sun.com";
       System.setProperty("java.net.useSystemProxies", "true");

      SocketFactory factory = SSLSocketFactory.getDefault(); 

      Socket socket = factory.createSocket(url, HTTPS_PORT); 

      BufferedWriter out = new BufferedWriter(new 
            OutputStreamWriter(socket.getOutputStream()));
      BufferedReader in = new BufferedReader(
        new InputStreamReader(socket.getInputStream()));
      out.write("GET / HTTP/1.0\n\n");
      out.flush();

      String line;
      StringBuffer sb = new StringBuffer();
      while((line = in.readLine()) != null) {
         sb.append(line);
      }
      out.close();
      in.close();
      System.out.println(sb.toString());
   }
}

It hangs up for a time about a minute (I believe due to server-side timeout) and fail with error. Hangs up on

它挂断了大约一分钟(我相信是由于服务器端超时)并因错误而失败。挂断

Socket socket = factory.createSocket(url, HTTPS_PORT); 

Error is

错误是

Exception in thread "main" java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(Unknown Source)
    at com.sun.ex1.ReadHttpsURL1.main(ReadHttpsURL1.java:20)

Here is second example:

这是第二个例子:

public class HttpsTest {

    public static void main(String[] args) throws MalformedURLException, IOException {
        System.setProperty("java.net.useSystemProxies", "true");

        URL url = new URL("https://www.sun.com");
        URLConnection con = url.openConnection();
        con.setAllowUserInteraction(true);
        InputStream is = new BufferedInputStream(con.getInputStream());
        for (int b = is.read(); b >= 0; b = is.read()) {
            System.out.write(b);
        }
    }
}

Just throw this exception:

只需抛出此异常:

Exception in thread "main" javax.net.ssl.SSLKeyException: RSA premaster secret error
    at com.sun.net.ssl.internal.ssl.RSAClientKeyExchange.<init>(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at HttpsTest.main(HttpsTest.java:16)
Caused by: java.security.NoSuchAlgorithmException: SunTlsRsaPremasterSecret KeyGenerator not available
    at javax.crypto.KeyGenerator.<init>(DashoA13*..)
    at javax.crypto.KeyGenerator.getInstance(DashoA13*..)
    at com.sun.net.ssl.internal.ssl.JsseJce.getKeyGenerator(Unknown Source)
    ... 14 more

I've read a bit about NoSuchAlgorithmException. This seems to be related with sunjce_provider.jar
I've tried different variants to include this file in the classpath and even make application dependency to this jar (jar was present in classpath for sure)

我已经阅读了一些关于NoSuchAlgorithmException 的内容。这似乎与 sunjce_provider.jar 有关,
我尝试了不同的变体以将该文件包含在类路径中,甚至使应用程序依赖于该 jar(jar 肯定存在于类路径中)

HTTPS URL is live URL. Proxy settings are working (it throws a different connection exception otherwise).
java version "1.6.0_23"

HTTPS URL 是实时 URL。代理设置正在工作(否则会引发不同的连接异常)。
java版本“1.6.0_23”

Are these errors related?
Any ideas how to fix?
Thanks for help!

这些错误是否相关?
任何想法如何解决?
感谢帮助!

采纳答案by Mykhaylo Adamovych

Issue with sockets was caused by proxy. I've wrong concluded if I don't get java.net.ConnectException: Connection refused: connect(in case proxy is not configured at all) proxy should not cause issue. In a 'guest network' (without proxy) application appeared to be working. As it turned out proxy had different configuration for each protocoland my company policy deprecate raw sockets connections.

套接字问题是由代理引起的。如果我没有得到java.net.ConnectException: Connection denied: connect(如果没有配置代理) 代理应该不会导致问题,我就得出了错误的结论。在“访客网络”(无代理)中,应用程序似乎正在运行。事实证明,代理对每个协议都有不同的配置,我的公司政策不赞成原始套接字连接。

回答by Daniel Baktiar

I type the above code on my Eclipse IDE, and it runs well. I think one problem that you may encounter is with your proxy server.

我在我的 Eclipse IDE 上输入了上面的代码,它运行良好。我认为您可能会遇到的一个问题是您的代理服务器

The response was:

回应是:

HTTP/1.1 301 Moved Permanently
Server: Sun-Java-System-Web-Server/7.0
Date: Fri, 25 Feb 2011 11:52:30 GMT
P3p: policyref="http://www.sun.com/p3p/Sun_P3P_Policy.xml", CP="CAO DSP COR CUR ADMa DEVa TAIa PSAa PSDa CONi TELi OUR  SAMi PUBi IND PHY ONL PUR COM NAV INT DEM CNT STA POL PRE GOV"Location: http://www.oracle.com/us/sun
Content-length: 0
Connection: close

What I changed from your code was only this snippet:

我从你的代码中改变的只是这个片段:

System.setProperty("java.net.useSystemProxies", "false");

Just my guess:

只是我的猜测:

  • your network there actually doesn't use proxy but you turned it on, or
  • your proxy doesn't support HTTPS or
  • your proxy HTTPS support for your user is disabled (either intentionally or unintentionally).
  • 你的网络实际上没有使用代理,但你打开了它,或者
  • 您的代理不支持 HTTPS 或
  • 您的用户的代理 HTTPS 支持被禁用(有意或无意)。

was:

曾是:

If you are not intended to write a low level library... How about using [Http Components from Apache][1]?

[1]: http://hc.apache.org/index.html

如果您不打算编写一个低级库...如何使用 [Apache 的 Http 组件][1]?

[1]:http: //hc.apache.org/index.html

回答by David O'Meara

Did you write this code yourself or copy it from somewhere? I only ask because it is not the way I usually make a HTTPS connection. The first thing I'd do when testing HTTPS is find server that will respond to a HTTPS request. www.sun.com will redirect to an Oracle page and while this is still valid it is possibly not what you want.
I can't be 100% sure on the first but I suspect you're suffering from either a blocking read or write. Debugging could help.
The only time I have seen that stack trace was when the JCE classes for Java 5 and 6 were mixed up and the Java version couldn't cope. The same code in HttpsTest "works for me"

这段代码是你自己写的还是从某个地方复制过来的?我只是问,因为这不是我通常建立 HTTPS 连接的方式。测试 HTTPS 时,我要做的第一件事是查找将响应 HTTPS 请求的服务器。www.sun.com 将重定向到 Oracle 页面,虽然这仍然有效,但它可能不是您想要的。
我不能 100% 确定第一次,但我怀疑您正在遭受读取或写入阻塞。调试可能会有所帮助。
我唯一一次看到堆栈跟踪是在 Java 5 和 6 的 JCE 类混淆并且 Java 版本无法应对时。HttpsTest 中的相同代码“对我有用”