我创建了一个 android 应用程序和两个服务器应用程序。
服务器详细信息 带 SSL 的 Tomcat 6。
我的两个服务器都在 HTTPS 上。
在这个应用程序中,我从服务器“A”读取命令并处理它们。一旦处理完成,我需要将它们发送到服务器“B”进行验证,并且需要将完整的报告(连同服务器“B”的响应)发送到服务器“A”回来。
现在,当我运行我的应用程序时,一切似乎都运行良好,但是在大约 160 到 170 个服务器连接之后,它给出了 SSLException: Unable to create application data。
起初我认为这可能与 tomcat 有关,但如果我将服务器转移到 HTTP 上,一切正常。我没有遇到任何问题。
以下是我的服务器通信代码:
public final class ServerCommunicator {
private static final int TIMEOUT = 30000;
public static long counter = 0;
public static String sendToTestTool(String url, String dataToSend) {
String encodedString = null;
counter = counter + 1;
System.out.println("Counter :" + counter);
try {
encodedString = getBase64EncodedString(dataToSend);
return sendToServer(encodedString, url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public static String sendToWSCServer(String dataToSend, String url) {
counter = counter + 1;
System.out.println("Counter :" + counter);
return sendToServer(dataToSend, url);
}
private static String sendToServer(String dataToSend, String url) {
HttpURLConnection connections = null;
try {
URL urls = new URL(url);
if (urls.getProtocol().equals("https")) {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs,
String authType) {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts,
new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
} catch (Exception e) {
}
HttpsURLConnection
.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname,
SSLSession session) {
return true;
}
});
connections = (HttpsURLConnection) urls.openConnection();
} else {
connections = (HttpURLConnection) urls.openConnection();
}
connections.setRequestMethod("POST");
connections.setDoInput(true);
connections.setDoOutput(true);
connections.setConnectTimeout(TIMEOUT);
connections.getOutputStream().write(dataToSend.getBytes());
InputStream inputStream = connections.getInputStream();
String responString = null;
switch (connections.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
long contentLength = connections.getContentLength();
byte[] read = read(inputStream, contentLength);
responString = new String(read);
break;
default:
break;
}
return discardWhitespace(responString);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connections != null) {
connections.disconnect();
connections = null;
}
}
return null;
}
public static byte[] read(InputStream in, long length) throws IOException {
// long length = in.available();
if (length > Integer.MAX_VALUE) {
throw new IOException("File is too large");
}
byte[] bytes = new byte[(int) length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead = in.read(bytes, offset, bytes.length - offset)) != -1) {
offset += numRead;
}
if (offset < bytes.length) {
throw new IOException("Could not completely read file ");
}
in.close();
return bytes;
}
private static String getBase64EncodedString(String sendToServer)
throws UnsupportedEncodingException {
byte[] data = sendToServer.getBytes("UTF-8");
String encodedString = Base64.encodeToString(data, Base64.DEFAULT);
return encodedString;
}
private static String discardWhitespace(String data) {
if (data == null) {
return null;
}
StringBuffer groomedData = new StringBuffer("");
for (int i = 0; i < data.length(); i++) {
switch (data.charAt(i)) {
case (byte) '\n':
case (byte) '\r':
break;
default:
groomedData.append(data.charAt(i));
}
}
return groomedData.toString();
}
}
我所有的通信都在非 UI 单线程上,而且所有通信都是顺序的,这意味着只有一个线程在一个接一个地执行一个通信。