我的简单java HTTPS服务器仅适用于localhost

我有一个用Java实现的简单HTTPS测试服务器,如下所示。 它接受客户端连接并发回一段有关套接字的文本。 问题是它使用https://localhost:8888在浏览器上本地工作,但是当我使用我的机器的真实IP(129.46.xx.xx:8888)时,它不适用于远程浏览器。 问题来自哪里? 测试时,不要忘记生成样本证书并提供以下信息。

编辑 :有趣的是,当我在Ubuntu 12.04上运行它时,我可以连接到它。 但不是在Windows上运行时!

 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSocket; public class HttpsEchoer { public static void main(String[] args) { String ksName = "myks.jks"; char ksPass[] = "mypass".toCharArray(); char ctPass[] = "mypass".toCharArray(); try { KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(ksName), ksPass); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, ctPass); SSLContext sc = SSLContext.getInstance("TLS"); sc.init(kmf.getKeyManagers(), null, null); SSLServerSocketFactory ssf = sc.getServerSocketFactory(); SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(8888); System.out.println("Server started:"); printServerSocketInfo(s); // Listening to the port int count = 0; while (true) { SSLSocket c = (SSLSocket) s.accept(); // Someone is calling this server count++; System.out.println("Connection #: "+count); printSocketInfo(c); BufferedWriter w = new BufferedWriter( new OutputStreamWriter(c.getOutputStream())); BufferedReader r = new BufferedReader( new InputStreamReader(c.getInputStream())); String m = r.readLine(); // System.out.println(m); if (m!=null) { // We have a real data connection w.write("HTTP/1.1 200 OK"); w.newLine(); w.write("Content-Type: text/html"); w.newLine(); w.newLine(); w.write("
"); w.newLine(); w.write("Connection #: "+count); w.newLine(); w.newLine(); w.write(m); w.newLine(); while ((m=r.readLine())!= null) { if (m.length()==0) break; // End of a GET call w.write(m); w.newLine(); } w.write("

"); w.newLine(); w.flush(); } w.close(); r.close(); c.close(); } } catch (Exception e) { e.printStackTrace(); } } private static void printSocketInfo(SSLSocket s) { System.out.println("Server socket class: "+s.getClass()); System.out.println(" Remote address = " +s.getInetAddress().toString()); System.out.println(" Remote port = " +s.getPort()); System.out.println(" Local socket address = " +s.getLocalSocketAddress().toString()); System.out.println(" Local address = " +s.getLocalAddress().toString()); System.out.println(" Local port = " +s.getLocalPort()); } private static void printServerSocketInfo(SSLServerSocket s) { System.out.println("Server socket class: "+s.getClass()); System.out.println(" Socker address = " +s.getInetAddress().toString()); System.out.println(" Socker port = " +s.getLocalPort()); System.out.println(" Need client authentication = " +s.getNeedClientAuth()); System.out.println(" Want client authentication = " +s.getWantClientAuth()); System.out.println(" Use client mode = " +s.getUseClientMode()); } }

这是printServerSocketInfo()方法显示的内容:

 Server started: Server socket class: class sun.security.ssl.SSLServerSocketImpl Socker address = 0.0.0.0/0.0.0.0 Socker port = 8888 Need client authentication = false Want client authentication = false Use client mode = false 

这是本地浏览器显示的内容:

 Connection #: 3 GET / HTTP/1.1 Host: localhost:8888 Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36 OPR/22.0.1471.50 (Edition Campaign 38) Accept-Encoding: gzip,deflate,lzma,sdch Accept-Language: en-US,en;q=0.8 

尝试像这样创建服务器套接字:

 SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(8888, 0, null); 

作为最后一个参数的null应该告诉服务器套接字工厂创建一个绑定到所有网络接口的套接字。

这是该方法特定版本的javadoc链接 。