2012-02-26 160 views
0

我想在java中實現udp圖像傳輸程序。發送方將圖像分成1024字節的數據包,其中前2個字節是帶有序列號的短字,第3個字節是表示數據包是否是最後一個的標誌。通過udp發送的圖像損壞

當我執行接收器並使用發件人發送圖像時,傳輸的圖像不完整並且顏色奇怪。 其他時候,當我執行接收器時,發送幾百個數據包後它會粘住。

下面是接收器的代碼,它接收數據包並將其寫入字節流。

 double DATAGRAM_MAX_SIZE = 1024; 
     byte[] recieveData = new byte[(int) DATAGRAM_MAX_SIZE]; 
     ByteArrayInputStream bais = new ByteArrayInputStream(recieveData); 
     DataInputStream dis = new DataInputStream(bais); 

     // Loop until all packets received 
     byte isLast = 0; 
     while(true) { 
      receievePacket = new DatagramPacket(recieveData, recieveData.length); 
      try { 
       receieveSocket.receive(receievePacket); 
      } catch (IOException e) { 
       System.out.println("Error receieving packet"); 
       e.printStackTrace(); 
      } 
      Short sequenceNum = dis.readShort(); 
      isLast = dis.readByte(); 
      System.out.println(recieveData[0] + " " + recieveData[1] +" " + recieveData[2]); 
      if (!seenSeq.contains(sequenceNum)) { 
       seenSeq.add(sequenceNum); 
       bos.write(recieveData, 3, (int) DATAGRAM_MAX_SIZE-3); 
      } 
      dis.reset(); 
      // Terminate loop if last packet received 
      if (isLast == 1) { 
       break; 
      } 
     } 

     // Byte array to hold image data from stream 
     byte[] imageData = bos.toByteArray(); 

每當接收並管理在這裏receieve所有數據包是產生的圖像: enter image description here

+0

我經常建議你在嘗試UDP之前使用TCP實現一個傳輸/連接,因爲它可靠地使用要複雜得多。 – 2012-02-26 21:09:49

回答

6
  1. 如果要連接到你自己一定要利用:

    Socket.setReceiveBufferSize 
    

    我遇到的問題是發送給自己的速度非常快,以至於在某些時候緩衝區溢出並且一些數據包被簡單地丟棄。 (甚至在連接到自己時假設理想的網絡條件)

  2. 做測試。你實際發送了什麼數據包。嘗試從發件人一側的數據包數據包創建圖像,以便發送您實際期望的內容。在接收端,確認哪些數據包丟失,並嘗試觀察模式。

  3. 如前所述,UDP是不可實現的 - 數據包可能不會到達,也可能以錯誤的順序到達。檢查是否按正確的順序將數據包無序放置。

  4. 另請注意,建立連接後,如果發送者說在接收者之前開始毫秒,那麼幾個數據包可能會丟失,因此在發件人開始執行任何操作之前,接收者應始終處於啓動狀態。 (如果線程沒有嚴格同步,這種情況甚至發生在本地主機上)

通過UDP發送圖像並不是真的太棒了。圖像,文本是真正應通過TCP發送的數據類型 - 這裏的部分丟失會產生重大影響。對於丟包尤其是交織和壓縮,VOIP是一個不太關心的問題。

2

UDP不是一個可靠的傳輸協議。如果你想要的可靠性,你需要自己實現它,或者使用TCP 閱讀UDP這裏