i有一个Android客户端应用程序和一个普通的Java服务器,都带有SSL加密。在服务器端,我设置了SSLServerSockets,一个用于数据,另一个用于向客户端或其他方式进行特殊的异步说明。这是设置SSLServerSocket的代码:
sslserversocket设置:
Security.addProvider(new Provider());
System.setProperty("javax.net.ssl.keyStore", GlobalVariables.KEYSTORE_PATH);
System.setProperty("javax.net.ssl.keyStorePassword", Server.KEY_STORE_PW);
sslServerSocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
// Enable debugging to view the handshake and communication which happens between the SSLClient and the SSLServer
System.setProperty("javax.net.debug", "all");
try
{
serverDataSocket = (SSLServerSocket) sslServerSocketfactory.createServerSocket(Server.SERVER_DATA_PORT);
serverStatusSocket = (SSLServerSocket) sslServerSocketfactory.createServerSocket(Server.SERVER_STATUS_PORT);
waitForClients();
}
catch (IOException e)
{
Log.error(ServerAgent.class, "Establishing ServerSocket was not successful.", e);
}
之后,我等待客户在WaitforClients()方法中连接您:
while (serverModel.isServerRunning())
{
try
{
clientDataSocket = (SSLSocket) serverDataSocket.accept();
clientStatusSocket = (SSLSocket) serverStatusSocket.accept();
new Thread(new Runnable()
{
@Override
public void run()
{
Client client = new Client(clientDataSocket, clientStatusSocket, iliasSoapClient, serverModel.getTimeoutServer());
if (client.manageHandshake())
{
serverModel.addClient(client);
}
}
}).start();
}
catch (SocketException e)
{
Log.warn(ServerAgent.class, "Close was invoked by an external method, so now the server is shutting down...", e);
}
catch (IOException e)
{
Log.error(ServerAgent.class, "Can not get the Socket from the ServerSocket.", e);
}
}
在客户端我首先连接到ServerDataSocket,然后使用此代码连接到ServerStatussocket:
public boolean connect()
{
try
{
dataServerSocket = (SSLSocket)sslSocketFactory.createSocket();
dataServerSocket.setSoTimeout(10000);
dataServerSocket.connect(new InetSocketAddress(Server.SERVER_IP, Server.SERVER_DATA_PORT), 10000);
dataInput = new Scanner(dataServerSocket.getInputStream());
dataOutput = new PrintWriter(dataServerSocket.getOutputStream(), true);
}
catch (UnknownHostException e)
{
Log.e(Client.class.getName(), "Cannot connect to host with IP: " + Server.SERVER_IP + " under data port: " + Server.SERVER_DATA_PORT + ".", e);
return false;
}
catch (IOException e)
{
Log.e(Client.class.getName(), "Common IOException: Cannot connect to host with IP: " + Server.SERVER_IP + " under data port: "
+ Server.SERVER_DATA_PORT + ".", e);
return false;
}
try
{
statusServerSocket = (SSLSocket)sslSocketFactory.createSocket();
statusServerSocket.setSoTimeout(10000);
statusServerSocket.connect(new InetSocketAddress(Server.SERVER_IP, Server.SERVER_STATUS_PORT), 10000);
statusInput = new Scanner(statusServerSocket.getInputStream());
statusOutput = new PrintWriter(statusServerSocket.getOutputStream(), true);
return true;
}
catch (UnknownHostException e)
{
Log.e(Client.class.getName(), "Cannot connect to host with IP: " + Server.SERVER_IP + " under status port: " + Server.SERVER_STATUS_PORT + ".", e);
return false;
}
catch (IOException e)
{
Log.e(Client.class.getName(), "Common IOException: Cannot connect to host with IP: " + Server.SERVER_IP + " under status port: "
+ Server.SERVER_STATUS_PORT + ".", e);
return false;
}
}
如果我尝试从服务器中检索InputStream作为客户端,请获得以下例外。不知道为什么:
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): Common IOException: Cannot connect to host with IP: 192.168.0.6 under data port: 51234.
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): java.net.SocketTimeoutException: SSL handshake timed out
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:398)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.<init>(OpenSSLSocketImpl.java:658)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:629)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at de.hska.ilias.app.client.Client.connect(Client.java:64)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at de.hska.ilias.app.client.LoginTask.doInBackground(LoginTask.java:82)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at de.hska.ilias.app.client.LoginTask.doInBackground(LoginTask.java:1)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-04 22:34:07.130: E/de.hska.ilias.app.client.Client(29098): at java.lang.Thread.run(Thread.java:841)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): Common IOException: Cannot connect to host with IP: 192.168.0.6 under data port: 51234.
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): java.net.SocketTimeoutException: SSL handshake timed out
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:398)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.<init>(OpenSSLSocketImpl.java:658)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:629)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at de.hska.ilias.app.client.Client.connectLocally(Client.java:109)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at de.hska.ilias.app.client.LoginTask.doInBackground(LoginTask.java:93)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at de.hska.ilias.app.client.LoginTask.doInBackground(LoginTask.java:1)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-04 22:34:17.200: E/de.hska.ilias.app.client.Client(29098): at java.lang.Thread.run(Thread.java:841)
SSL握手时机。您必须查看服务器日志,以了解为什么可能在Javax.net.debug = SSL,握手输出。您已经将阅读超时设置为十秒钟,无论如何都相当短,但尤其是握手。我会先致电startHandshake()
,然后拨打setSoTimeout(),
和/或使用更长的超时进行握手。
但是除非该服务器仅用于服务一个客户端,否则整个策略都是有风险的。如果两个客户同时连接,则您有危险将连接从第二个客户端将连接视为第一个客户的第二个连接,反之亦然。