我们正在尝试通过 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 天里,我们一直在头疼。如果有人可以提供帮助,将不胜感激。