2013-07-02 28 views
0

發送端 - 它是在android中,它是AsyncTask,doInBackground的一部分。基本上,它將發送文件名稱,大小和圖像數據到服務器端。Android-java Fil通過TCP字節傳輸丟失

   InetAddress serverIP = InetAddress.getByName(IP); 
       Socket client = new Socket(serverIP,SERVER_PORT); 
       System.out.println("Connected to Server\n"); 
       System.out.println(imgFile.length()); 
       //sending name of the file 
       PrintWriter name = new PrintWriter(new OutputStreamWriter(client.getOutputStream()),true); 
       name.println(fileName); 
       name.flush(); 
       //sending size of the file 
       name.println(imgFile.length()); 
       name.flush(); 

       //sending body 
       DataInputStream imgBodyIn = new DataInputStream(new FileInputStream(imgFile)); 
       DataOutputStream imgBodyOut = new DataOutputStream(client.getOutputStream()); 
       byte[] buffer = new byte[BUFFER_SIZE]; 
       int len; 
       long filesize = imgFile.length(); 
       while(filesize >=0&& (len=imgBodyIn.read(buffer,0,(int)Math.min(buffer.length,filesize)))>0){ 
        imgBodyOut.write(buffer,0,len); 
        filesize-=len; 
       } 
       name.close(); 
       imgBodyIn.close(); 
       imgBodyOut.flush(); 
       imgBodyOut.close(); 
       client.close(); 

接收方

  //receiving name 
      BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));    
      String name = in.readLine(); 
      System.out.println("Name of the File : " + name+".JPG"); 
      //receiveing size info 
      String size = in.readLine(); 
      System.out.println("Size of the File :"+size +"bytes"); 

      //storing file 
      File f = new File("/home/ubuntu", name+".JPG"); 
      FileOutputStream output = new FileOutputStream(f); 

      int len=0; 
      long received=0; 
      byte[] buf = new byte[BUFFER]; 
     while(received<=Long.parseLong(size)&&(len=sock.getInputStream().read(buf))>0) 
     { 

      output.write(buf,0,len); 
      received +=len; 
      System.out.print("Receiving.."+received +"/"+size+"\r"); 


     }  
     output.flush(); 
     output.close(); 
     in.close(); 
     System.out.println("\n"+name+".JPG received"); 
     System.out.println("Size received :"+f.length()+"bytes"); 

,當我試圖發送一個文件,正確的尺寸信息和名稱被轉移。但是,我無法收到完整的文件;一些字節丟失。我使用的緩衝區大小爲1024

採樣運行:

Waiting for client to connect.. 
Client Accepted 

Name of the File : P1011474.JPG 
Size of the File :714438bytes 
Receiving..712997/714438 
P1011474.JPG received 
Size received :712997bytes 

socket closed 

回答

0

最有可能的是在接收端,從流中讀取時,它包含一個內部緩衝區,以提高性能BufferedReader。請參閱Javadoc

從字符輸入流中讀取文本,緩衝字符以提供字符,數組和行的有效讀取。

所以不會只讀過兩行,但還不如讀你的兩條線後提前。因此,您附加的二進制映像的一部分也可能會被緩存。然後,當您嘗試從InputStream直接讀取包裝有DataInputStream的二進制數據時,您將不會收到BufferedReader實例中已經緩存的字節。

我建議,您不要使用PrintWriter而是寫文件名,並直接使用從DataOutputStream方法長度,例如:

out.writeUTF(fileName); 
out.writeLong(imgFile.length()); 

在接收端使用的DataInputStreamread*方法,而不是BufferedReader。如果你希望緩衝,包裹插座InputStreamBufferedInputStream

DataInputStream dis = new DataInputStream(
    new BufferedInputStream(socket.getInputStream())); 
String fileName = dis.readUTF(); 
long fileLength = dis.readLong(); 
// now read file contents from stream 

順便說一句,你沒有做的事:

imgBodyIn.read(buffer,0,(int)Math.min(buffer.length,filesize)) 

從一個文件中的圖像讀取時,只是做:

imgBodyIn.read(buffer, 0, buffer.length) 

流/文件的末尾認可和read()將返回的字節長度讀,所以你不需要做Math.min()

+0

對不起,但你能詳細解釋一下嗎?謝謝。 – user2543738

+0

@ user2543738:我改進了解釋,如果您有具體問題,請詢問。 – nif

+0

謝謝您的明確解釋,我確實改變了以上方法發送方和接收方,但仍然收到相同的金額(顯示在線程中)。 – user2543738