我在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
收到:「(
請幫助
你有一個通過FTP的聊天應用程序?這將如何工作? – greenapps
'我的客戶端讀取線程代碼,我稱之爲MFtp getFile方法:'是和多次。爲什麼不提這個?客戶端讀取包含json的行之前。你應該開始發佈你的帖子,告訴服務器先發送json。 P!緩解重試.. – greenapps
請不要發佈logcat的圖像。僅發佈文字。 – greenapps