我想在 Android 设备上有一个 SSL 加密的 TCP 服务器,在计算机上有一个客户端连接到该设备。
我在 Android 设备上使用自己的 keystore 创建了一个 SSLServerSocket。
final KeyStore localTrustStore = KeyStore.getInstance("BKS"); //NON-NLS
final InputStream in = context.getResources().openRawResource(R.raw.syncapp);
localTrustStore.load(in, "secret".toCharArray()); //Keystore pw
in.close();
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); //NON-NLS
final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(localTrustStore);
final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(localTrustStore, "secret".toCharArray()); //privat key pw
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
serverSocket = sslContext.getServerSocketFactory().createServerSocket(SERVER_PORT);
((SSLServerSocket) serverSocket).setNeedClientAuth(true);
然后我等待客户端连接。当客户端想要连接时,一个新线程被启动并且流被请求:
final DataInputStream input = new DataInputStream(this.clientSocket.getInputStream());
final DataOutputStream output = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
首先,我将此代码与 USB 网络共享一起使用,以在计算机和 Android 设备之间建立连接。所以没有启用 Wifi/网络。一切都很完美。
然后我激活了android设备上的wifi并连接到没有互联网的wlan。 但是现在调用 getInputStream() 似乎需要 5 到 10 秒。 如果我停用 SSL,它会完美运行。 如果 wlan 确实连接到互联网,也没有延迟。 我用 Android 4.2 和 5.1 测试了这个。 更新:现在我可以用 Android 6 测试这个问题。这个问题似乎已经解决了......
握手已正确完成,但此后在 Android 设备上似乎存在某种延迟。 (对 getInputStream 的调用消耗了那个时间) 一些开发人员说它会进行 DNS 反向查找,这会遇到超时。
看一下捕获,第一个连接是在禁用 wifi 时建立的。进行数据传输需要 0.3 秒。然后我只是激活了 wifi,我没有通过 wifi 连接,它仍然通过 usb 通信。它花了 5 多秒。
我在这里也发现了这个问题,但他们使用的是客户端套接字。我需要一个服务器套接字。有谁知道如何解决这个问题?
最佳答案
您是对的,反向 DNS 查找超时。在某些 Java 运行时环境中,在与原始 IP 地址握手期间,SSLContext 不必要地执行服务器 IP 地址的查找。这是为了确定服务器证书的通用名称是否匹配。尝试使用此处提到的解决方案之一:
关于java - 当 android 设备处于 wifi 时,SSLSocket 在 getInputStream 处挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37717585/