2017-04-18 59 views
0

我在java中開發基於套接字的聊天應用程序。我在Android上創建了兩個客戶端,桌面客戶端和移動客戶端,並且一切都很好,現在我添加了文件發送功能,我面臨着Android客戶端的不確定行爲,有時它會獲取整個文件,有時它在讀取文件時崩潰,或者我使用與桌面客戶端上完全相同的傳輸代碼! 我的客戶端應用程序以json格式向服務器發送命令,並且服務器以相同的格式作出迴應,在文件請求中,服務器回覆包含'文件'字段,因此客戶端應該輸入MFtp.ftpGetFile方法,因爲服務器發送結果後file作爲字段自動輸入sendFile方法 這是我的傳輸代碼!通過Java套接字將文件發送到Android設備時數據丟失

MFtp.java

package com.molo.ftp; 

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 

public class MFtp { 
public static boolean ftpPut(File file,DataOutputStream out){ 
    //File file=new File(fname); 
    if(!file.exists()) 
     return false; 
    { 
     System.out.println("Begin sending file"); 
     BufferedInputStream fin=null; 
     try{ 
      fin= new BufferedInputStream(new FileInputStream(file)); 
      String fname=file.getName(); 
      long fileSize=file.length(); 
      //send file name; 
      out.writeUTF(fname); 
      //send file size 
      out.writeLong(fileSize); 
      out.flush();//send completely those informations 
      int byteRead=0; 
      byte[] buffer=new byte[(int) Math.min(4096, fileSize)]; 
      System.out.println("Buffer size: "+buffer.length); 
      while((byteRead=fin.read(buffer))>0){ 
       out.write(buffer,0,byteRead); 
       out.flush(); 
       System.out.println("BYTE READ AND WRITE TO SERVER :"+byteRead); 
      } 
      System.out.println("File totaly sent"); 
      out.flush(); 
      fin.close(); 
     }catch(NumberFormatException e){ 
      return false; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return false; 
     } 
    } 
    return true; 
} 
public static boolean ftpPut(String fname,DataOutputStream out){ 
    File file=new File(fname); 
    if(!file.exists()) 
     return false; 
    { 
     System.out.println("Begin sending file"); 
     BufferedInputStream fin=null; 
     try{ 
      fin= new BufferedInputStream(new FileInputStream(file)); 
      long fileSize=file.length(); 
      fname=file.getName(); 
      //send file name; 
      out.writeUTF(fname); 
      //send file size 
      out.writeLong(fileSize); 
      out.flush();//send completely those informations 
      int byteRead=0; 
      byte[] buffer=new byte[(int) Math.min(4096, fileSize)]; 
      System.out.println("Buffer size: "+buffer.length); 
      while((byteRead=fin.read(buffer))>0){ 
       out.write(buffer,0,byteRead); 
       out.flush(); 
       System.out.println("BYTE READ AND WRITE TO SERVER :"+byteRead); 
      } 
      System.out.println("File totaly sent"); 
      out.flush(); 
      fin.close(); 
     }catch(NumberFormatException e){ 
      return false; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return false; 
     } 
    } 
    return true; 
} 
public static File ftpGetFile(DataInputStream din,String dir){ 

    //read file size from the client 
    try{ 
     //read file name 
     String fname=din.readUTF(); 
     //read filename 
     long fileSize=din.readLong(); 

     File outPut=new File(dir+"/"+fname); 
     BufferedOutputStream fout=null; 
     fout= new BufferedOutputStream(new FileOutputStream(outPut)); 
     long byteRestants=fileSize; 
     byte[] buffer=new byte[(int) Math.min(4096, fileSize)]; 
     System.out.println("Start receiving file: "+fname+"/"+fileSize); 
     int byteToRead=0; 
     while(byteRestants>0){ 
      byteToRead=din.read(buffer, 0,(int)Math.min(buffer.length, byteRestants)); 
      byteRestants-=byteToRead; 
      fout.write(buffer,0,byteToRead); 
      System.out.println("Byte restant: "+byteRestants); 
     } 
     fout.close(); 
     return outPut; 
    }catch(NumberFormatException e){ 
     return null; 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     return null; 
    } 
} 

}

而且票數是我的客戶端讀取線程代碼,我調用MFTP GetFile方法:

private class ReadThread extends Thread{ 
    @Override 
    public void run() { 
     if(reader==null){ 
      try { 
       System.out.println("Openning"); 
       reader=new DataInputStream(new BufferedInputStream(socket.getInputStream())); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     while(go){ 

      try { 
       String line= readLine(reader); 
       if(line==null) 
        break; 
       System.out.println("Client.ReadThread:line "+line); 
       JSONObject result= new JSONObject(line); 
       if(!result.has("hash")) 
        continue; 
       Response r=new Response(result.getLong("hash"),result.getInt("status"), result.get("data")); 
       //System.out.println("Result: "+result.toString()); 
       MediaFile[] medias=null; 
       if(result.has("files")){ 
        JSONArray list=result.getJSONArray("files"); 
        System.out.println("Client.ReadThread:line "+"Has Media :"+list.length()); 
        // List<MediaFile> files= new ArrayList<>(); 
        medias=new MediaFile[list.length()]; 
        for(int i =0;i<list.length();i++){ 
         JSONObject obj=list.getJSONObject(i); 
         MediaFile m=new MediaFile(); 
         m.name=obj.getString("name"); 
         m.size=obj.getLong("size"); 
         m.type=obj.getString("type"); 
         Log.e("Client.medias.receiving","m.size: "+m.size+" m.name "+m.name+" m.type : "+m.type); 
         m.file= MFtp.ftpGetFile(reader, MainActivity.TEMP_DIR); 
         if(m.file!=null){ 
          m.absolutPath=m.file.getAbsolutePath(); 
          Log.e("Client.received: ",m.absolutPath); 
         }else{ 
          Log.e("Client.received: ","Failed to save file"); 
          System.out.println("Client.received: "+"Failed to save file"); 
         } 
        } 
       } 
       r.medias=medias; 
       if(queryManager!=null && r.hash>0){ 
        queryManager.onResult(r); 
       } 
       else if(listener!=null && r.hash<=0) 
        listener.onReceiveNewMessage(r); 
      }catch(SocketException e){ 
       if(listener!=null) 
        listener.onSocketExceptionWhenRead(socket); 
      } 
      catch (IOException e) { 
       if(listener!=null) 
        listener.onIOExceptionWhenRead(socket); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      try { 
       Thread.sleep(40); 
      } catch (InterruptedException e) { 
       // TODO: handle exception 
       //readThread.interrupt(); 
       break; 
      } 
     } 

    } 
} 

讀者線程在插座上市,當它從套接字接收到新消息時,它將以json格式解析它,然後創建一個新的Response對象,但是如果響應包含文件字段,則意味着服務器烏拉圭回合將在代碼

............... 
else if(command.matches("getUserProfil")){ 
    if(request.has("user")){ 
     String userLog=request.get("user").asText(); 
     ObjectNode n=mapper.createObjectNode(); 
     Membre m=memberManager.getOne(userLog); 
     MediaFile f=new MediaFile(); 
     f.file=new File(m.getProfil()); 
     f.name=f.file.getName(); 
     f.size=f.file.length(); 
     f.type="image/png"; 
     n.put("cache", true); 
     System.out.println("SIZE: "+f.size+" ;; "+f.size); 
     println(mOut, createResponse(comId, MyStandarMessageType.OK, n,f));//will send a json string with "files" as a field 
     mOut.flush(); 
     sendFile(f); 
    } 
} 
...........the sendFile method......... 
private void sendFile(MediaFile... files) throws IOException { 
    if(files!=null && files.length >0){ 
     System.out.println("SendFile"); 
     for(MediaFile f:files){ 
      System.out.println("Start sending file"); 
      MFtp.ftpPut(f.file,mOut); 
     } 
    } 
} 

在桌面上是沒有問題的只是像票數後發送一個文件,但Android客戶端上,有時文件被成功接收,但更多的時候,不! 最不合邏輯的是,在客戶端讀取線程,進入ftpGetFile方法之後,行字符串行=的readLine(讀取器)(以readThread)被調用而不是String FNAME = din.readUTF()在ftpGetFile方法

這是在一個案件的日誌貓,但有時該文件是完全

I/System.out: Client.ReadThread:line {"hash":2,"status":200,"data":{"cache":true},"files":[{"type":"image/png","size":1875,"name":"prof_molo_1492209637904.png"}]} 
I/System.out: Client.ReadThread:line Has Media :1 
I/System.out: Client.ReadThread:line prof_molo_1492209637904.png 
I/System.out: fGetFile 
I/System.out: MFt.ftpGetFile name : 
I/System.out: MFt.ftpGetFile size: 122915152 
W/System.err: java.io.FileNotFoundException: /storage/sdcard0/molochat/temp: open failed: EISDIR (Is a directory) 
W/System.err: org.json.JSONException: Value prof_molo_1492209637904.png of type java.lang.String cannot be converted to JSONObject 
W/System.err:  at libcore.io.IoBridge.open(IoBridge.java:416) 
W/System.err:  at java.io.FileOutputStream.<init>(FileOutputStream.java:88) 
W/System.err:  at java.io.FileOutputStream.<init>(FileOutputStream.java:73) 
W/System.err:  at com.molo.app.chat.ftp.MFtp.ftpGetFile(MFtp.java:99) 
W/System.err:  at com.molo.app.chat.net.Client$ReadThread.run(Client.java:228) 
W/System.err: Caused by: libcore.io.ErrnoException: open failed: EISDIR (Is a directory) 
W/System.err:  at org.json.JSON.typeMismatch(JSON.java:111) 
W/System.err:  at org.json.JSONObject.<init>(JSONObject.java:158) 
W/System.err:  at org.json.JSONObject.<init>(JSONObject.java:171) 
W/System.err:  at com.molo.app.chat.net.Client$ReadThread.run(Client.java:209) 
W/System.err:  at libcore.io.Posix.open(Native Method) 
W/System.err:  at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 
W/System.err:  at libcore.io.IoBridge.open(IoBridge.java:400) 
W/System.err: ... 4 more 
E/Client.received:: Failed to save file 
I/System.out: Client.received: Failed to save file 

收到:「(

請幫助

+0

你有一個通過FTP的聊天應用程序?這將如何工作? – greenapps

+0

'我的客戶端讀取線程代碼,我稱之爲MFtp getFile方法:'是和多次。爲什麼不提這個?客戶端讀取包含json的行之前。你應該開始發佈你的帖子,告訴服務器先發送json。 P!緩解重試.. – greenapps

+0

請不要發佈logcat的圖像。僅發佈文字。 – greenapps

回答

0

是我的錯,我正確地沒有關閉線程!當申請時n進入暫停狀態,因此在恢復時創建了一個新的讀取線程,因此數據未按預期處理!