2012-03-07 31 views
0

我正在使用TFTP服務器應用程序。我設法處理從服務器到客戶端的成功的文件傳輸,但是另一方面卻被竊聽。讀取文件時發生IndexOutOfBoundException

客戶端而不是傳輸整個文件只是終止惠普編譯器返回沒有錯誤。調試器在引用該數組超出範圍的標記代碼上顯示IOBE異常。

整個轉移過程是這樣這樣:

  1. 客戶端發送一個文件名和請求的操作WRQ - 寫請求
  2. 服務器接收到的數據包,並確定該操作是否WRQ是給出了新的文件合適的名稱。
  3. 服務器現在開始執行receiveData(),直到它獲得一個數據包< 512 indicationg EOT
  4. 客戶端不斷傳輸從文件中讀取的數據。

關鍵代碼:

客戶:

private void sendWRQ() throws Exception 
{ 
    String rrq = "WRQ-" + data; 
    outgoingData = rrq.getBytes(); 

    DatagramPacket output = new DatagramPacket(outgoingData, outgoingData.length, serverAddress, serverPort); 
    clientSocket.send(output); 
    //Thread.sleep(50); 
    sendData(); 
} 
byte outgoingData = new byte[512]; 
private void sendData() throws Exception 
{ 
    DatagramPacket dataTransfer = new DatagramPacket(outgoingData, outgoingData.length, serverAddress, serverPort); 
    InputStream fis = new FileInputStream(new File(data)); 

    int x; 
    while((x = fis.read(outgoingData,0,512)) != -1) // << Debugged gives IOBE 
    { 
     dataTransfer.setLength(x); 
     clientSocket.send(dataTransfer); 
     Thread.sleep(5); 
    } 

    fis.close(); 
} 

服務器:

private void listen() throws Exception 
{ 
    DatagramPacket incTransfer = new DatagramPacket(incomingData, incomingData.length); 
    serverSocket.receive(incTransfer); 

    clientAddress = incTransfer.getAddress(); 
    clientPort = incTransfer.getPort(); 

    String output = new String(incTransfer.getData()); 
    if(output.substring(0, 3).equals("RRQ")) 
    { 
     File test = new File(output.substring(4)); 
     responseData = output.substring(4); 
     if(test.exists()) 
     { 
      sendResponse("Y"); 
     } else { 
      sendResponse("N"); 
     } 
    } else if (output.substring(0, 3).equals("WRQ")) 
    { 
     File test = new File(output.substring(4)); 
     if(test.exists()) 
     { 
      Calendar cal = Calendar.getInstance(); 
      SimpleDateFormat prefix = new SimpleDateFormat(date_format); 
      String date = prefix.format(cal.getTime()).toString(); 

      responseData = date + output.substring(4); 
      receiveData(); 
     } else { 
      responseData = output.substring(4); 
      receiveData(); 
     } 
    } 
} 


private void receiveData() throws Exception 
{ 
    DatagramPacket receiveData = new DatagramPacket(incomingData, incomingData.length); 
    OutputStream fos = new FileOutputStream(new File(responseData)); 

    while(true) 
    { 
     serverSocket.receive(receiveData); 
     if(receiveData.getLength() == 512) 
     { 
      fos.write(receiveData.getData()); 
     } else { 
      fos.write(receiveData.getData(), receiveData.getOffset(), receiveData.getLength()); 
      break; 
     } 
    } 
    fos.close(); 
} 
+0

print'rrq.getBytes()'並查看它是否正確。不確定'String'是否正確處理特殊字符。 – vulkanino 2012-03-07 16:01:35

+0

這是正確的。問題不在這裏這部分是發送和接收,因爲它應該是有問題的部分是我在代碼中標記的地方。 – 2012-03-07 16:03:46

+0

你不提供'outgoingData'定義,它是否有足夠的空間容納512字節? – vulkanino 2012-03-07 16:07:30

回答

0

可能發生的唯一方法是,如果偏移量或長度參數違反了InputStream.read(byte[], int, int)指定的約束;在這種情況下,緩衝區可能不是512字節長。在這種情況下,不需要指定第二和第三個參數,只需省略它們,然後在內部變爲read(buffer, 0, buffer.length),這不會錯誤。

0

好的,這是編碼的方式中, 'outgoingData' 字段是:初始化爲512

2)接着的長度

1),在sendWRQ(), 'outgoingData' 是重新初始化爲任何rrq.getBytes()發回的內容。

3)然後,在sendData()中,'outgoingData'用作從文件中讀取數據並將其放入dataTransfer對象的中間緩衝區。

然而,由於'outgoingData'在步驟#2中被重新初始化,因此步驟#3中的'outgoingData'仍然是512字節的假設是假的。

所以,雖然EJP說使用read(outgoingData,0,outgoingData.length())可以正常工作,但是如果您解決了一些體系結構問題,您將清除很多潛在的錯誤。

例如:

與提供的代碼,有看似沒有理由有outgoingData在類級聲明和中的兩個功能共享。根據應用程序的其他部分,這可能最終會成爲線程問題。 也許byte [] buffer = rrq.getBytes();在sendWRQ()和byte [] buffer = new byte [1024];在sendData()中。 此外,「數據」參數是在課堂級別....出於什麼原因?如果它傳遞參數可能會更好地被控制。

最後,我在網絡情況下使用do {} while()循環運氣不錯。確保send()獲得至少一次發送數據的機會並保持代碼更易讀。

相關問題