2015-01-16 121 views
0

我使用的是SSLEngine而不是Java NIO解除阻塞服務器套接字來處理連接。我能夠成功握手客戶端並將小記錄集傳遞給服務器。然而,當我嘗試將文件傳輸到服務器text/binary我收到以下錯誤:JAVA SSLENGINE:不支持的記錄版本Unknown-0.0試圖用SSLEngine解開bytebuffer記錄

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

請檢查此鏈接:http://stackoverflow.com/questions/26166121/unsupported-record-version-sslv2hello-using-closeablehttpclient這將幫助你。 –

回答

0

您的代碼是沒有意義的。

  1. 當你得到一個BufferOverflowExceptionunwrap(),你需要通過flip()/get()/compact().

  2. 清空目標緩衝區當你在wrap()一個BufferOverflowException,你需要通過flip()/write()/compact(),清空目標緩衝區,其中write()去到網絡。

    在兩種情況下它任何意義,分配一個新的緩衝區等

  3. rewind()flip()後沒有開始道理在任何情況下。

在這裏有很多關於如何正確使用SSLEngine的帖子和答案。我建議你仔細閱讀。