2012-11-04 22 views
0

我試圖通過Weberknecht Java library連接到WebSocket。當Java客戶端試圖建立連接,我收到以下錯誤信息:通過Weberknecht連接到WebSocket時發生ArrayIndexOutOfBoundsException

W/System.err(805): java.lang.ArrayIndexOutOfBoundsException: length=1000; index=1000 
W/System.err(805): at ...WebSocketConnection.connect(WebSocketConnection.java:86) 

這是導致問題的一部分:

public void connect() throws WebSocketException { 
    try { 
     if (connected) { 
      throw new WebSocketException("already connected"); 
     } 

     socket = createSocket(); 
     input = new DataInputStream(socket.getInputStream()); 
     output = new PrintStream(socket.getOutputStream()); 

     output.write(handshake.getHandshake()); 

     boolean handshakeComplete = false; 
     int len = 10000; 
     byte[] buffer = new byte[len]; 
     int pos = 0; 
     ArrayList<String> handshakeLines = new ArrayList<String>(); 

     while (!handshakeComplete) { 
      int b = input.read(); 
      buffer[pos] = (byte) b; // THIS LINE CAUSES THE EXCEPTION 
      pos += 1; 

      if (buffer[pos - 1] == 0x0A && buffer[pos - 2] == 0x0D) { 
       String line = new String(buffer, "UTF-8"); 
       if (line.trim().equals("")) { 
        handshakeComplete = true; 
       } else { 
        handshakeLines.add(line.trim()); 
       } 

       buffer = new byte[len]; 
       pos = 0; 
      } 
     } 

什麼會導致這個問題?這個客戶端庫是否可能不符合服務器使用的WebSocket版本?

issue over there at Weberknecht尚未解決。我想問這個問題,因爲它似乎是一個相當普遍的問題(閱讀WebSocket標題和握手數據)。

+0

告訴我,在第86行 – RajeshVijayakumar

+0

聲明它是'緩衝液[POS] =(字節)B;'視標中的代碼。 – caw

+1

您應該知道這個庫存在安全問題。請參閱:http://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf – leggetter

回答

1

代碼需要檢查input.read()中的-1以表示連接打到EOF。

此外,我會假設基於相同的代碼位,如果握手尚未達到10000字節後,它是一個無效的握手。

while (!handshakeComplete) { 
      int b = input.read(); 

      if (b == -1) 
       throw new WebSocketException ("Connected closed.");     

      if (pos == buffer.length) 
       throw new WebSocketException ("Invalid handshake."); 

      buffer[pos] = (byte) b; // THIS LINE CAUSES THE EXCEPTION 
      pos += 1; 

      if (buffer[pos - 1] == 0x0A && buffer[pos - 2] == 0x0D) { 
       String line = new String(buffer, "UTF-8"); 
       if (line.trim().equals("")) { 
        handshakeComplete = true; 
       } else { 
        handshakeLines.add(line.trim()); 
       } 

       buffer = new byte[len]; 
       pos = 0; 
      } 
     } 

更新

這裏是一個更好的實現:

public void connect() throws WebSocketException { 
    try { 
     if (connected) { 
      throw new WebSocketException("already connected"); 
     } 

     socket = createSocket(); 
     input = new DataInputStream(socket.getInputStream()); 
     output = new PrintStream(socket.getOutputStream()); 

     output.write(handshake.getHandshake()); 

     boolean handshakeComplete = false; 

     ArrayList<String> handshakeLines = new ArrayList<String>(); 

     BufferedReader reader = new BufferedReader(input); 

     String handshakeData; 
     while ((handshakeData = reader.readLine()) != null) { 
      if (handshakeData.trim().equals("")) { 
       handshakeComplete = true; 
       break; 
      } 
      handshakeLines.add(handshakeData); 
     } 

     if (!handshakeComplete) 
      throw new WebSocketException ("Failed to establish handshake."); 
0

僅通過簡單查看,您不能保證在buffer.length == pos之前停止。這將是一件事雙重檢查 - pos必須保持嚴格小於緩衝區的長度。

1

,我只是在想,你爲什麼不使用int read(byte[] b)它讀取的字節數爲您服務。 int read(byte[] b) --> Reads some number of bytes from the contained input stream and stores them into the buffer array b.

while (!handshakeComplete) { 
    int bytesRead = input.read(buffer);//returns number of bytes read 
    if(bytesRead < 10000 || bytesRead == -1 || 
     (buffer[bytesRead - 1] == 0x0A && buffer[bytesRead - 2] == 0x0D)){ 
     //done with reading 
     handshakeComplete = true; 
    } 
    if(bytesRead != -1){ 
     String line = new String(buffer, "UTF-8"); 
     if (!line.trim().equals("")) { 
     handshakeLines.add(line.trim()); 
     } 
    } 
}