Android使用Wi-Fi热点进行Socket传输多个文件的问题

假装是AA 2016-05-04 10:43:32
最近在模仿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();
}


如果有哪些地方可以改进或是有错,愿请赐教!
...全文
361 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
JMSissi 2020-05-14
  • 打赏
  • 举报
回复
大神 怎么搞啊 搞定了没 有demo不
Rampage_SS 2016-05-09
  • 打赏
  • 举报
回复
你这个多文件传输如果是异步传输,代码很显然没有做队列管理操作。如果是简单的一个文件传完了传下一个文件,简单的YModem协议即可。
小白在此 2016-05-08
  • 打赏
  • 举报
回复
引用 2 楼 hyq912 的回复:
[quote=引用 1 楼 u013545836 的回复:] 我大致看了一下,你在接受的时候是如何判断一个文件全部发送完毕的呢?都是字节流,根本无法分别,感觉你这个协议格式有问题,你可以考虑 先定n个字节表示下一个文件的长度,然后发送文件,然后再发送下一个文件的文件长度,再发送文件……,在接受的时候先接受n个字节,转化成整数len,然后再接受len个字节的文件,这样一个文件就接受完毕,紧接着就是接受下一个k字节,这样循环,直到最后一个k字节转换的整数为0,表示结束。 当然这也只是我的想法,如果有问题恳请指正。
我大概明白了你的意思,我原来已经把当前文件大小发送到接收端,现在只需要再将下一个文件的大小也发过来,在while循环那里判断下接收的大小,如果文件大小等于当前文件大小,就跳出while循环去接收下一个文件,但是有个问题:假定接收的buffer大小为1024,每次1024地发送和接收,当前文件最后那次发送可能包含了下一个文件的字节流,这个怎么截取出来?[/quote] 你可以记录已经接受的字节数,用文件大小减去已接受的,如果剩下的不足1024,你就去精确接受剩下的字节数就好了。
假装是AA 2016-05-05
  • 打赏
  • 举报
回复
引用 1 楼 u013545836 的回复:
我大致看了一下,你在接受的时候是如何判断一个文件全部发送完毕的呢?都是字节流,根本无法分别,感觉你这个协议格式有问题,你可以考虑 先定n个字节表示下一个文件的长度,然后发送文件,然后再发送下一个文件的文件长度,再发送文件……,在接受的时候先接受n个字节,转化成整数len,然后再接受len个字节的文件,这样一个文件就接受完毕,紧接着就是接受下一个k字节,这样循环,直到最后一个k字节转换的整数为0,表示结束。 当然这也只是我的想法,如果有问题恳请指正。
我大概明白了你的意思,我原来已经把当前文件大小发送到接收端,现在只需要再将下一个文件的大小也发过来,在while循环那里判断下接收的大小,如果文件大小等于当前文件大小,就跳出while循环去接收下一个文件,但是有个问题:假定接收的buffer大小为1024,每次1024地发送和接收,当前文件最后那次发送可能包含了下一个文件的字节流,这个怎么截取出来?
小白在此 2016-05-04
  • 打赏
  • 举报
回复
我大致看了一下,你在接受的时候是如何判断一个文件全部发送完毕的呢?都是字节流,根本无法分别,感觉你这个协议格式有问题,你可以考虑 先定n个字节表示下一个文件的长度,然后发送文件,然后再发送下一个文件的文件长度,再发送文件……,在接受的时候先接受n个字节,转化成整数len,然后再接受len个字节的文件,这样一个文件就接受完毕,紧接着就是接受下一个k字节,这样循环,直到最后一个k字节转换的整数为0,表示结束。 当然这也只是我的想法,如果有问题恳请指正。

80,353

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧