java socket数据流断点续传

再见也许再也不再见 2014-01-26 12:46:30
设备正在给我发送数据,突然网络断开,服务端检测超时时间,在超时时间内如果没有检测到数据过来,就给设备端发送已个心跳测试,捕捉到异常说明设备已经离线,然后我生成日志文件,记录设备的id和文件的上传路径,等下一次该设备向我发送请求的时候,我判断是上传请求还是续传请求,如果是续传请求,则根据设备id到日志文件里面去匹配,如果能匹配到信息,则获取信息中的上传路径,接着将设备发送过来的数据追加到该路径下面的文件中,如果续传成功,则删除日志文件中改设备的所有信息

现在续传可以实现,但是接收的数据不对,设备记录断线时已经发送的字节,上线后接着发送剩余字节

我没有什么办法可以检测设备断线前给我发送的数据已经全部保存下来了

或者提供更好的断点续传思路,先谢谢大家了


这是第一次接收代码
package receive;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import listenport.ListenPort_1;
import returndata.ReturnData_6;
import test_photo.Test;
import threadfilemanage.ThreadSynchronizedReceiveData_7;
import filemanage.Createfile;

public class ReceiveData_7 {

FileOutputStream fw;
String errorlogtxt;

public void ReceiveData(Socket clientSocket) throws IOException {

// 从套接字中获取客户端发过来的数据
InputStream bufIn = clientSocket.getInputStream();

// 将输入写入到指定文件
long start = System.nanoTime();

byte buf[] = new byte[10240];

int len = 0;

String url = Createfile.url;
FileOutputStream fw = new FileOutputStream(url);

// 定义写入缓冲区
System.out.println("正在接收数据...");

int a = 0;
int count = 0;

try {
clientSocket.setSoTimeout(30000);

while ((len = bufIn.read(buf)) > 0) {
a = 1;
fw.write(buf, 0, len);
fw.flush();
}

System.gc();

} catch (SocketTimeoutException e) {
System.out.println();
System.err.println("!!!连接超时!!!");
start=start+30;
try {
clientSocket.sendUrgentData(0xFF);
} catch (Exception ex) {
// 客户端连接已断开
System.out.println("客户端已下线");
}

}

long end = System.nanoTime();

System.out.println("\n"+"用时:" + (end - start) / 1000000000 + "s");

if (a == 0) {
System.out.println("没有接收到数据");
}

Test test = new Test();

int countE_anlilianpic = test.count(url, "E_anlilianPic");

if (countE_anlilianpic == 0) {

System.err.println("数据接收不完整" + "\n" + "正在生成错误日志");

/**
* 记录设备断线信息
*
* 设备id nn 教练员id ip地址
*
* 文件路径
*/
String errorlog = "D:\\photomessage\\errorlog";

File file = new File(errorlog);

errorlogtxt = "D:\\photomessage\\errorlog\\errorlog.txt";

if (!file.exists()) {

file.mkdirs();

File file2 = new File(errorlogtxt);
file2.createNewFile();
System.out.println("创建errorlog.txt");

} else {

System.err.println("FILE IS EXITED");
}

String errormessage = ReceiveTreatmentData_3.n + " "
+ ReceiveTreatmentData_3.driver_id + " "
+ clientSocket.getInetAddress() + " " + url;

ThreadSynchronizedReceiveData_7 tsr = new ThreadSynchronizedReceiveData_7();

tsr.Thread_Synchronized_ReceiveData_7(errorlogtxt, errormessage);

} else {

count = test.count(url, "##$##");

System.out.println("共接收" + count + "张照片");
}

ReceiveTreatmentData_3.is.close();
ReturnData_6.outputStream.close();
fw.close();
bufIn.close();
ListenPort_1.count--;
System.out.println("------------------已释放资源------------------");
clientSocket.close();
}
}




这是第二次续接的代码

package receive;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import listenport.ListenPort_1;
import returndata.ReturnData_6;
import test_photo.Test;
import threadfilemanage.ThreadSynchronizedReceiveResumeData;

/**
*
* @author 凌骁 接收续传数据
*/
public class ReceiveResumeData {

public void Receive_ResumeData(Socket clientSocket,String mes,String errorlog,String n) throws IOException {

//设备id
String device_ID = n;
// 获取url
String[] b = mes.split(" ");
String url = b[3];
System.out.println("文件地址" + url);

// 从套接字中获取客户端发过来的数据
InputStream bufIn = clientSocket.getInputStream();

// 将输入写入到指定文件
long start = System.nanoTime();

byte buf[] = new byte[10240];

int len = 0;

FileOutputStream fw = new FileOutputStream(url, true);

// 定义写入缓冲区
System.out.println("正在续接数据...");

int a = 0;
int count = 0;

try {
clientSocket.setSoTimeout(30000);

while ((len = bufIn.read(buf)) != -1)
{
a = 1;
fw.write(buf, 0, len);
fw.flush();

System.gc();
}

System.out.println();

} catch (SocketTimeoutException e) {

System.err.println("!!!连接超时!!!");

try {

clientSocket.sendUrgentData(0xFF);

} catch (Exception ex) {
// 客户端连接已断开
System.out.println("客户端已下线");
}
}

long end = System.nanoTime();

System.out.println("用时:" + (end - start) / 1000000000 + "s");

if (a == 0) {

System.out.println("没有接收到数据");

}

Test test = new Test();

int countE_anlilianpic = test.count(url, "E_anlilianPic");

if (countE_anlilianpic == 0) {

System.err.println("数据接收不完整" + "\n" + "正在生成错误日志");

} else {

count = test.count(url, "##$##");

System.out.println("共接收" + count + "张照片");

// 删除errorlog记录信息
ThreadSynchronizedReceiveResumeData tsrrd = new ThreadSynchronizedReceiveResumeData();
tsrrd.Thread_Synchronized_ReceiveResumeData(device_ID, errorlog);

System.out.println("日志信息处理完毕");

}

ReceiveTreatmentData_3.is.close();
ReturnData_6.outputStream.close();
fw.close();
bufIn.close();
ListenPort_1.count--;
System.out.println("------------------已释放资源------------------");
clientSocket.close();

}

}



...全文
199 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
想喝咖啡的貓 2014-01-26
  • 打赏
  • 举报
回复
我认为 你提供给他一个查询指定文件大小的方法就行了。 另外,最好crc校验一下上传的数据。
  • 打赏
  • 举报
回复
引用 2 楼 feg545 的回复:
比如有一个100M的文件要发送,先进行切片处理,每片10M共10片。 然后给每片做个校验(长度或者CRC什么的)。 基本结构差不多是这样的: { index:当前片索引 totoal:总共多少片 length:当前片长度...或者CRC随便你 data:[0001,0002,,,,,] } 服务端接收后校验一下是不是完整的。完整的就写入到对应的位置上。 如果中间断了,就把这一片重新传。对其他片没有影响。
设备端的代码不是我写的,已经在设备端记录好了上次传送到的字节,然后上线后就给我发送剩余字节,我这里只要继续接收就可以了,我怎么做校验呢,帮我看下我的代码,如果不是我这边的问题,我就放心了
福来哥 2014-01-26
  • 打赏
  • 举报
回复
比如有一个100M的文件要发送,先进行切片处理,每片10M共10片。 然后给每片做个校验(长度或者CRC什么的)。 基本结构差不多是这样的: { index:当前片索引 totoal:总共多少片 length:当前片长度...或者CRC随便你 data:[0001,0002,,,,,] } 服务端接收后校验一下是不是完整的。完整的就写入到对应的位置上。 如果中间断了,就把这一片重新传。对其他片没有影响。
  • 打赏
  • 举报
回复
求解答,不清楚是设备端的问题还是我接收有问题

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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