我使用SSLEngine
而不是Java NIO
解锁服务器套接字来处理连接。我能够成功握手客户端并将小记录集传递给服务器。但是,当我尝试将文件传输到服务器text/binary
时,我收到以下错误:
javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
at sun.security.ssl.InputRecord.checkRecordVersion(InputRecord.java:552)
at sun.security.ssl.EngineInputRecord.bytesInCompletePacket(EngineInputRecord.java:113)
at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:862)
at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:775)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
at ncp.io.network.tls.TLSWrapper.unwrap(TLSWrapper.java:170)
at ncp.io.network.tls.TLSIO.decodeData(TLSIO.java:110)
at ncp.io.network.tls.TLSIO.handleRead(TLSIO.java:71)
at ncp.io.network.SocketThread.run(SocketThread.java:137)
但我无法找出导致此错误的原因。
以下是我的代码段
@Override
public int handleRead(ByteBuffer temp) {
int read = opsManager.handleRead(temp);
if (read > 0) {
try {
tlsDecodeBuffer = decodeData(temp);
try {
temp.clear();
temp.put(tlsDecodeBuffer);
}catch (BufferOverflowException e){
temp = ByteBuffer.allocateDirect(tlsDecodeBuffer.remaining());
temp.put(tlsDecodeBuffer);
}
temp.flip();
temp.rewind();
if(tlsDecodeBuffer.hasRemaining())
tlsDecodeBuffer.compact();
else
tlsDecodeBuffer.clear();
}catch (SSLException e){
// Error occurs here:
e.printStackTrace();
log.warning("Insecure connection attempted/ SSL failure for:" + e.getMessage());
opsManager.close();
}
catch (IOException e) {
e.printStackTrace();
}
return read;
} else {
return -1;
}
}
private ByteBuffer decodeData(ByteBuffer input) throws IOException {
ncp.io.network.tls.TLSStatus stat = null;
boolean continueLoop = true;
do {
tlsDecodeBuffer = wrapper.unwrap(input, tlsDecodeBuffer);
switch (wrapper.getStatus()) {
case NEED_WRITE:
writeBuff(ByteBuffer.allocate(0));
break;
case UNDERFLOW:
if (tlsDecodeBuffer.capacity() == tlsDecodeBuffer.remaining()) {
throw new BufferUnderflowException();
} else {
input.compact();
continueLoop = false;
}
break;
case CLOSED:
if (log.isLoggable(Level.FINER)) {
log.finer("TLS Socket closed..." + toString());
}
throw new EOFException("Socket has been closed.");
default:
break;
}
stat = wrapper.getStatus();
} while (continueLoop && ((stat == TLSStatus.NEED_READ) || (stat == TLSStatus.OK))
&& input.hasRemaining());
if (continueLoop) {
if (input.hasRemaining()) {
input.rewind();
} else {
input.clear();
}
}
tlsDecodeBuffer.flip();
return tlsDecodeBuffer;
}
答案 0 :(得分:0)
您的代码没有意义。
当您在BufferOverflowException
中获得unwrap()
时,需要通过flip()/get()/compact().
当您在BufferOverflowException
中获得wrap()
时,您需要通过flip()/write()/compact(),
转到网络的write()
清空目标缓冲区。
在任何情况下都没有任何意义来分配新的缓冲区等。
rewind()
flip()
在任何情况下都没有意义。
这里有很多关于如何正确使用SSLEngine
的帖子和答案。我建议你仔细阅读。