2017-04-18 31 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进入暂停状态,因此在恢复时创建了一个新的读取线程,因此数据未按预期处理!