最近在模仿QQ面對面快傳做個小demo,用到wifi熱點進行socket傳輸,在此程序中傳輸單個檔案是沒有問題的,但是傳輸多個檔案,在接收端for回圈時buffer會接收到多余的檔案流,導致每個檔案的大小不一致,現貼上有問題的這些代碼,求大神解答,在此感謝!!!完整代碼已托管到開源中國Git上:http://git.oschina.net/hyq912/WifiTransfer
發送端部分代碼(執行緒):
public void send() {
new Thread(new Runnable() {
@Override
public void run() {
try {
OutputStream outputStream = mSocket.getOutputStream();
InputStream inputStream = mSocket.getInputStream();
//將檔案名和檔案大小發送給接收端
outputStream.write(getHeaderString(mHeader).getBytes(UTF_8));
outputStream.flush();
sendMessage(mHandler, 10, "已發送檔案名和檔案大小");
byte[] startData = new byte[buf_size];
int len = inputStream.read(startData);
if(len != -1) {
String start = new String(startData, 0, len);
if(start.equals("start")) {
for(FileInfo fileInfo : mHeader.getFileInfos()) {
int sentLen = 0;
byte[] sendData = new byte[file_buf_size];
long totalSize = fileInfo.getFileLength();
InputStream fileInputStream = new FileInputStream(new File(fileInfo.getFileName()));
sendMessage(mHandler, 10, "正在發送: " + fileInfo.getFileName());
while ((len = fileInputStream.read(sendData)) != -1) {
outputStream.write(sendData, 0, len);
sentLen += len;
int progress = (int) (sentLen * 100 / totalSize);
L.error("檔案(" + fileInfo.getFileName() + ") 總大小: " + totalSize + " 已接收檔案(" + progress + "): " + sentLen);
}
fileInputStream.close();
}
outputStream.close();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
L.error("FileNotFoundException: " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
L.error("IOException: " + e.getMessage());
} finally {
try {
mSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
sendMessage(mHandler, 10, "發送完成");
}
}
}).start();
}
接收端部分代碼(執行緒):
public void receive() {
new Thread(new Runnable() {
@Override
public void run() {
//是否全部接收完畢
boolean isFinish = false;
if (mSocket != null) {
try {
final InputStream is = mSocket.getInputStream();
OutputStream os = mSocket.getOutputStream();
//獲取檔案名和檔案大小
byte[] headerData = new byte[buf_size];
int len = is.read(headerData);
if (len != -1) {
Header header = getHeader(new String(headerData, 0, len, UTF_8));
if (header != null && header.getFileInfos() != null && header.getFileInfos().size() > 0) {
sendMessage(mHandler, ReceiverActivity.INIT_ADAPTER, header.getFileInfos());
//告知發送端開始發送
os.write("start".getBytes(UTF_8));
os.flush();
//準備接收
String fileDir = FileUtils.getReceiveFilesPath();
for (int i = 0; i < header.getFileTotalCount(); i++) {
FileInfo fileInfo = header.getFileInfos().get(i);
String filename = fileInfo.getFileName();
long totalSize = fileInfo.getFileLength();
sendMessage(mHandler, 10, "準備接收: 檔案名: " + filename + " 檔案大小: " + totalSize);
//如果檔案不存在,創建它
File file = new File(fileDir + filename);
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
byte[] recvData = new byte[file_buf_size];
int receiveLen = 0;
while ((len = is.read(recvData)) != -1) {
dos.write(recvData, 0, len);
receiveLen += len;
int progress = (int) (receiveLen * 100 / totalSize);
sendMessage(mHandler, ReceiverActivity.REFRESH_PROGRESS, i, progress);
L.error("檔案(" + filename + ") 總大小: " + totalSize + " 已接收檔案(" + progress + "): " + receiveLen);
if(progress == 100) {
break;
}
}
//檔案大小不一致
if (receiveLen != totalSize) {
sendMessage(mHandler, 10, "檔案大小不一致");
}
dos.flush();
dos.close();
}
//全部接收完畢
isFinish = true;
os.close();
is.close();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
isFinish = false;
sendMessage(mHandler, 10, "接收失敗: " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
isFinish = false;
sendMessage(mHandler, 10, "接收失敗: " + e.getMessage());
} finally {
try {
//關閉Socket
mSocket.close();
} catch (IOException e) {
isFinish = false;
e.printStackTrace();
}
if (isFinish) {
sendMessage(mHandler, 10, "全部接收完畢");
} else {
sendMessage(mHandler, 10, "接收出錯");
}
}
}
}
}).start();
}
如果有哪些地方可以改進或是有錯,愿請賜教!
uj5u.com熱心網友回復:
我大致看了一下,你在接受的時候是如何判斷一個檔案全部發送完畢的呢?都是位元組流,根本無法分別,感覺你這個協議格式有問題,你可以考慮 先定n個位元組表示下一個檔案的長度,然后發送檔案,然后再發送下一個檔案的檔案長度,再發送檔案……,在接受的時候先接受n個位元組,轉化成整數len,然后再接受len個位元組的檔案,這樣一個檔案就接受完畢,緊接著就是接受下一個k位元組,這樣回圈,直到最后一個k位元組轉換的整數為0,表示結束。當然這也只是我的想法,如果有問題懇請指正。
uj5u.com熱心網友回復:
我大概明白了你的意思,我原來已經把當前檔案大小發送到接收端,現在只需要再將下一個檔案的大小也發過來,在while回圈那里判斷下接收的大小,如果檔案大小等于當前檔案大小,就跳出while回圈去接收下一個檔案,但是有個問題:假定接收的buffer大小為1024,每次1024地發送和接收,當前檔案最后那次發送可能包含了下一個檔案的位元組流,這個怎么截取出來?
uj5u.com熱心網友回復:
你可以記錄已經接受的位元組數,用檔案大小減去已接受的,如果剩下的不足1024,你就去精確接受剩下的位元組數就好了。
uj5u.com熱心網友回復:
你這個多檔案傳輸如果是異步傳輸,代碼很顯然沒有做佇列管理操作。如果是簡單的一個檔案傳完了傳下一個檔案,簡單的YModem協議即可。uj5u.com熱心網友回復:
大神 怎么搞啊 搞定了沒 有demo不轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/33746.html
標籤:Android
上一篇:關于Android UsbCamera HAL 實作的問題
下一篇:bmob獲取圖片檔案出現問題
