断点续传的原理断点续传是大型文件数据传输的核心。本文将以多线程技术和Socket技术为依托,介绍大型文件断点续传的实现方法。
断点续传的原理
断点续传的原理  基本实现思想
断点续传的原理
断点续传的原理  多线程断点续传实现的基本思想就是在发送端(也称客户端)将要传输的文件分割为大小相当的多块,用多个线程,将这些块同时向目标服务器端发送;在服务器端的服务程序监听数据传输请求,每当接到新的请求,则创建一个新的线程,与客户端的发送线程对应,接收数据,记录数据传输进程
断点续传的原理
断点续传的原理  图1是点对点文件断点续传第N块传输过程示意图。在传输发起端(客户端),将大型文件事先分割为大小相当的N块,同时创建N个传输线程,连接目标端服务器。当服务器端接收到每一个连接请求后,告知客户端可以传输文件。当客户端接收到可以传输文件的消息时,首先向服务器发送数据传输信息块(包括第几块、在块中的起始位置)请求,当服务器端接收到该请求后,向客户端发送数据传输信息,客户端然后传输数据传输信息块指定的数据给服务器端,服务器端更新数据传输信息块。
断点续传的原理
断点续传的原理(一)断点续传的原理 
断点续传的原理其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。 
断点续传的原理打个比方,浏览器请求服务器上的一个文时,所发出的请求如下: 
断点续传的原理假设服务器域名为wwww.sjtu.edu.cn,文件名为down.zip。 
断点续传的原理GET /down.zip HTTP/1.1 
断点续传的原理Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms- 
断点续传的原理excel, application/msword, application/vnd.ms-powerpoint, */* 
断点续传的原理Accept-Language: zh-cn 
断点续传的原理Accept-Encoding: gzip, deflate 
断点续传的原理User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) 
断点续传的原理Connection: Keep-Alive 
断点续传的原理
断点续传的原理
断点续传的原理服务器收到请求后,按要求寻找请求的文件,提取文件的信息,然后返回给浏览器,返回信息如下: 
断点续传的原理
断点续传的原理
断点续传的原理200 
断点续传的原理Content-Length=106786028 
断点续传的原理Accept-Ranges=bytes 
断点续传的原理Date=Mon, 30 Apr 2001 12:56:11 GMT 
断点续传的原理ETag=W/"02ca57e173c11:95b" 
断点续传的原理Content-Type=application/octet-stream 
断点续传的原理Server=Microsoft-IIS/5.0 
断点续传的原理Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT 
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给 
断点续传的原理Web服务器的时候要多加一条信息--从哪里开始。 
断点续传的原理下面是用自己编的一个"浏览器"来传递请求信息给Web服务器,要求从2000070字节开始。 
断点续传的原理GET /down.zip HTTP/1.0 
断点续传的原理User-Agent: NetFox 
断点续传的原理RANGE: bytes=2000070- 
断点续传的原理Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 
断点续传的原理
断点续传的原理
断点续传的原理仔细看一下就会发现多了一行RANGE: bytes=2000070- 
断点续传的原理这一行的意思就是告诉服务器down.zip这个文件从2000070字节开始传,前面的字节不用传了。 
断点续传的原理服务器收到这个请求以后,返回的信息如下: 
断点续传的原理206 
断点续传的原理Content-Length=106786028 
断点续传的原理Content-Range=bytes 2000070-106786027/106786028 
断点续传的原理Date=Mon, 30 Apr 2001 12:55:20 GMT 
断点续传的原理ETag=W/"02ca57e173c11:95b" 
断点续传的原理Content-Type=application/octet-stream 
断点续传的原理Server=Microsoft-IIS/5.0 
断点续传的原理Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT 
断点续传的原理
断点续传的原理
断点续传的原理和前面服务器返回的信息比较一下,就会发现增加了一行: 
断点续传的原理Content-Range=bytes 2000070-106786027/106786028 
断点续传的原理返回的代码也改为206了,而不再是200了。 
断点续传的原理
断点续传的原理
断点续传的原理知道了以上原理,就可以进行断点续传的编程了。 
断点续传的原理
断点续传的原理
断点续传的原理(二)Java实现断点续传的关键几点 
断点续传的原理
断点续传的原理
断点续传的原理(1)用什么方法实现提交RANGE: bytes=2000070-。 
断点续传的原理当然用最原始的Socket是肯定能完成的,不过那样太费事了,其实Java的net包中提供了这种功能。代码如下: 
断点续传的原理URL url = new URL("http://www.sjtu.edu.cn/down.zip"); 
断点续传的原理HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection 
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理(); 
断点续传的原理//设置User-Agent 
断点续传的原理httpConnection.setRequestProperty("User-Agent","NetFox"); 
断点续传的原理//设置断点续传的开始位置 
断点续传的原理httpConnection.setRequestProperty("RANGE","bytes=2000070"); 
断点续传的原理//获得输入流 
断点续传的原理InputStream input = httpConnection.getInputStream(); 
断点续传的原理
断点续传的原理
断点续传的原理从输入流中取出的字节流就是down.zip文件从2000070开始的字节流。 
断点续传的原理大家看,其实断点续传用Java实现起来还是很简单的吧。 
断点续传的原理接下来要做的事就是怎么保存获得的流到文件中去了。 
断点续传的原理
断点续传的原理
断点续传的原理保存文件采用的方法。 
断点续传的原理我采用的是IO包中的RandAccessFile类。 
断点续传的原理操作相当简单,假设从2000070处开始保存文件,代码如下: 
断点续传的原理RandomAccess oSavedFile = new RandomAccessFile("down.zip","rw"); 
断点续传的原理long nPos = 2000070; 
断点续传的原理//定位文件指针到nPos位置 
断点续传的原理oSavedFile.seek(nPos); 
断点续传的原理byte[] b = new byte[1024]; 
断点续传的原理int nRead; 
断点续传的原理//从输入流中读入字节流,然后写到文件中 
断点续传的原理while((nRead=input.read(b,0,1024)) > 0) 
断点续传的原理
断点续传的原理oSavedFile.write(b,0,nRead); 
断点续传的原理
断点续传的原理
断点续传的原理怎么样,也很简单吧。 
断点续传的原理接下来要做的就是整合成一个完整的程序了。包括一系列的线程控制等等。 
断点续传的原理
断点续传的原理
断点续传的原理(三)断点续传内核的实现 
断点续传的原理主要用了6个类,包括一个测试类。 
断点续传的原理SiteFileFetch.java负责整个文件的抓取,控制内部线程(FileSplitterFetch类)。 
断点续传的原理FileSplitterFetch.java负责部分文件的抓取。 
断点续传的原理FileAccess.java负责文件的存储。 
断点续传的原理SiteInfoBean.java要抓取的文件的信息,如文件保存的目录,名字,抓取文件的URL等。 
断点续传的原理Utility.java工具类,放一些简单的方法。 
断点续传的原理TestMethod.java测试类。 
断点续传的原理
断点续传的原理
断点续传的原理下面是源程序: 
断点续传的原理/* 
断点续传的原理**SiteFileFetch.java 
断点续传的原理*/ 
断点续传的原理package NetFox; 
断点续传的原理import java.io.*; 
断点续传的原理import java.net.*; 
断点续传的原理
断点续传的原理
断点续传的原理public class SiteFileFetch extends Thread { 
断点续传的原理
断点续传的原理
断点续传的原理SiteInfoBean siteInfoBean = null; //文件信息Bean 
断点续传的原理long[] nStartPos; //开始位置 
断点续传的原理long[] nEndPos; //结束位置 
断点续传的原理FileSplitterFetch[] fileSplitterFetch; //子线程对象 
断点续传的原理long nFileLength; //文件长度 
断点续传的原理boolean bFirst = true; //是否第一次取文件 
断点续传的原理boolean bStop = false; //停止标志 
断点续传的原理File tmpFile; //文件下载的临时信息 
断点续传的原理DataOutputStream output; //输出到文件的输出流 
断点续传的原理
断点续传的原理
断点续传的原理public SiteFileFetch(SiteInfoBean bean) throws IOException 
断点续传的原理
断点续传的原理siteInfoBean = bean; 
断点续传的原理//tmpFile = File.createTempFile ("zhong","1111",new File(bean.getSFilePath())); 
断点续传的原理tmpFile = new File(bean.getSFilePath()+File.separator + bean.getSFileName()+".info"); 
断点续传的原理if(tmpFile.exists ()) 
断点续传的原理
断点续传的原理bFirst = false; 
断点续传的原理read_nPos(); 
断点续传的原理
断点续传的原理else 
断点续传的原理
断点续传的原理nStartPos = new long[bean.getNSplitter()]; 
断点续传的原理nEndPos = new long[bean.getNSplitter()]; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public void run() 
断点续传的原理
断点续传的原理//获得文件长度 
断点续传的原理//分割文件 
断点续传的原理//实例FileSplitterFetch 
断点续传的原理//启动FileSplitterFetch线程 
断点续传的原理//等待子线程返回 
断点续传的原理try{ 
断点续传的原理if(bFirst) 
断点续传的原理
断点续传的原理nFileLength = getFileSize(); 
断点续传的原理if(nFileLength == -1) 
断点续传的原理
断点续传的原理System.err.println("File Length is not known!"); 
断点续传的原理
断点续传的原理else if(nFileLength == -2) 
断点续传的原理
断点续传的原理System.err.println("File is not access!"); 
断点续传的原理
断点续传的原理else 
断点续传的原理
断点续传的原理for(int i=0;i new FileSplitterFetch( siteInfoBean.getSSiteURL(), 
断点续传的原理siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName(), 
断点续传的原理nStartPos[i],nEndPos[i],i); 
断点续传的原理Utility.log( " Thread " + i + " , nStartPos =" + nStartPos[i]+", nEndPos = " + nEndPos[i]); 
断点续传的原理fileSplitterFetch[i].start(); 
断点续传的原理
断点续传的原理// fileSplitterFetch[nPos.length-1] = new FileSplitterFetch(siteInfoBean.getSSiteURL(), 
断点续传的原理siteInfoBean.getSFilePath() + File.separator + siteInfoBean.getSFileName() , nPos[nPos.length-1], nFileLength, nPos.length-1); 
断点续传的原理// Utility.log("Thread " + (nPos.length-1 ) + " , nStartPos = " + nPos[nPos.length-1] + ", 
断点续传的原理nEndPos = " + nFileLength); 
断点续传的原理// fileSplitterFetch[nPos.length-1].start(); 
断点续传的原理
断点续传的原理
断点续传的原理//等待子线程结束 
断点续传的原理//int count = 0; 
断点续传的原理//是否结束while循环 
断点续传的原理boolean breakWhile = false; 
断点续传的原理
断点续传的原理
断点续传的原理while(!bStop) 
断点续传的原理
断点续传的原理write_nPos(); 
断点续传的原理Utility.sleep(500); 
断点续传的原理breakWhile = true; 
断点续传的原理
断点续传的原理
断点续传的原理for(int i=0;i4) 
断点续传的原理// siteStop(); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理System.err.println("文件下载结束!"); 
断点续传的原理
断点续传的原理catch(Exception e){e.printStackTrace ();} 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理//获得文件长度 
断点续传的原理public long getFileSize() 
断点续传的原理
断点续传的原理int nFileLength = -1; 
断点续传的原理try{ 
断点续传的原理URL url = new URL(siteInfoBean.getSSiteURL()); 
断点续传的原理HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection (); 
断点续传的原理httpConnection.setRequestProperty("User-Agent","NetFox"); 
断点续传的原理
断点续传的原理
断点续传的原理int responseCode=httpConnection.getResponseCode(); 
断点续传的原理if(responseCode>=400) 
断点续传的原理
断点续传的原理processErrorCode(responseCode); 
断点续传的原理return -2; //-2 represent access is error 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理String sHeader; 
断点续传的原理
断点续传的原理
断点续传的原理for(int i=1;;i++) 
断点续传的原理
断点续传的原理//DataInputStream in = new DataInputStream(httpConnection.getInputStream ()); 
断点续传的原理//Utility.log(in.readLine()); 
断点续传的原理sHeader=httpConnection.getHeaderFieldKey(i); 
断点续传的原理if(sHeader!=null) 
断点续传的原理
断点续传的原理if(sHeader.equals("Content-Length")) 
断点续传的原理
断点续传的原理nFileLength = Integer.parseInt(httpConnection.getHeaderField(sHeader)); 
断点续传的原理break; 
断点续传的原理
断点续传的原理
断点续传的原理else 
断点续传的原理break; 
断点续传的原理
断点续传的原理
断点续传的原理catch(IOException e){e.printStackTrace ();} 
断点续传的原理catch(Exception e){e.printStackTrace ();} 
断点续传的原理
断点续传的原理
断点续传的原理Utility.log(nFileLength); 
断点续传的原理
断点续传的原理
断点续传的原理return nFileLength; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理//保存下载信息(文件指针位置) 
断点续传的原理private void write_nPos() 
断点续传的原理
断点续传的原理try{ 
断点续传的原理output = new DataOutputStream(new FileOutputStream(tmpFile)); 
断点续传的原理output.writeInt(nStartPos.length); 
断点续传的原理for(int i=0;iDataInputStream(new FileInputStream(tmpFile)); 
断点续传的原理int nCount = input.readInt(); 
断点续传的原理nStartPos = new long[nCount]; 
断点续传的原理nEndPos = new long[nCount]; 
断点续传的原理for(int i=0;i 0 & & nStartPos 
< nEndPos && !bStop) 
断点续传的原理
断点续传的原理nStartPos +
= fileAccessI.write(b,0,nRead); 
断点续传的原理
//if(nThreadID == 1) 
断点续传的原理// Utility.log("nStartPos 
= " + nStartPos + ", nEndPos = " + nEndPos); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理Utility.log("
Thread " + nThreadID + " is over!"); 
断点续传的原理bDownOver 
= true; 
断点续传的原理
//nPos = fileAccessI.write (b,0,nRead); 
断点续传的原理
断点续传的原理catch(Exception e){e.printStackTrace ();} 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理//打印回应的头信息 
断点续传的原理public void logResponseHead(HttpURLConnection con) 
断点续传的原理
断点续传的原理for(int i
=1;;i++) 
断点续传的原理

断点续传的原理String header
=con.getHeaderFieldKey(i); 
断点续传的原理
if(header!=null) 
断点续传的原理
//responseHeaders.put(header,httpConnection.getHeaderField(header)); 
断点续传的原理Utility.log(header+" : "+con.getHeaderField(header)); 
断点续传的原理else 
断点续传的原理break; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public void splitterStop() 
断点续传的原理
断点续传的原理bStop 
= true; 
断点续传的原理

断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理/* 
断点续传的原理**FileAccess.java 
断点续传的原理*/ 
断点续传的原理package NetFox; 
断点续传的原理import java.io.*; 
断点续传的原理
断点续传的原理
断点续传的原理public class FileAccessI implements Serializable{ 
断点续传的原理
断点续传的原理
断点续传的原理RandomAccessFile oSavedFile; 
断点续传的原理long nPos; 
断点续传的原理
断点续传的原理
断点续传的原理public FileAccessI() throws IOException 
断点续传的原理
断点续传的原理this("",0); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public FileAccessI(String sName,long nPos) throws IOException 
断点续传的原理
断点续传的原理oSavedFile 
= new RandomAccessFile(sName,"rw"); 
断点续传的原理this.nPos 
= nPos; 
断点续传的原理
oSavedFile.seek(nPos); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public synchronized int write(byte[] b,int nStart,int nLen) 
断点续传的原理
断点续传的原理int n 
= -1; 
断点续传的原理
try{ 
断点续传的原理oSavedFile.write(b,nStart,nLen); 
断点续传的原理
= nLen; 
断点续传的原理

断点续传的原理catch(IOException e) 
断点续传的原理
断点续传的原理e.printStackTrace (); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理return n; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理/* 
断点续传的原理**SiteInfoBean.java 
断点续传的原理*/ 
断点续传的原理package NetFox; 
断点续传的原理
断点续传的原理
断点续传的原理public class SiteInfoBean { 
断点续传的原理
断点续传的原理
断点续传的原理private String sSiteURL; //Site's URL 
断点续传的原理private String sFilePath; //Saved File's Path 
断点续传的原理private String sFileName; //Saved File's Name 
断点续传的原理private int nSplitter; //Count of Splited Downloading File 
断点续传的原理
断点续传的原理
断点续传的原理public SiteInfoBean() 
断点续传的原理
断点续传的原理//default value of nSplitter is 5 
断点续传的原理this("","","",5); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public SiteInfoBean(String sURL,String sPath,String sName,int nSpiltter) 
断点续传的原理
断点续传的原理sSiteURL
= sURL; 
断点续传的原理
sFilePath = sPath; 
断点续传的原理
sFileName = sName; 
断点续传的原理
this.nSplitter = nSpiltter; 
断点续传的原理
断点续传的原理
断点续传的原理

断点续传的原理
断点续传的原理
断点续传的原理public String getSSiteURL() 
断点续传的原理
断点续传的原理return sSiteURL; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public void setSSiteURL(String value) 
断点续传的原理
断点续传的原理sSiteURL 
= value; 
断点续传的原理

断点续传的原理
断点续传的原理
断点续传的原理public String getSFilePath() 
断点续传的原理
断点续传的原理return sFilePath; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public void setSFilePath(String value) 
断点续传的原理
断点续传的原理sFilePath 
= value; 
断点续传的原理

断点续传的原理
断点续传的原理
断点续传的原理public String getSFileName() 
断点续传的原理
断点续传的原理return sFileName; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public void setSFileName(String value) 
断点续传的原理
断点续传的原理sFileName 
= value; 
断点续传的原理

断点续传的原理
断点续传的原理
断点续传的原理public int getNSplitter() 
断点续传的原理
断点续传的原理return nSplitter; 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public void setNSplitter(int nCount) 
断点续传的原理
断点续传的原理nSplitter 
= nCount; 
断点续传的原理

断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理/* 
断点续传的原理**Utility.java 
断点续传的原理*/ 
断点续传的原理package NetFox; 
断点续传的原理
断点续传的原理
断点续传的原理public class Utility { 
断点续传的原理
断点续传的原理
断点续传的原理public Utility() 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public static void sleep(int nSecond) 
断点续传的原理
断点续传的原理try{ 
断点续传的原理Thread.sleep(nSecond); 
断点续传的原理
断点续传的原理catch(Exception e) 
断点续传的原理
断点续传的原理e.printStackTrace (); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public static void log(String sMsg) 
断点续传的原理
断点续传的原理System.err.println(sMsg); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public static void log(int sMsg) 
断点续传的原理
断点续传的原理System.err.println(sMsg); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理/* 
断点续传的原理**TestMethod.java 
断点续传的原理*/ 
断点续传的原理package NetFox; 
断点续传的原理
断点续传的原理
断点续传的原理public class TestMethod { 
断点续传的原理
断点续传的原理
断点续传的原理public TestMethod() 
断点续传的原理{ ///xx/weblogic60b2_win.exe 
断点续传的原理try{ 
断点续传的原理SiteInfoBean bean 
= new SiteInfoBean("http://localhost/xx/weblogic60b2_win.exe"," L: emp","weblogic60b2_win.exe",5); 
断点续传的原理//SiteInfoBean bean 
= new SiteInfoBean("http://localhost:8080/down.zip"," L: emp","weblogic60b2_win.exe",5); 
断点续传的原理SiteFileFetch fileFetch 
= new SiteFileFetch(bean); 
断点续传的原理fileFetch.start(); 
断点续传的原理
断点续传的原理catch(Exception e){e.printStackTrace ();} 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理public static void main(String[] args) 
断点续传的原理
断点续传的原理new TestMethod(); 
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理
断点续传的原理一,最重要的一点,断点续传需要服务器的支持,这个是必要条件。 
断点续传的原理传统的FTP SERVER是不支持断点续传的,因为它不支持REST指令,传统的FTP指令(我是指服务器端指令)并不包括REST指令。 
断点续传的原理第二,客户端要知道使用REST等一系列指令来作断点续传。 
断点续传的原理看看断点续传的详细过程(FTP SERVER): 
断点续传的原理首先客户端使用REST指令来告诉FTP SERVER它需要从文件的某个点开始传,接着用STOR或者RETR命令开始传文件,大概的命令的流程如下: 
断点续传的原理TYPE I 
断点续传的原理200 Type set to I. 
断点续传的原理PASV 
断点续传的原理227 Entering Passive Mode (204,48,18,69,98,250) 
断点续传的原理REST 187392 
断点续传的原理350 Restarting at 187392. Send STORE or RETRIEVE to initiate transfer. 
断点续传的原理RETR /pub/audio/pci/maestro-3/win2k/1056.zip 
断点续传的原理150 Opening BINARY mode data connection for /pub/audio/pci/maestro-3/win2k/1056.zip (936098 bytes). 
断点续传的原理首先使用TYPE命令告诉FTP SERVER使用BINARY模式传送文件; 
断点续传的原理然后使用PASV命令告诉FTP SERVER使用被动打开模式来传送文件; 
断点续传的原理接着使用REST 187392指令告诉FTP SERVER要从文件的187392字节开始传送; 
断点续传的原理最后使用RETR指令来传送文件。 
断点续传的原理从上面可以看出,这个FTP SERVER支持REST指令,有的FTP SERVER(特别的老的)是不支持这个指令的,这时即使FTP CLIENT支持断点续传也一点用都没有! 
断点续传的原理支持断点的FTP SERVER:Serv-U FTP,还有一系列的新出现的FTP SERVER; 
断点续传的原理不支持断点的:IIS4以前版本所带的都不行,IIS5 有,不家可以测试一下,登录进FTP SERVER,然后输入REST 1000命令,看服务器是否认识,认识就是支持断点。 
断点续传的原理上面说的是FTP SERVER的断点,HTTP的断点续传是这样的: 
断点续传的原理在以前版本的HTTP SERVER也是不支持断点的,HTTP/1.1开始就支持了,具体如下: 
断点续传的原理在HTTP请求的头部信息里面,通常是这样的: 
断点续传的原理GET http://xxx.xxx.xxx.xxx/index.html HTTP/1.1 
断点续传的原理Host:www.163.net 
断点续传的原理Accept:*/* 
断点续传的原理上面是HTTP请求头的主要内容,是浏览器等客户端发给HTTP SERVER的信息。 
断点续传的原理在这个请求头里面,第一行叫做Request Line,GET叫做请求方法(通常得到一个HTML页面都是用GET,CGI等请求是用POST),http://bbs.netbuddy.org/index.html是URL,HTTP/1.1为版本号。 
断点续传的原理Host:bbs.netbuddy.org是HTTP服务器名字,这也是HTTP/1.1的新东东,以前做虚拟主机可是要一个主机名对应多个IP,现在好了断点续传的原理断点续传的原理呵呵,这个离题太远,不说了) 
断点续传的原理要做断点续传,浏览器等客户端需要在请求头里面发送 
断点续传的原理Range: bytes
=1140736- 
断点续传的原理
这样的请求,就是告诉HTTP SERVER,这个文件要从1140736字节开始传送。 
断点续传的原理最 后一点,大家看了上面的描述可能会有一个问题,那么多点传送怎么做呢?那就是多起几个线程,连接到服务器,用断点指令来传送文件,在传送的过程中,会检查 前面的(比如说第一个蚂蚁)得到的文件的部分是否超过了后面的(比如说第二个蚂蚁)的起点,相等就停前面的蚂蚁,最后再合并几个部分,就得到一个完整的文 件了
断点续传的原理
断点续传的原理----------------------------------------------
断点续传的原理C版本实现方式:
断点续传的原理
断点续传的原理3 具体实现
断点续传的原理
断点续传的原理  在实现过程中我使用了MFC的多线程和Windows的Socket,分客户端和服务器端实现。因为数据传输往往是对等的,所以需要将客户端和服务器端集成在一起,在客户端和服务器端分别实现后,这是件非常简单的工作,只需将它们集成在一起即可。下面将分别介绍客户端和服务器端的实现。
断点续传的原理
断点续传的原理  3.1 关键数据结构
断点续传的原理
断点续传的原理  文件信息数据结构 用于在服务器端和客户端之间传递文件第N块的属性信息,详细定义如下:
断点续传的原理
断点续传的原理  structfileinfo
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  int fileno; //文件号
断点续传的原理
断点续传的原理  int type; //消息类别
断点续传的原理
断点续传的原理  long len; //文件(块)长度,在客户端向服务器端发送数据时,是文件长度;
断点续传的原理
断点续传的原理  //在服务器端向客户端发送已传部分的信息时,是应该续传部分的长度;
断点续传的原理
断点续传的原理  long seek; //开始位置,标识要传输数据在原文件中的起始位置
断点续传的原理
断点续传的原理  char name[MAX_PATH_LEN];//文件名
断点续传的原理
断点续传的原理  };
断点续传的原理
断点续传的原理  发送进度记录结构 用户记录文件传输进程,详细定义如下:
断点续传的原理
断点续传的原理  structSentInfo
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  long totle; //已经成功发送数据的长度;
断点续传的原理
断点续传的原理  int block; //块标识;
断点续传的原理
断点续传的原理  long filelen; //文件总长度;
断点续传的原理
断点续传的原理  int threadno; //负责传输第N块数据的线程标识;
断点续传的原理
断点续传的原理  CString name; //文件名称
断点续传的原理
断点续传的原理  };
断点续传的原理
断点续传的原理  客户端类 客户端文件发送实例封装,用户记录客户端文件发送过程中的属性信息、已发送大小、发送线程句柄、发送线程状态、发送统计信息等,具体定义是:
断点续传的原理
断点续传的原理  classCClient:publicCObject
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  protected:
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //Attributes
断点续传的原理
断点续传的原理  public:
断点续传的原理
断点续传的原理  CClient(CString ip);
断点续传的原理
断点续传的原理  ~CClient(); 
断点续传的原理
断点续传的原理  SentInfo doinfo;
断点续传的原理
断点续传的原理  long m_index; //块索引
断点续传的原理
断点续传的原理  BOOL sendOk[BLOCK]; //块发送结束状态
断点续传的原理
断点续传的原理  CString SendFileName;
断点续传的原理
断点续传的原理  CString DestIp; //目标IP地址
断点续传的原理
断点续传的原理  THREADSTATUS SendStatus;
断点续传的原理
断点续传的原理  int GetBlockIndex(); //获取当前要传输文件块的序号,例如0,1,2…
断点续传的原理
断点续传的原理  CCriticalSection m_gCS;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //Sending File Block Thread Handles
断点续传的原理
断点续传的原理  HANDLE m_thread[BLOCK]; //Block Sending Thread Handles Array
断点续传的原理
断点续传的原理  HANDLE m_ExitThread; //WaitToExitThread Handle
断点续传的原理
断点续传的原理  HANDLE m_ProcessTrackThread;
断点续传的原理
断点续传的原理  HANDLE m_hEventKill; //User canceled Event
断点续传的原理
断点续传的原理  long m_IdxInListCtrl; //Index in ListView
断点续传的原理
断点续传的原理  long m_lBeginTimeTick;
断点续传的原理
断点续传的原理  long m_lBytesSent;
断点续传的原理
断点续传的原理  // Operations
断点续传的原理
断点续传的原理  public:
断点续传的原理
断点续传的原理  };
断点续传的原理
断点续传的原理  3.2 客户端
断点续传的原理
断点续传的原理  发送线程 用于发送由lpparam参数指定的Client对象标识的文件块数据。具体实现是:
断点续传的原理
断点续传的原理  //发送线程主函数
断点续传的原理
断点续传的原理  //并行进行的线程,针对每个要发送的文件有BLOCK个该线程
断点续传的原理
断点续传的原理  DWORDWINAPISendThread(LPVOIDlpparam)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  CClient* pClient
=(CClient*)lpparam;
断点续传的原理
断点续传的原理  
int block_index = pClient->GetBlockIndex();
断点续传的原理
断点续传的原理  
//发送文件的第m_index块
断点续传的原理
断点续传的原理  //发送线程
断点续传的原理
断点续传的原理  sockaddr_in local;
断点续传的原理
断点续传的原理  SOCKET m_socket;
断点续传的原理
断点续传的原理  int rc
=0;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  
local.sin_family=AF_INET;
断点续传的原理
断点续传的原理  
local.sin_port=htons(pMainFrm->m_FilePort);
断点续传的原理
断点续传的原理  
local.sin_addr.S_un.S_addr=inet_addr(pClient->DestIp);
断点续传的原理
断点续传的原理  
m_socket=socket(AF_INET,SOCK_STREAM,0);
断点续传的原理
断点续传的原理  
int ret;
断点续传的原理
断点续传的原理  char m_buf[MAX_BUFSIZE];
断点续传的原理
断点续传的原理  fileinfo file_info;
断点续传的原理
断点续传的原理  //Connect to Server
断点续传的原理
断点续传的原理  ret 
= connect(m_socket,(LPSOCKADDR)&local,sizeof(local));
断点续传的原理
断点续传的原理  
while((ret == SOCKET_ERROR)&&(WaitForSingleObject(pClient->m_hEventKill, 0)
断点续传的原理
断点续传的原理  ==WAIT_TIMEOUT))
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  closesocket (m_socket);
断点续传的原理
断点续传的原理  } 
断点续传的原理
断点续传的原理  file_info.len = pClient->doinfo.filelen ;
断点续传的原理
断点续传的原理  if (file_info.len 
<= 0) //已经完成传输
断点续传的原理
断点续传的原理  return 1;
断点续传的原理
断点续传的原理  file_info.seek
=0;
断点续传的原理
断点续传的原理  
file_info.type=1; //从服务器上获取文件的第index块已接收的大小
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  file_info.fileno 
= block_index; 
断点续传的原理
断点续传的原理  
strcpy(file_info.name,pClient->doinfo.name);
断点续传的原理
断点续传的原理  //发送第index块已发送大小请求
断点续传的原理
断点续传的原理  sendn(m_socket,(char*)
&file_info,PROTOCOL_HEADSIZE); 
断点续传的原理
断点续传的原理  long nRead = readn(m_socket,m_buf,PROTOCOL_HEADSIZE);
断点续传的原理
断点续传的原理  if(nRead 
<= 0)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  closesocket (m_socket);
断点续传的原理
断点续传的原理  return -1;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  fileinfo * pfile_info 
= (fileinfo*)m_buf;
断点续传的原理
断点续传的原理  
if (pfile_info->len == 0)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  closesocket (m_socket);
断点续传的原理
断点续传的原理  //block_index块是续传,且发送完毕
断点续传的原理
断点续传的原理  pClient->good[block_index] = TRUE;
断点续传的原理
断点续传的原理  return 1;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  CFile SourceFile;
断点续传的原理
断点续传的原理  SourceFile.Open(pClient->SendFileName, 
断点续传的原理
断点续传的原理  CFile::modeRead|CFile::typeBinary| CFile::shareDenyNone); 
断点续传的原理
断点续传的原理  //Seek right position of sending file
断点续传的原理
断点续传的原理  long apos=SourceFile.Seek(pfile_info->seek,CFile::begin);
断点续传的原理
断点续传的原理  int len1;
断点续传的原理
断点续传的原理  len1=pfile_info->len;
断点续传的原理
断点续传的原理  //取得已经发送的长度
断点续传的原理
断点续传的原理  if (block_index 
< BLOCK - 1)
断点续传的原理
断点续传的原理  pClient-
>doinfo.totle += pClient->doinfo.filelen / BLOCK - pfile_info->len;
断点续传的原理
断点续传的原理  else
断点续传的原理
断点续传的原理  pClient->doinfo.totle += pClient->doinfo.filelen – 
断点续传的原理
断点续传的原理  pClient->doinfo.filelen/BLOCK* (BLOCK - 1) - pfile_info->len;
断点续传的原理
断点续传的原理  int nBegin = GetTickCount();
断点续传的原理
断点续传的原理  int SendTotal = 0;
断点续传的原理
断点续传的原理  while((len1 > 0) && (WaitForSingleObject(pClient->m_hEventKill, 0) == WAIT_TIMEOUT))
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  nRead = SourceFile.Read(m_buf, (len1 
< pMainFrm->m_CurrentBlockSize) ? 
断点续传的原理
断点续传的原理  len1:pMainFrm->m_CurrentBlockSize);
断点续传的原理
断点续传的原理  int send_count=sendn(m_socket,m_buf,nRead);
断点续传的原理
断点续传的原理  float nLimit;
断点续传的原理
断点续传的原理  if(send_count
<=0)
断点续传的原理
断点续传的原理  { 
断点续传的原理
断点续传的原理  closesocket (m_socket);
断点续传的原理
断点续传的原理  SourceFile.Close();
断点续传的原理
断点续传的原理  return 1;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  len1 
= len1 - send_count;
断点续传的原理
断点续传的原理  //进度信息
断点续传的原理
断点续传的原理  pClient-
>doinfo.totle += send_count;
断点续传的原理
断点续传的原理  SendTotal += send_count;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  SourceFile.Close();
断点续传的原理
断点续传的原理  shutdown(m_socket,2);
断点续传的原理
断点续传的原理  closesocket (m_socket);
断点续传的原理
断点续传的原理  if(len1 
<= 0)pClient->good[block_index] = TRUE;
断点续传的原理
断点续传的原理  return 1;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  创建发送线程 对应要发送的文件,创建BLOCK个线程,负责发送各自的数据块。
断点续传的原理
断点续传的原理  for(inti=0;i
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  //创建线程,状态为停止状态
断点续传的原理
断点续传的原理  pClient->m_thread[i] = ::CreateThread(NULL,0,SendThread,(LPVOID)pClient,
断点续传的原理
断点续传的原理  CREATE_SUSPENDED,
&dwthread);
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  ::SetThreadPriority(pClient->m_thread[i],THREAD_PRIORITY_HIGHEST);
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  3.3 服务器端
断点续传的原理
断点续传的原理  监听函数 负责监听文件传输请求,在接受请求后,创建数据块接收线程,具体实现如下:
断点续传的原理
断点续传的原理  //监听函数
断点续传的原理
断点续传的原理  DWORDWINAPIlistenthread(LPVOIDlpparam)
断点续传的原理
断点续传的原理  { 
断点续传的原理
断点续传的原理  SOCKET pSocket=(SOCKET)lpparam;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //最多监听MAX_LISTENCOUNT个客户端连接
断点续传的原理
断点续传的原理  int rc=listen(pSocket,MAX_LISTENCOUNT);
断点续传的原理
断点续传的原理  if (rc
<0)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  //Error
断点续传的原理
断点续传的原理  return 0;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  //Listening all the incoming connections
断点续传的原理
断点续传的原理  while(1)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  SOCKET aSocket;
断点续传的原理
断点续传的原理  //Listening and Block
断点续传的原理
断点续传的原理  aSocket
=accept(pSocket,NULL,NULL);
断点续传的原理
断点续传的原理  
DWORD dwthread;
断点续传的原理
断点续传的原理  // Create Server Data Receiving Thread "Serverthread"
断点续传的原理
断点续传的原理  // And Transfers data
断点续传的原理
断点续传的原理  ::CreateThread(NULL,0, Serverthread,(LPVOID)aSocket,0,&dwthread); 
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  return 0;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  接收文件数据 负责接收由参数seek和len以及block_index标识的数据块,实现如下:
断点续传的原理
断点续传的原理  //接收文件数据
断点续传的原理
断点续传的原理  voidRecvFile(SOCKETso,CStringPeerName,CString DestFileName,long seek,
断点续传的原理
断点续传的原理  longlen,intblock_index,CFileInfoRecving*pfileinfo)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  CFile DestFile;
断点续传的原理
断点续传的原理  long fileseek 
= seek;
断点续传的原理
断点续传的原理  
long filelen = len;
断点续传的原理
断点续传的原理  
CMainFrame* pWnd = (CMainFrame*) AfxGetMainWnd();
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  if (!DestFile.Open(pWnd-
>m_DestPath + "\\IP" + PeerName + "-" + DestFileName, 
断点续传的原理
断点续传的原理  CFile::modeWrite|CFile::typeBinary| CFile::shareDenyNone))
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  DWORD error = GetLastError();
断点续传的原理
断点续传的原理  return;
断点续传的原理
断点续传的原理  }; 
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  long apos = DestFile.Seek(fileseek,CFile::begin);
断点续传的原理
断点续传的原理  char m_buf[MAX_BUFSIZE];
断点续传的原理
断点续传的原理  CString m_temp;
断点续传的原理
断点续传的原理  m_temp.Format("%s\\Temp\\IP%s-%s.%d",pWnd->m_appPath,PeerName,
断点续传的原理
断点续传的原理  DestFileName,block_index);
断点续传的原理
断点续传的原理  CFile BlockFile;
断点续传的原理
断点续传的原理  BlockFile.Open(m_temp, CFile::modeWrite | CFile::typeBinary);
断点续传的原理
断点续传的原理  while((filelen>0) && (WaitForSingleObject(pWnd->m_hEventKill, 0) == WAIT_TIMEOUT))
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  int nRead = readn(so, m_buf, (filelen > MAX_BUFSIZE) ? MAX_BUFSIZE : filelen);
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //Exited
断点续传的原理
断点续传的原理  if (nRead == 0) 
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  CString msg;
断点续传的原理
断点续传的原理  msg.Format("[SOCKET %d] Receiving file %s break(Recv 0).",so,DestFileName);
断点续传的原理
断点续传的原理  pWnd->SendMessage(WM_NEWMSG,(LPARAM)msg.GetBuffer(0),3);
断点续传的原理
断点续传的原理  msg.ReleaseBuffer();
断点续传的原理
断点续传的原理  break;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  if(nRead
<0)
断点续传的原理
断点续传的原理  { 
断点续传的原理
断点续传的原理  CString msg;
断点续传的原理
断点续传的原理  msg.Format("[SOCKET %d] Receiving file %s break.",so,DestFileName);
断点续传的原理
断点续传的原理  pWnd-
>SendMessage(WM_NEWMSG,(LPARAM)msg.GetBuffer(0),3);
断点续传的原理
断点续传的原理  msg.ReleaseBuffer();
断点续传的原理
断点续传的原理  break;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  DestFile.Write(m_buf,nRead);
断点续传的原理
断点续传的原理  filelen -= nRead;
断点续传的原理
断点续传的原理  fileseek += nRead;
断点续传的原理
断点续传的原理  BlockFile.Seek(0,CFile::begin);
断点续传的原理
断点续传的原理  BlockFile.Write(
&fileseek,sizeof(long));
断点续传的原理
断点续传的原理  BlockFile.Write(
&filelen,sizeof(long));
断点续传的原理
断点续传的原理  pfileinfo->m_seek = fileseek;
断点续传的原理
断点续传的原理  pfileinfo->m_len = filelen;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  closesocket (so);
断点续传的原理
断点续传的原理  //Current Block Received OK
断点续传的原理
断点续传的原理  BlockFile.Close();
断点续传的原理
断点续传的原理  DestFile.Close();
断点续传的原理
断点续传的原理  if (filelen 
<= 0
断点续传的原理
断点续传的原理  pfileinfo-
>canDel = true;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  初始化文件数据块信息 负责初始化文件传输时数据块的大小、开始位置等信息。具体实现是:
断点续传的原理
断点续传的原理  //初始化文件数据块信息
断点续传的原理
断点续传的原理  CFileInfoRecving*GetRecvedFileBlock(CStringPeerName,CStringFileName,long& filelen,
断点续传的原理
断点续传的原理  long
&fileseek,intblock_index)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  CString m_temp;
断点续传的原理
断点续传的原理  CMainFrame* pWnd = (CMainFrame*) AfxGetMainWnd();
断点续传的原理
断点续传的原理  m_temp.Format("%s\\temp\\IP%s-%s.%d",pWnd->m_appPath,PeerName,FileName,block_index);
断点续传的原理
断点续传的原理  FILE* fp=NULL;
断点续传的原理
断点续传的原理  CFile Blockfile;
断点续传的原理
断点续传的原理  CFile RecvFile;
断点续传的原理
断点续传的原理  long seek = fileseek;
断点续传的原理
断点续传的原理  long flen = filelen;
断点续传的原理
断点续传的原理  CString DestFile = pWnd->m_DestPath + "\\IP" + PeerName + "-" + FileName;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  bool DestFileNoExist = false;
断点续传的原理
断点续传的原理  if((fp=fopen(DestFile,"r"))==NULL)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  RecvFile.Open(DestFile,
断点续传的原理
断点续传的原理  CFile::modeCreate|CFile::modeWrite|CFile::typeBinary| CFile::shareDenyNone);
断点续传的原理
断点续传的原理  RecvFile.Close();
断点续传的原理
断点续传的原理  DestFileNoExist = true;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  if (fp) fclose(fp);
断点续传的原理
断点续传的原理  CFileInfoRecving* pfileinfo = NULL;
断点续传的原理
断点续传的原理  //如果目标文件不存在或者长度记录文件不存在,重新传
断点续传的原理
断点续传的原理  if( ((fp=fopen(m_temp,"r"))==NULL) || (DestFileNoExist))
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  //第一次接收
断点续传的原理
断点续传的原理  fileseek = block_index*(flen/BLOCK);
断点续传的原理
断点续传的原理  filelen = flen/BLOCK;
断点续传的原理
断点续传的原理  if (block_index == (BLOCK - 1)) 
断点续传的原理
断点续传的原理  filelen = flen - fileseek;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //Add To Recving File List
断点续传的原理
断点续传的原理  pfileinfo = new CFileInfoRecving();
断点续传的原理
断点续传的原理  pfileinfo->m_sFileName = FileName;
断点续传的原理
断点续传的原理  pfileinfo->m_sPeerName = PeerName;
断点续传的原理
断点续传的原理  pfileinfo->m_nBlockIndex = block_index;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  pfileinfo->m_sFileSize.Format("%d",flen);
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  seek = fileseek;
断点续传的原理
断点续传的原理  flen = filelen;
断点续传的原理
断点续传的原理  pfileinfo->m_seek = seek;
断点续传的原理
断点续传的原理  pfileinfo->m_len = flen;
断点续传的原理
断点续传的原理  pWnd->m_RecvingFileList.AddTail(pfileinfo);
断点续传的原理
断点续传的原理  Blockfile.Open(m_temp,
断点续传的原理
断点续传的原理  CFile::modeCreate|CFile::modeWrite| CFile::typeBinary | CFile::shareDenyNone);
断点续传的原理
断点续传的原理  Blockfile.Write(
&seek,sizeof(long));
断点续传的原理
断点续传的原理  Blockfile.Write(
&flen,sizeof(long));
断点续传的原理
断点续传的原理  Blockfile.Close();
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  else
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  POSITION pos = pWnd->m_RecvingFileList.GetHeadPosition();
断点续传的原理
断点续传的原理  while (pos)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  pfileinfo = pWnd->m_RecvingFileList.GetAt(pos);
断点续传的原理
断点续传的原理  if (pfileinfo)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  if ((pfileinfo->m_sFileName == FileName) &&
断点续传的原理
断点续传的原理  (pfileinfo->m_sPeerName == PeerName) &&
断点续传的原理
断点续传的原理  (pfileinfo->m_nBlockIndex == block_index))
断点续传的原理
断点续传的原理  break;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  pWnd->m_RecvingFileList.GetNext(pos);
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  Blockfile.Open(m_temp,CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone);
断点续传的原理
断点续传的原理  Blockfile.Read(
&fileseek,sizeof(long));
断点续传的原理
断点续传的原理  Blockfile.Read(
&filelen,sizeof(long));
断点续传的原理
断点续传的原理  if ((pfileinfo == NULL) || (!pos))
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  pfileinfo = new CFileInfoRecving();
断点续传的原理
断点续传的原理  pfileinfo->m_sFileName = FileName;
断点续传的原理
断点续传的原理  pfileinfo->m_sPeerName = PeerName;
断点续传的原理
断点续传的原理  pfileinfo->m_nBlockIndex = block_index;
断点续传的原理
断点续传的原理  pfileinfo->m_sFileSize.Format("%d",flen);
断点续传的原理
断点续传的原理  //Add To Recving File List
断点续传的原理
断点续传的原理  //pWnd->m_RecvingFileListCS.Lock();
断点续传的原理
断点续传的原理  pWnd->m_RecvingFileList.AddTail(pfileinfo);
断点续传的原理
断点续传的原理  //pWnd->m_RecvingFileListCS.Unlock();
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  Blockfile.Close();
断点续传的原理
断点续传的原理  pfileinfo->m_seek = fileseek;
断点续传的原理
断点续传的原理  pfileinfo->m_len = filelen;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  if (fp) fclose(fp);
断点续传的原理
断点续传的原理  return pfileinfo;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  数据接收线程 负责从客户端接收数据信息:
断点续传的原理
断点续传的原理  //数据接收线程
断点续传的原理
断点续传的原理  DWORDWINAPIServerthread(LPVOIDlpparam)
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  fileinfo* pFileInfo;
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //
断点续传的原理
断点续传的原理  char* m_buf = new char[PROTOCOL_HEADSIZE];
断点续传的原理
断点续传的原理  SOCKET pthis=(SOCKET)lpparam;
断点续传的原理
断点续传的原理  int nRead = readn(pthis,m_buf,PROTOCOL_HEADSIZE);
断点续传的原理
断点续传的原理  if( nRead 
< 0 )
断点续传的原理
断点续传的原理  {
断点续传的原理
断点续传的原理  closesocket (pthis);
断点续传的原理
断点续传的原理  return -1;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  pFileInfo 
= (fileinfo*)m_buf;
断点续传的原理
断点续传的原理  
CString MsgStr;
断点续传的原理
断点续传的原理  int addrlen;
断点续传的原理
断点续传的原理  CString FileID;
断点续传的原理
断点续传的原理  sockaddr_in* pSocket;
断点续传的原理
断点续传的原理  CFileInfoRecving* pfileinfo;
断点续传的原理
断点续传的原理  switch(pFileInfo-
>type)
断点续传的原理
断点续传的原理  { 
断点续传的原理
断点续传的原理  case 1:
断点续传的原理
断点续传的原理  //获取文件块的已接收大小
断点续传的原理
断点续传的原理  pfileinfo = 
断点续传的原理
断点续传的原理  GetRecvedFileBlock(FileID,pFileInfo->name,pFileInfo->len,pFileInfo->seek,pFileInfo->fileno);
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  nRead = sendn(pthis,(char*)pFileInfo,PROTOCOL_HEADSIZE);
断点续传的原理
断点续传的原理  if(nRead 
< 0)
断点续传的原理
断点续传的原理  { 
断点续传的原理
断点续传的原理  closesocket (pthis);
断点续传的原理
断点续传的原理  return -1;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  
断点续传的原理
断点续传的原理  //开始接收文件
断点续传的原理
断点续传的原理  RecvFile(pthis,FileID,pFileInfo-
>name,pFileInfo->seek,
断点续传的原理
断点续传的原理  pFileInfo->len,pFileInfo->fileno,pfileinfo);
断点续传的原理
断点续传的原理  closesocket(pthis);
断点续传的原理
断点续传的原理  break;
断点续传的原理
断点续传的原理  default:
断点续传的原理
断点续传的原理  break;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  delete [] m_buf;
断点续传的原理
断点续传的原理  return 0;
断点续传的原理
断点续传的原理  }
断点续传的原理
断点续传的原理  4 小结
断点续传的原理
断点续传的原理  本文简要介绍了点对点文件断点续传的多线程实现方法,有一定的使用性。限于水平,文中不当之处,敬请批评指正。
断点续传的原理
断点续传的原理
断点续传的原理

相关文章: