Unable to make socket non blocking
guys. I want make my application support https connection. My HttpClient code as follow:
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_0);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, true);
HttpConnectionParams.setConnectionTimeout(params, SO_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT);
HttpConnectionParams.setSocketBufferSize(params, DEFAULT_BUFFER_SIZE);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), HTTP_PORT));
schReg.register(new Scheme("https", new CustomSSLSocketFactory(),
HTTPS_PORT));
ClientConnectionManager connMgr = new ThreadSafeClientConnManager(params, schReg);
PersistentCookieStore store = new PersistentCookieStore();
store.clearExpired(new Date());
client = new DefaultHttpClient(connMgr, params);
client.setCookieStore(store);
client.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(HttpRequest request, HttpContext context) {
// Add header to accept gzip content
if (!request.containsHeader(HEADER_ACCEPT_ENCODING)) {
request.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
}
}
});
client.addResponseInterceptor(new HttpResponseInterceptor() {
public void process(HttpResponse response, HttpContext context) {
// Inflate any responses compressed with gzip
final HttpEntity entity = response.getEntity();
if(entity != null){
final Header encoding = entity.getContentEncoding();
if (encoding != null) {
for (HeaderElement element : encoding.getElements()) {
if (element.getName().equalsIgnoreCase(ENCODING_GZIP)) {
response.setEntity(new InflatingEntity(response
.getEntity()));
break;
}
}
}
}
}
});
requests = new ArrayList<HttpUriRequest>();
}*
but it will occur an exception in logcat :
*12-20 07:42:41.895: DEBUG/com.ceosoft.alumlife.http.HttpClient(504): GET https://174.129.95.184:8443/AlumniFinderServer/ws/event/all
12-20 07:42:42.125: WARN/SingleClientConnManager(504): Invalid use of SingleClientConnManager: connection still allocated.
12-20 07:42:42.125: WARN/SingleClientConnManager(504): Make sure to release the connection before allocating another one.
12-20 07:42:42.134: WARN/SingleClientConnManager(504): Invalid use of SingleClientConnManager: connection still allocated.
12-20 07:42:42.134: WARN/SingleClientConnManager(504): Make sure to release the connection before allocating another one.
12-20 07:42:42.144: INFO/System.out(504): cookies == None
12-20 07:42:42.164: WARN/SingleClientConnManager(504): Invalid use of SingleClientConnManager: connecti开发者_运维技巧on still allocated.
12-20 07:42:42.164: WARN/SingleClientConnManager(504): Make sure to release the connection before allocating another one.
12-20 07:42:42.239: WARN/SingleClientConnManager(504): Invalid use of SingleClientConnManager: connection still allocated.
12-20 07:42:42.239: WARN/SingleClientConnManager(504): Make sure to release the connection before allocating another one.
12-20 07:42:54.734: INFO/System.out(504): IOException e
java.io.IOException: Unable to make socket non blocking
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeconnect(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:316)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.<init>(OpenSSLSocketImpl.java:520)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:461)
at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:93)
at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:171)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.ceosoft.alumlife.http.HttpClient.getResponse(HttpClient.java:440)
at com.ceosoft.alumlife.http.HttpClient.getPublicData(HttpClient.java:317)
at com.ceosoft.alumlife.http.Client.getEventList(Client.java:423)
at com.ceosoft.alumlife.data.manager.DataManager$8.launch(DataManager.java:330)
at com.ceosoft.alumlife.data.DataTask.doInBackground(DataTask.java:93)
at com.ceosoft.alumlife.data.DataTask.doInBackground(DataTask.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1096)*
_------------------------------------------------------------ CustomSSLSocketFactory.java :
import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager;
import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.scheme.LayeredSocketFactory; import org.apache.http.conn.scheme.SocketFactory; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams;
/** * Factory for create ssl socket and accept self * certificate */ public class CustomSSLSocketFactory implements SocketFactory, LayeredSocketFactory {
private static final String SSL_PROTOCOL_NAME = "TLS";
private SSLContext sslContext = null;
/**
* Creates a new CustomSSLSocket object.
*
* @return the SSL context
* @throws NoSuchAlgorithmException
* the no such algorithm exception
* @throws KeyManagementException
* the key management exception
* @throws KeyStoreException
* the key store exception
*/
private static SSLContext createSSLContext() throws
NoSuchAlgorithmException,
KeyManagementException,
KeyStoreException {
SSLContext context = SSLContext.getInstance(SSL_PROTOCOL_NAME);
context.init(null, new TrustManager[] { new MyTrustManager() }, null);
//context.init(null, new TrustManager[] { new CustomX509TrustManager(null) }, new SecureRandom());
return context;
}
/**
* Gets the SSL context. Create new context and handle exceptions.
*
* @return the sSL context
* @throws IOException
* Signals that an I/O exception has occurred.
*/
private SSLContext getSSLContext() throws IOException {
if (sslContext == null) {
try {
sslContext = createSSLContext();
} catch (KeyManagementException e) {
throw new IOException(e.getLocalizedMessage());
} catch (NoSuchAlgorithmException e) {
throw new IOException(e.getLocalizedMessage());
} catch (KeyStoreException e) {
throw new IOException(e.getLocalizedMessage());
}
}
return sslContext;
}
/* (non-Javadoc)
* @see org.apache.http.conn.scheme.SocketFactory#createSocket()
*/
public Socket createSocket() throws IOException {
return getSSLContext().getSocketFactory().createSocket();
}
/* (non-Javadoc)
* @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
*/
public boolean isSecure(Socket socket) throws IllegalArgumentException {
return true;
}
/* (non-Javadoc)
* @see org.apache.http.conn.scheme.LayeredSocketFactory#
* createSocket(java.net.Socket, java.lang.String, int, boolean)
*/
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket();
}
/* (non-Javadoc)
* @see org.apache.http.conn.scheme.SocketFactory#
* connectSocket(java.net.Socket, java.lang.String, int,
* java.net.InetAddress, int, org.apache.http.params.HttpParams)
*/
@Override
public Socket connectSocket(Socket socket, String reqHost, int reqPort,
InetAddress arg3, int arg4, HttpParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
int soTimeout = HttpConnectionParams.getSoTimeout(params);
InetSocketAddress remoteAddress = new InetSocketAddress(reqHost, reqPort);
SSLSocket sslSocket = null;
if (socket != null) {
sslSocket = (SSLSocket) socket;
} else {
sslSocket = (SSLSocket) createSocket();
}
InetSocketAddress inetSocketAddress = new InetSocketAddress(arg3, arg4);
sslSocket.bind(inetSocketAddress);
sslSocket.connect(remoteAddress, connTimeout);
sslSocket.setSoTimeout(soTimeout);
return sslSocket;
}
}
import java.security.cert.CertificateException; import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/** * * @file MyTrustManager.java * @author Samuel.Cai * @date 2010-12-21 */ public class MyTrustManager implements X509TrustManager{
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
}
When I make a independent demo use these code. (less code and remove irrelevant code ,may lead to some very valuable information)
The real valuable information as follows:
12-23 01:19:38.618: ERROR/NativeCrypto(265): Unknown error 5 during connect java.io.IOException: SSL handshake failure: I/O error during system call, Broken pipe at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeconnect(Native Method) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:316) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.(OpenSSLSocketImpl.java:520) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:461) at org.apache.http.impl.io.SocketInputBuffer.(SocketInputBuffer.java:93) at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83) at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170) at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106) at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:171) at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) at info.iamkebo.demo.Demo.GetHttps(Demo.java:75) at info.iamkebo.demo.Demo.onCreate(Demo.java:40) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) at android.app.ActivityThread.access$2300(ActivityThread.java:125) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
Then I get the solution from :
Custom SSL handling stopped working on Android 2.2 FroYo
Thanks Eric again.
精彩评论