Я разрабатываю приложение для Android, которое использует SSLSocket для подключения к серверу. Это код, который я использую:
// Connect
if (socket == null || socket.isClosed() || !socket.isConnected()) {
if (socket != null && !socket.isClosed())
socket.close();
Log.i(getClass().toString(), "Connecting...");
if (sslContext == null) {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new SecureRandom());
}
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
socket = (SSLSocket)socketFactory.createSocket(host, port);
socket.setSoTimeout(20000);
socket.setUseClientMode(true);
connected = true;
Log.i(getClass().toString(), "Connected.");
}
// Secure
if (connected) {
Log.i(getClass().toString(), "Securing...");
SSLSession session = socket.getSession();
secured = session.isValid();
if (secured) {
Log.i(getClass().toString(), "Secured.");
}
else
Log.i(getClass().toString(), "Securing failed.");
}
Проблема в том, что для установления связи TLS в следующей строке требуется около 5 секунд или больше событий:
SSLSession session = socket.getSession();
Я сделал подобное приложение для iPhone, рукопожатие там занимает всего 1 секунду, поэтому я думаю, что проблема не в сервере, к которому я подключаюсь, а, возможно, в приведенном выше коде. Само соединение достаточно быстрое, просто рукопожатие TLS медленное.
Кто-нибудь знает, нормально ли это в Android или нет, как сделать это быстрее?
Спасибо.
ИЗДАНО 21.01.11:
Я обнаружил, что рукопожатие происходит быстро, когда я подключаюсь к другому серверу, например paypal.com: 443 .
Но я раньше подключался к другому серверу - службе .NET, написанной мной. Как я уже говорил ранее, я не думал, что проблема была в том сервере, потому что, если я подключаюсь к нему с помощью приложения для iPhone, рукопожатие происходит быстро. Теперь я не знаю, почему это быстро на iPhone и медленно на Android. После того, как соединение установлено, единственное, что я делаю на сервере .NET:
Console.WriteLine("New client connected.");
this.sslStream = new SslStream(tcpClient.GetStream(), true);
this.sslStream.ReadTimeout = 15000;
this.sslStream.WriteTimeout = 15000;
Console.WriteLine("Beginning TLS handshake...");
this.sslStream.AuthenticateAsServer(connection.ServerCertificate, false, SslProtocols.Tls, false);
Console.WriteLine("TLS handshake completed.");