1

我们正在尝试通过 NIO TCPs SocketChannel 读取大量数据。
代码适用于少量数据(小于 16 KB),但高于第一次,它将 16 KB 读入目标缓冲区,再次尝试读取剩余数据,但给出BUFFER_UNDERFLOW异常。

基于文档

客户端正在从网络中读取部分数据,我们需要强制客户端再次读取。但是,
它没有发生在我们的代码中。我们正在使用以下代码:

  protected ByteBuffer read(SocketChannel socketChannel, SSLEngine engine) throws Exception {
                mPeerNetData.clear();
                int waitToReadMillis = 50;
                boolean exitReadLoop = false;
                while (!exitReadLoop) {
                    int bytesRead = socketChannel.read(mPeerNetData);
                    if (bytesRead > 0) {
                        mPeerNetData.flip();
                        while (mPeerNetData.hasRemaining()) {
                            mPeerAppData.clear();
                            SSLEngineResult result = engine.unwrap(mPeerNetData, mPeerAppData);
                            switch (result.getStatus()) {
                                case OK:
                                    mPeerAppData.flip();
                                    exitReadLoop = true;
                                    break;
                                case BUFFER_OVERFLOW:
                                    mPeerAppData = enlargeApplicationBuffer(engine, mPeerAppData);
                                    break;
                                case BUFFER_UNDERFLOW:
                                    mPeerNetData = handleBufferUnderflow(engine, mPeerNetData);
                                    break;
                                case CLOSED:
                                    closeConnection(socketChannel, engine);
                                    return null;
                                default:
                                    throw new IllegalStateException("Invalid SSL status: " + result.getStatus());
                            }
                        }
                    } else if (bytesRead < 0) {
                        handleEndOfStream(socketChannel, engine);
                        return null;
                    }
                    Thread.sleep(waitToReadMillis);
                }
                return mPeerAppData;
            }

上面的代码参考取自这里

调试代码后,我们得到以下异常

javax.net.ssl.SSLException: Unable to parse TLS packet header
System.err:     at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:792)
com.amg.androidntg6poc W/System.err:     at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:733)
com.amg.androidntg6poc W/System.err:     at org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:698)
2019-09-12 12:21:58.478 5040-6411/com.amg.androidntg6poc W/System.err:     at thrift.transport.sslengine.TTLSClient.read(TTLSClient.java:194)
2019-09-12 12:21:58.485 5040-6449/com.amg.androidntg6poc I/System.out: 2019/09/12 12:21:58
2019-09-12 12:21:58.488 5040-6411/com.amg.androidntg6poc W/System.err:     at thrift.transport.sslengine.TTLSClient.read(TTLSClient.java:168)
2019-09-12 12:21:58.488 5040-6411/com.amg.androidntg6poc W/System.err:     at thrift.transport.TTcpTransport$2.canRead(TTcpTransport.java:721)
2019-09-12 12:21:58.489 5040-6411/com.amg.androidntg6poc W/System.err:     at thrift.TReactor.threadProc(TReactor.java:215)
2019-09-12 12:21:58.489 5040-6451/com.amg.androidntg6poc I/System.out: 2019/09/12 12:21:58
2019-09-12 12:21:58.504 5040-6411/com.amg.androidntg6poc W/System.err:     at thrift.TReactor.access$000(TReactor.java:30)
2019-09-12 12:21:58.504 5040-6411/com.amg.androidntg6poc W/System.err:     at thrift.TReactor$1.run(TReactor.java:105)
2019-09-12 12:21:58.505 5040-6411/com.amg.androidntg6poc W/System.err:     at java.lang.Thread.run(Thread.java:764)
2019-09-12 12:21:58.509 5040-6450/com.amg.androidntg6poc W/System.err: TException(E_TRANSPORT_CLOSED)
2019-09-12 12:21:58.510 5040-6450/com.amg.androidntg6poc W/System.err:     at thrift.TServiceBroker.transportStatusChanged(TServiceBroker.java:548)
2019-09-12 12:21:58.510 5040-6450/com.amg.androidntg6poc W/System.err:     at thrift.transport.TTransport$1.run(TTransport.java:258)
2019-09-12 12:21:58.511 5040-6450/com.amg.androidntg6poc W/System.err:     at thrift.TReactor.threadProc(TReactor.java:148)
2019-09-12 12:21:58.511 5040-6411/com.amg.androidntg6poc D/ThriftGeneralService: connectionStatusChanged() :: 6
2019-09-12 12:21:58.511 5040-6411/com.amg.androidntg6poc D/ThriftGeneralService: client :thrift.transport.TTcpTransport@4608884, state :DISCONNECTED
2019-09-12 12:21:58.511 5040-6450/com.amg.androidntg6poc W/System.err:     at thrift.TReactor.access$000(TReactor.java:30)
2019-09-12 12:21:58.511 5040-6450/com.amg.androidntg6poc W/System.err:     at thrift.TReactor$1.run(TReactor.java:105)
2019-09-12 12:21:58.512 5040-6450/com.amg.androidntg6poc W/System.err:     at java.lang.Thread.run(Thread.java:764)
2019-09-12 12:21:58.513 5040-6450/com.amg.androidntg6poc E/ThriftGeneralService: TException(E_TRANSPORT_CLOSED)
        at thrift.TServiceBroker.transportStatusChanged(TServiceBroker.java:548)
        at thrift.transport.TTransport$1.run(TTransport.java:258)
        at thrift.TReactor.threadProc(TReactor.java:148)
        at thrift.TReactor.access$000(TReactor.java:30)
        at thrift.TReactor$1.run(TReactor.java:105)
        at java.lang.Thread.run(Thread.java:764)

我们使用Conscrypt库来建立与 TCps 服务器的基于 PSK(预共享密钥)的通信,因此使用从 Conscrypt 提供的 pskKeyManagers 初始化的 sslContext。在具有大数据负载的 api 请求期间,我们收到上述错误。

此外,如果我们能获得任何使用 Conscrypt 进行 TLS 读/写通信的示例代码,那将会很有帮助。


在过去的 10 天里,我们一直在头疼。如果有人可以提供帮助,将不胜感激。

4

0 回答 0