java socket数据流断点续传
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java socket数据流断点续传相关的知识,希望对你有一定的参考价值。
设备正在给我发送数据,突然网络断开,服务端检测超时时间,在超时时间内如果没有检测到数据过来,就给设备端发送已个心跳测试,捕捉到异常说明设备已经离线,然后我生成日志文件,记录设备的id和文件的上传路径,等下一次该设备向我发送请求的时候,我判断是上传请求还是续传请求,如果是续传请求,则根据设备id到日志文件里面去匹配,如果能匹配到信息,则获取信息中的上传路径,接着将设备发送过来的数据追加到该路径下面的文件中,如果续传成功,则删除日志文件中改设备的所有信息
现在续传可以实现,但是接收的数据不对,设备记录断线时已经发送的字节,上线后接着发送剩余字节
我没有什么办法可以检测设备断线前给我发送的数据已经全部保存下来了
或者提供更好的断点续传思路,先谢谢大家了
传输数据开始,设备向你这边传输数据,你这边将受到的数据保存到文件或者数据库。传输过程中,你可能要告诉设备已经保存的数据字节数。
假如网络连接异常,按照你说的思路,发送心跳包检测连接情况。你这边程序将本次操作的数据保存、并将设备ID、数据MD5校验值、操作授权码、已保存的字节数保存到日志。
下次客户端请求续传,你就校验它的设备ID、操作授权代码,然后再告诉它从哪里开始续传,跳过那些字节。
续传完成,通知客户端,续传成功。追问
现在的问题就是,传送到哪个字节设备自己做了记录,并不是我告诉他的,这样就不知道我这断线前保存的数据是不是和设备记录的数据一致
追答如果设备那边出错,TCP发送数据默认都有缓冲区,交换机之类的网络设备都可能会缓冲设备发来的数据,如果设备自己做记录,有可能将发送失败的字节也累加了,这可能是造成数据不一致的原因。
我想还是服务端做个记录比较妥。客户端也可以和你做个比对。看看丢了多少数据。
这样的话,我的思路是这样的,断网时我这边记录下已经上传的字节数,设备给我发送续传请求,我匹配到有记录,先返回一个带有已上传字节数的报文给设备,然后设备根据那个字节数,继续给我发送数据
我如何记录字节数,保存的数据可能有一二百兆,而且是没有经过协议解析的原始数据,也就是说都是乱码,用字节来计算会有影响么,应该怎么计算呢
按你说应该是字符数据流,但是你如果是按字节来接收发送,两端都是按字节计算,肯定不会出问题。
注意字符的编码一致性。我也不清楚你是按字节来保存还是其他方式的。中间可能都是按字节来接收。
方便加Q么1102488623
追答已加你。
参考技术A 你的思路很完整,挑不出什么不好的地方,现在的问题就是你要确定你所记录的断线时的已经传了多少的信息是否和已经保存起来的信息一致,先找个简单的txt文件写几行字试试追问设备端是别人写的,我这里也不好做记录,如果可以的话,+1102488623,我把代码给你看看,如果我这里没有问题的话,那就是设备端的问题了
参考技术B 思路是对的哈,你如果不确定是不是设备那边的问题,可以自己写一个简易的client来试一下Java Socket如何实现文件的断点续传,有代码更好
1package com.tangshun.www.socket;2
3import java.io.File;
4import java.io.IOException;
5import java.io.InputStream;
6import java.io.RandomAccessFile;
7import java.net.HttpURLConnection;
8import java.net.MalformedURLException;
9import java.net.URL;
10
11//断点续传
12public class DownLoad
13
14 public static void down(String URL, long nPos, String savePathAndFile)
15 try
16 URL url = new URL(URL);
17 HttpURLConnection httpConnection = (HttpURLConnection) url
18 .openConnection();
19 // 设置User-Agent
20 httpConnection.setRequestProperty("User-Agent", "NetFox");
21 // 设置断点续传的开始位置
22 httpConnection.setRequestProperty("RANGE", "bytes=" + nPos);
23 // 获得输入流
24 InputStream input = httpConnection.getInputStream();
25 RandomAccessFile oSavedFile = new RandomAccessFile(savePathAndFile,
26 "rw");
27 // 定位文件指针到nPos位置
28 oSavedFile.seek(nPos);
29 byte[] b = new byte[1024];
30 int nRead;
31 // 从输入流中读入字节流,然后写到文件中
32 while ((nRead = input.read(b, 0, 1024)) > 0)
33 (oSavedFile).write(b, 0, nRead);
34
35 httpConnection.disconnect();
36 catch (MalformedURLException e)
37 e.printStackTrace();
38 catch (IOException e)
39 e.printStackTrace();
40
41
42
43 public static long getRemoteFileSize(String url)
44 long size = 0;
45 try
46 HttpURLConnection conn = (HttpURLConnection) (new URL(url))
47 .openConnection();
48 size = conn.getContentLength();
49 conn.disconnect();
50 catch (Exception e)
51 e.printStackTrace();
52
53 return size;
54
55
56public static void main(String[] args)
57 String url = " http://www.videosource.cgogo.com/media/0/16/8678/8678.flv";
58 String savePath = "F:\\";
59 String fileName = url.substring(url.lastIndexOf("/"));
60 String fileNam=fileName;
61 HttpURLConnection conn = null;
62 try
63 conn = (HttpURLConnection) (new URL(url)).openConnection();
64 catch (Exception e)
65 e.printStackTrace();
66
67 File file = new File(savePath + fileName);
68 // 获得远程文件大小
69 long remoteFileSize = getRemoteFileSize(url);
70 System.out.println("远程文件大小="+remoteFileSize);
71 int i = 0;
72 if (file.exists())
73 // 先看看是否是完整的,完整,换名字,跳出循环,不完整,继续下载
74 long localFileSize = file.length();
75 System.out.println("已有文件大小为:"+localFileSize);
76
77 if (localFileSize < remoteFileSize)
78 System.out.println("文件续传");
79 down(url, localFileSize, savePath + fileName);
80 else
81 System.out.println("文件存在,重新下载");
82 do
83 i++;
84 fileName = fileNam.substring(0, fileNam.indexOf(".")) + "(" + i
85 + ")" + fileNam.substring(fileNam.indexOf("."));
86
87 file = new File(savePath + fileName);
88 while(file.exists());
89 try
90 file.createNewFile();
91 catch (IOException e)
92 e.printStackTrace();
93
94 down(url, 0, savePath + fileName);
95
96 // 下面表示文件存在,改名字
97
98 else
99 try
100 file.createNewFile();
101 System.out.println("下载中");
102 down(url, 0, savePath + fileName);
103 catch (IOException e)
104 e.printStackTrace();
105
106
107
108 参考技术A 上传:
上传时附带一个描述数据起始位置的参数。
接受的一端接收到数据后,按照起始位置续写文件。
下载:
按照本地已保存的大小,提交下载请求。
服务器按照请求的位置,传数据。
大概就是这么个意思。还要处理很多异常情况。
以上是关于java socket数据流断点续传的主要内容,如果未能解决你的问题,请参考以下文章