2017-06-21 50 views
0

我創建了使用串行通信(RXTXComm庫)發送和接收文件的服務器/客戶端JAVA應用程序。
由於我的項目,鏈接可以在傳輸過程中被物理切斷,所以我實現了一個滑動窗口和一個連接重置代碼,在網絡重新建立之後,該代碼可以恢復傳輸。串行連接中的錯誤位重置

的問題是,在連接之後接收到的數據已經被切斷和重新建立損壞

服務器代碼「接收器」:

bytesRead = in.read(mybytearray, 0, mybytearray.length); 
System.out.println("R\t Bytes read\t" + bytesRead); 
current = bytesRead; 
System.out.println("R\t\t FIRST Last byte recieved \t" + current); 
outR.writeLong((current + 1)); 
outR.flush(); 
System.out.println("R\t\tSending ACK"); 

while (true) { 
    do { 
     bytesRead = in.read(mybytearray, current, (mybytearray.length - current)); 
     System.out.println("R\t Bytes read\t" + bytesRead); 
     if (bytesRead >= 0) current += bytesRead; 
     System.out.println("R\t\tLast byte recieved \t" + current); 
     //ACK = Integer.toString((current+1)); 
     outR.writeLong((current + 1)); 

     outR.flush(); 
     System.out.println("R\t\tSending ACK"); 

    } while (bytesRead > 0); 
    //in.close(); 

    if ((mybytearray[current - 1] & 0xff) != 0b01000101) { 
     int timer = 0; 
     boolean loop = true; 
     while (loop) { 
      timer++; 
      Thread.sleep(1000); 
      if (timer > 5) { 

       System.out.println("R\t\t Connection Timeout"); 
       timer = 0; 
       current = 0; 
       break; 
      } 
     } 
    } else { 
     break; 
    } 
} 
bos.write(mybytearray, 0, current - 1); 
bos.flush(); 
System.out.println("R\t\tfinished recieving"); 
bos.close(); 

,這是客戶端「發件人」

public static class InReciever implements Runnable { 
    DataInputStream inS; 
    public InReciever(DataInputStream in) { 
     inS = in; 
    } 

    @Override 
    public void run() { 
     try { 
      //int timer=0; 
      while (true) { 
       long ack = 0; 

       if (brek) 
        break; 
       if ((ack = inS.readLong()) > 0) { 

        firstACK = false; 
        windowStart = ack; 

        System.out.println("S\t\tRecieving ack"); 
        System.out.println("S\tNext byte to send\t" + ack); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

public static class SerialWriter implements Runnable { 
    OutputStream out; 
    DataInputStream inS; 
    DataOutputStream outHello; 
    byte[] mybytearray; 

    public SerialWriter(OutputStream out, DataInputStream in, DataOutputStream outHello, byte[] buffer) { 
     this.out = out; 
     inS = in; 
     this.outHello = outHello; 
     mybytearray = buffer; 
    } 

    public void run() { 
     try { 
      new Thread(new InReciever(inS)).start(); 
      for (int i = 0; i < mybytearray.length; i++) { 
       //System.out.println("windowEnd \t"+windowEnd); 
       out.write(mybytearray[i]); 
       out.flush(); 
       int timer = 0; 
       while (windowEnd > (windowStart + 2000) && !firstACK) { 
        timer++; 
        Thread.sleep(1000); 

        if (timer > 5) { 
         System.out.println("S\tTimeout \n Restart connection \t"); 
         i = -1; 
         out.flush(); 
         windowStart = 0; 
         windowEnd = 0; 
         firstACK = true; 
        } 
        //Thread.sleep(100); 
        // 
       } 
       windowEnd++; 
      } 
      outHello.writeChar('E'); 
      outHello.flush(); 
      System.out.println("s\tfinished sending"); 
      brek = true; 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

回答

0

我沒有分析每行代碼,但我沒有看到任何形式的驗證。串行通信通常採用許多形式的驗證,例如數據包檢查。

您是否曾嘗試將流分成更小的塊並一次發送塊?發送方應該在接收方可以驗證的每個塊中包含一些類型的CRC校驗和計算。

中斷重新啓動後,接收器將驗證CRC校驗和的最新塊。如果不匹配,則丟棄塊並重新啓動。

我懷疑你的「重啓」代碼沒有正確丟棄損壞的位。