开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜