android - 使用 OkHttp 覆盖 SocketFactory 后的问题

标签 android ssl okhttp

将我的应用程序更新到 api 21 后,我遇到了 https 请求的问题。经过深入的代码审查后,我发现了一个有趣的错误。

我的应用程序现在已经用 api-21 编译了,这个 api 在 sdk 中有一个新版本的 okHttp,版本 2.2.0。旧版本应用使用okHttp 2.0.0版本。

在 2.2.0 版本中,当我尝试打开一个新的 https 请求时出现异常。异常(exception)情况是:

java.net.SocketException: Unconnected sockets not implemented
        at javax.net.SocketFactory.createSocket(SocketFactory.java:64)
        at com.squareup.okhttp.Connection.connect(Connection.java:144)
        at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:169)
        at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:119)
        at com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:134)
        at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:314)
        at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:237)
        at com.squareup.okhttp.Call.getResponse(Call.java:233)
        at com.squareup.okhttp.Call.execute(Call.java:84) 

问题是 okHttp 改变了 Connection 类在 2.1.0 版本上的工作方式。在版本 2.0.0 上,连接直接创建一个新的普通套接字,但知道向套接字工厂请求此套接字,此套接字将升级为 TLS。变化是:

socket = route.address.socketFactory.createSocket();

我的问题是我已经为 NotHttpSocketFactory 覆盖了 socketFactory,并且这个实现什么都不做(没关系,你想删除 http 连接)并且方法 createSocket() 没有被覆盖。我不喜欢允许 http 请求。

我覆盖了 SocketFactory。

client.setSocketFactory(new BlackphoneStubSocketFactory());

我不明白为什么我需要一个普通的套接字,因为我正在创建一个 https 请求。这是必要的吗?我可以覆盖方法 createSocket() 并返回一个空套接字,但这是必要的,否则它是 OkHttp 上的错误。

最佳答案

确保您在自定义工厂上定义了 createSocket()。

val httpClient = OkHttpClient.Builder()
    .connectTimeout(5, TimeUnit.SECONDS)
    .retryOnConnectionFailure(false)
    .socketFactory(object: SocketFactory() {
        val factory = SocketFactory.getDefault()

        override fun createSocket(): Socket {
            return wrap(factory.createSocket())
        }

        override fun createSocket(p0: String?, p1: Int): Socket {
            return wrap(factory.createSocket(p0, p1))
        }

        override fun createSocket(p0: InetAddress?, p1: Int): Socket {
            return wrap(factory.createSocket(p0, p1))
        }

        override fun createSocket(p0: String?, p1: Int, p2: InetAddress?, p3: Int): Socket {
            return wrap(factory.createSocket(p0, p1, p2, p3))
        }

        override fun createSocket(p0: InetAddress?, p1: Int, p2: InetAddress?, p3: Int): Socket {
            return wrap(factory.createSocket(p0, p1, p2, p3))
        }

        private fun wrap(s: Socket): Socket {
            s.receiveBufferSize = 32*1024*1024
            return s
        }
    })
    .build()

关于android - 使用 OkHttp 覆盖 SocketFactory 后的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27947506/

相关文章:

java - 使用全屏按钮在下一个 Activity 中播放视频

Android TranslationAnimation 无法正常工作

dom - SoundCloud iframe 嵌入产生 IndexSizeError

c# - 使用 POP3 连接到 SSL

java - OkHttp 反向 Http

Android - OkHttp - 使用 TrafficStats 标记所有网络请求

java - Android Room 数据库文件在数据库浏览器中的文件格式无效

c++ - 使用大型源代码文件的 IDE 建议

Python 请求 : load SSL certificate from database

android - 如何指定 Get-Request 编码(Retrofit + OkHttp)