DELPHI如何实现下载的断点续传功能(119分)

  • 主题发起人 主题发起人 nccxl
  • 开始时间 开始时间
N

nccxl

Unregistered / Unconfirmed
GUEST, unregistred user!
本人刚接触,手头资料比较少,请知道的朋友给点帮助。<br>具体的实现代码到不重要,有个思路或者该了解的知识面的方向就可以。
 
你用的什么控件来下载?
 
我比较菜,什么控件都没用,只是想了解这方面的知识。想自己做这个功能。
 
这个一时不好说,下载也分好多种协议的。建议了解一下协议
 
一般的下载吧,走HTTP的协议就行。主要是现在也不大清楚该看哪方面的资料。
 
可以先看关于WinSock和HTTP协议的资料。其实实现起来比较简单。也就是发包,收包,存文件。断点续传就是Range改个值就行了。如果不想做比较复杂的,可以直接用IdHTTP控件,GET一下就下下来了。不过这个控件我现在还没用好。
 
参考下这些代码<br>http://www.2ccc.com/article.asp?articleid=775<br>http://www.2ccc.com/article.asp?articleid=680
 
断点续传就是把断点做为参数。再次传递时从该点开始传递
 
有没有推荐看的书呢?或者是有哪些资料文档可以看看,大家推荐一下吧。
 
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;{}filectrl,inifiles,{}Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls, ScktComp, ExtCtrls;<br><br>type<br> &nbsp;Tbuf_char=array[0..4095] of char;<br> &nbsp;Tbuf_byte=array[0..4095] of byte;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;ClientSocket1: TClientSocket;<br> &nbsp; &nbsp;Memo1: TMemo;<br> &nbsp; &nbsp;Panel1: TPanel;<br> &nbsp; &nbsp;Edit1: TEdit;<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Edit2: TEdit;<br> &nbsp; &nbsp;Button3: TButton;<br> &nbsp; &nbsp;Button4: TButton;<br> &nbsp; &nbsp;Label2: TLabel;<br> &nbsp; &nbsp;Label3: TLabel;<br> &nbsp; &nbsp;Label1: TLabel;<br> &nbsp; &nbsp;procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp; &nbsp;procedure ClientSocket1Connect(Sender: TObject;<br> &nbsp; &nbsp; &nbsp;Socket: TCustomWinSocket);<br> &nbsp; &nbsp;procedure Edit1Change(Sender: TObject);<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp; &nbsp;procedure Edit2Change(Sender: TObject);<br> &nbsp; &nbsp;procedure Button3Click(Sender: TObject);<br> &nbsp; &nbsp;procedure Button4Click(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp; &nbsp;filename1:string; //本地文件名<br> &nbsp; &nbsp;serfilename:string; &nbsp;//服务器端文件名<br> &nbsp; &nbsp;serhost1:string; &nbsp;//服务器地址<br> &nbsp; &nbsp;can_rec1:boolean; //是否可以接收<br> &nbsp; &nbsp;stop1:boolean; //是否停止<br><br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br> &nbsp;pos1:longint; //上次下载到的位置<br><br><br>implementation<br><br><br>{$R *.dfm}<br><br>function app_path1:string;<br>begin<br> &nbsp;result:=extractfilepath(application.ExeName);<br>end;<br><br><br>//接收一行数据//socket,超时,结束符<br>function socket_rec_line1(socket1:TCustomWinSocket;timeout1:integer;crlf1:string=#13#10):string;<br>var<br> &nbsp;buf1:Tbuf_char;<br> &nbsp;r1:integer;<br> &nbsp;ts1:TStringStream; //保存所有的数据<br><br> &nbsp;FSocketStream: TWinSocketStream;<br><br>begin<br><br> &nbsp;ts1:=TStringStream.Create('');<br> &nbsp;FSocketStream:= TWinSocketStream.create(Socket1, timeout1);<br><br><br> &nbsp;//while true do//下面的一句更安全,不过对本程序好象没起作用<br> &nbsp;while (socket1.Connected=true) do<br> &nbsp;begin<br><br> &nbsp; &nbsp;//确定是否可以接收数据<br> &nbsp; &nbsp;//只能确定接收的超时,可见WaitForData的源码<br> &nbsp; &nbsp;if not FSocketStream.WaitForData(timeout1) then break; //continue;<br><br> &nbsp; &nbsp;//这一句是一定要有的,以免返回的数据不正确<br> &nbsp; &nbsp;zeromemory(@buf1,sizeof(buf1));<br> &nbsp; &nbsp;r1 := FsocketStream.Read(buf1, 1); //每次只读一个字符,以免读入了命令外的数据<br> &nbsp; &nbsp;//读不出数据时也要跳出,要不会死循环<br> &nbsp; &nbsp;if r1=0 then break; //test<br> &nbsp; &nbsp;//用FsocketStream.Read能设置超时<br> &nbsp; &nbsp;//r1:=socket1.ReceiveBuf(buf1,sizeof(buf1));<br> &nbsp; &nbsp;ts1.Write(buf1,r1);<br><br> &nbsp; &nbsp;//读到回车换行符了<br> &nbsp; &nbsp;if pos(crlf1,ts1.DataString)&lt;&gt;0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;break;<br> &nbsp; &nbsp;end;<br><br> &nbsp;end;<br><br> &nbsp;result:=ts1.DataString;<br><br> &nbsp;//没有读到回车换行符,就表示有超时错,这时返回空字符串<br> &nbsp;if pos(crlf1,result)=0 then<br> &nbsp;begin<br> &nbsp; &nbsp;result:='';<br> &nbsp;end;<br><br> &nbsp;ts1.Free;<br> &nbsp;FSocketStream.Free;<br><br>end;<br><br><br> &nbsp;function get_host1(in1:string):string;<br> &nbsp;begin<br> &nbsp; &nbsp;in1:=trim(in1);<br> &nbsp; &nbsp;if pos('http://',lowercase(in1))=1 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;in1:=copy(in1,length('http://')+1,length(in1));<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;if pos('/',in1)&lt;&gt;0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;in1:=copy(in1,0,pos('/',in1)-1);<br> &nbsp; &nbsp;end; &nbsp;<br> &nbsp; &nbsp;result:=in1;<br> &nbsp;end;<br><br> &nbsp;function get_file1(in1:string):string;<br> &nbsp;begin<br> &nbsp; &nbsp;in1:=trim(in1);<br> &nbsp; &nbsp;if pos('http://',lowercase(in1))=1 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;in1:=copy(in1,length('http://')+1,length(in1));<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;if pos('/',in1)&lt;&gt;0 then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;in1:=copy(in1,pos('/',in1)+1,length(in1));<br> &nbsp; &nbsp;end; &nbsp;<br> &nbsp; &nbsp;result:=in1;<br><br> &nbsp;end;<br><br>procedure TForm1.ClientSocket1Read(Sender: TObject;<br> &nbsp;Socket: TCustomWinSocket);<br>begin<br> &nbsp;memo1.Lines.Add(socket.ReceiveText);<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br> &nbsp;url1:string;<br> &nbsp;buf1:Tbuf_byte;<br> &nbsp;rec1:longint;<br> &nbsp;f1:file;<br><br> &nbsp;cmd1:string; //这一行的内容<br> &nbsp;reclen1,real_reclen1:longint; //服务器返回的长度;实际已经收到的长度<br> &nbsp;value1:string; //标志们的值<br> &nbsp;total_len1:longint; //数据总长<br><br>begin<br> &nbsp;try<br><br> &nbsp; &nbsp;//self.filename1:='c:/temp1.dat';<br> &nbsp; &nbsp;assignfile(f1,self.filename1);<br> &nbsp; &nbsp;can_rec1:=false;<br> &nbsp; &nbsp;self.stop1:=false;<br><br> &nbsp; &nbsp;if FileExists(self.filename1)=true then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;reset(f1,1);<br> &nbsp; &nbsp; &nbsp;pos1:=filesize(f1);<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;rewrite(f1,1);<br> &nbsp; &nbsp; &nbsp;pos1:=0;<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;seek(f1,pos1);<br><br><br> &nbsp; &nbsp;ClientSocket1.Active:=false;<br> &nbsp; &nbsp;ClientSocket1.Host:=get_host1(edit1.Text);<br> &nbsp; &nbsp;ClientSocket1.Port:=80;<br><br><br> &nbsp; &nbsp;url1:='';<br><br> &nbsp; &nbsp;self.serfilename:=get_file1(edit1.Text);<br> &nbsp; &nbsp;self.serhost1:=get_host1(edit1.Text);<br><br> &nbsp; &nbsp;//取得文件长度以确定什么时候结束接收[通过&quot;head&quot;请求得到]<br><br> &nbsp; &nbsp;ClientSocket1.Active:=false;<br> &nbsp; &nbsp;ClientSocket1.Active:=true;<br> &nbsp; &nbsp;url1:='';<br> &nbsp; &nbsp;<br> &nbsp; &nbsp;url1:=url1+'HEAD /'+self.serfilename+' HTTP/1.1'+#13#10;<br><br> &nbsp; &nbsp;//不使用缓存,我附加的<br> &nbsp; &nbsp;//与以前的服务器兼容<br> &nbsp; &nbsp;url1:=url1+'Pragma: no-cache'+#13#10;<br> &nbsp; &nbsp;//新的<br> &nbsp; &nbsp;url1:=url1+'Cache-Control: no-cache'+#13#10;<br><br> &nbsp; &nbsp;//不使用缓存,我附加的_end;<br><br> &nbsp; &nbsp;url1:=url1+'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'+#13#10;<br> &nbsp; &nbsp;//下面这句必须要有<br> &nbsp; &nbsp;//url1:=url1+'Host: clq.51.net'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'Host: '+self.serhost1+#13#10;<br> &nbsp; &nbsp;url1:=url1+#13#10;<br> &nbsp; &nbsp;<br> &nbsp; &nbsp;ClientSocket1.Socket.SendText(url1);<br><br> &nbsp; &nbsp;while ClientSocket1.Active=true do<br> &nbsp; &nbsp;begin<br><br> &nbsp; &nbsp; &nbsp;if self.stop1=true then break;<br><br> &nbsp; &nbsp; &nbsp;cmd1:=socket_rec_line1(ClientSocket1.Socket,60*1000);<br><br> &nbsp; &nbsp; &nbsp;//计算文件的长度<br><br> &nbsp; &nbsp; &nbsp;if pos(lowercase('Content-Length: '),lowercase(cmd1))=1 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;value1:=copy(cmd1,length('Content-Length: ')+1,length(cmd1));<br> &nbsp; &nbsp; &nbsp; &nbsp;total_len1:=strtoint(trim(value1));<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;//计算文件的长度_end;<br><br> &nbsp; &nbsp; &nbsp;if cmd1=#13#10 then break;<br> &nbsp; &nbsp;end; &nbsp;<br><br> &nbsp; &nbsp;//取得文件长度以确定什么时候结束接收_end;<br><br> &nbsp; &nbsp;//发送get请求,以得到实际的文件数据<br><br> &nbsp; &nbsp;clientsocket1.Active:=false;<br> &nbsp; &nbsp;clientsocket1.Active:=true;<br><br> &nbsp; &nbsp;url1:='';<br><br> &nbsp; &nbsp;//url1:=url1+'GET http://clq.51.net/textfile.zip HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;//url1:=url1+'GET /textfile.zip HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'GET /'+self.serfilename+' HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*'+#13#10;<br> &nbsp; &nbsp;//应该可以不要url1:=url1+'Accept-Language: zh-cn'+#13#10;<br> &nbsp; &nbsp;//应该可以不要url1:=url1+'Accept-Encoding: gzip, deflate'+#13#10;<br><br> &nbsp; &nbsp;//不使用缓存,我附加的<br> &nbsp; &nbsp;//与以前的服务器兼容<br> &nbsp; &nbsp;//url1:=url1+'Pragma: no-cache'+#13#10;<br> &nbsp; &nbsp;//新的<br> &nbsp; &nbsp;//url1:=url1+'Cache-Control: no-cache'+#13#10;<br><br> &nbsp; &nbsp;//不使用缓存,我附加的_end;<br><br> &nbsp; &nbsp;url1:=url1+'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'+#13#10;<br> &nbsp; &nbsp;//接受数据的范围,可选<br> &nbsp; &nbsp;//url1:=url1+'RANGE: bytes=533200-'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'RANGE: bytes='+inttostr(pos1)+'-'+#13#10;<br> &nbsp; &nbsp;//下面这句必须要有<br> &nbsp; &nbsp;//url1:=url1+'Host: clq.51.net'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'Host: '+self.serhost1+#13#10;<br> &nbsp; &nbsp;//应该可以不要<br> &nbsp; &nbsp;//url1:=url1+'Connection: Keep-Alive'+#13#10;<br> &nbsp; &nbsp;url1:=url1+#13#10;<br> &nbsp; &nbsp;ClientSocket1.Socket.SendText(url1);<br><br> &nbsp; &nbsp;while ClientSocket1.Active=true do<br> &nbsp; &nbsp;begin<br><br> &nbsp; &nbsp; &nbsp;if self.stop1=true then break;<br><br> &nbsp; &nbsp; &nbsp;cmd1:=socket_rec_line1(ClientSocket1.Socket,60*1000);<br><br> &nbsp; &nbsp; &nbsp;//是否可接收<br> &nbsp; &nbsp; &nbsp;if pos(lowercase('Content-Range:'),lowercase(cmd1))=1 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;can_rec1:=true;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;//是否可接收_end;<br><br> &nbsp; &nbsp; &nbsp;//计算要接收的长度<br> &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp;if pos(lowercase('Content-Length: '),lowercase(cmd1))=1 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;value1:=copy(cmd1,length('Content-Length: ')+1,length(cmd1));<br> &nbsp; &nbsp; &nbsp; &nbsp;reclen1:=strtoint(trim(value1));<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;//计算要接收的长度_end;<br><br> &nbsp; &nbsp; &nbsp;//头信息收完了<br> &nbsp; &nbsp; &nbsp;if cmd1=#13#10 then break;<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;real_reclen1:=0;<br> &nbsp; &nbsp;while ClientSocket1.Active=true do<br> &nbsp; &nbsp;begin<br><br><br> &nbsp; &nbsp; &nbsp;if self.stop1=true then break;<br><br> &nbsp; &nbsp; &nbsp;//不能接收则退出<br> &nbsp; &nbsp; &nbsp;if can_rec1=false then break;<br><br> &nbsp; &nbsp; &nbsp;//如果文件当前的长度大于服务器标识的长度,则是出错了,不要写入文件中<br> &nbsp; &nbsp; &nbsp;if filesize(f1)&gt;=total_len1 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;showmessage('文件已经下载完毕了!');<br> &nbsp; &nbsp; &nbsp; &nbsp;break;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;zeromemory(@buf1,sizeof(buf1));<br> &nbsp; &nbsp; &nbsp;rec1:=ClientSocket1.Socket.ReceiveBuf(buf1,sizeof(buf1));<br><br> &nbsp; &nbsp; &nbsp;//如果实际收到的长度大于服务器标识的长度,则是出错了,不要写入文件中<br> &nbsp; &nbsp; &nbsp;if real_reclen1&gt;=reclen1 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;showmessage('文件已经下载完毕了!');<br> &nbsp; &nbsp; &nbsp; &nbsp;break;<br><br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;//如果当前的长度大于服务器标识的长度,则是出错了,不要写入文件中<br> &nbsp; &nbsp; &nbsp;if pos1=reclen1 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;showmessage('文件已经下载完毕了!');<br> &nbsp; &nbsp; &nbsp; &nbsp;break;<br><br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;blockwrite(f1,buf1,rec1);<br><br> &nbsp; &nbsp; &nbsp;real_reclen1:=real_reclen1+rec1;<br><br> &nbsp; &nbsp; &nbsp;Label1.Caption:=FormatFloat('#,##',real_reclen1)+'/'+FormatFloat('#,##',reclen1);<br> &nbsp; &nbsp; &nbsp;Label1.Caption:=Label1.Caption+'-&gt;'+inttostr(trunc((real_reclen1/reclen1)*100))+'%';<br> &nbsp; &nbsp; &nbsp;application.ProcessMessages;<br><br><br><br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;closefile(f1);<br> &nbsp; &nbsp;showmessage('ok');<br><br> &nbsp; &nbsp;//发送get请求,以得到实际的文件数据_end;<br><br> &nbsp; &nbsp;ClientSocket1.Active:=false;<br> &nbsp; &nbsp;<br> &nbsp;except<br> &nbsp; &nbsp;closefile(f1);<br> &nbsp; &nbsp;showmessage('discon...');<br> &nbsp;end;<br><br><br>end;<br><br>procedure TForm1.ClientSocket1Connect(Sender: TObject;<br> &nbsp;Socket: TCustomWinSocket);<br>var<br> &nbsp;url1:string; &nbsp;<br>begin<br>{ &nbsp;url1:='';<br><br> &nbsp;url1:=url1+'GET http://clq.51.net/textfile.zip HTTP/1.1'+#13#10;<br> &nbsp;url1:=url1+'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*'+#13#10;<br> &nbsp;//应该可以不要url1:=url1+'Accept-Language: zh-cn'+#13#10;<br> &nbsp;//应该可以不要url1:=url1+'Accept-Encoding: gzip, deflate'+#13#10;<br><br> &nbsp;//不使用缓存,我附加的<br> &nbsp;//与以前的服务器兼容<br> &nbsp;url1:=url1+'Pragma: no-cache'+#13#10;<br> &nbsp;//新的<br> &nbsp;url1:=url1+'Cache-Control: no-cache'+#13#10;<br><br> &nbsp;//不使用缓存,我附加的_end;<br><br> &nbsp;url1:=url1+'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'+#13#10;<br> &nbsp;//接受数据的范围,可选<br> &nbsp;url1:=url1+'RANGE: bytes=533200-'+#13#10;<br> &nbsp;//下面这句必须要有<br> &nbsp;url1:=url1+'Host: clq.51.net'+#13#10;<br> &nbsp;url1:=url1+'Connection: Keep-Alive'+#13#10;<br> &nbsp;url1:=url1+#13#10;<br> &nbsp;ClientSocket1.Socket.SendText(url1);<br><br> }<br>end;<br><br>procedure TForm1.Edit1Change(Sender: TObject);<br>var<br> &nbsp;ini1:tinifile;<br>begin<br> &nbsp;ini1:=tinifile.Create(app_path1+'sys1.ini');<br> &nbsp;ini1.WriteString('file1','host1',edit1.Text);<br><br> &nbsp;ini1.Free;<br><br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br> &nbsp;ini1:tinifile;<br>begin<br> &nbsp;ini1:=tinifile.Create(app_path1+'sys1.ini');<br> &nbsp;edit1.Text:=ini1.ReadString('file1','host1',edit1.Text);<br> &nbsp;self.filename1:=ini1.ReadString('file1','filename1','c:/temp1.dat');<br> &nbsp;edit2.Text:=self.filename1;<br> &nbsp;//pos1:=filesize(<br> &nbsp;ini1.Free;<br><br><br>end;<br><br>procedure TForm1.Edit2Change(Sender: TObject);<br>var<br> &nbsp;ini1:tinifile;<br>begin<br> &nbsp;ini1:=tinifile.Create(app_path1+'sys1.ini');<br> &nbsp;ini1.WriteString('file1','filename1',edit2.Text);<br><br> &nbsp;self.filename1:=edit2.Text;<br> &nbsp;ini1.Free;<br><br>end;<br><br>procedure TForm1.Button3Click(Sender: TObject);<br>var<br> &nbsp;url1:string;<br> &nbsp;buf1:Tbuf_byte;<br> &nbsp;rec1:longint;<br> &nbsp;f1:file;<br><br> &nbsp;cmd1:string; //这一行的内容<br> &nbsp;reclen1,real_reclen1:longint; //服务器返回的长度;实际已经收到的长度<br> &nbsp;value1:string; //标志们的值<br><br>begin<br> &nbsp; &nbsp;self.stop1:=false;<br><br> &nbsp; &nbsp;ClientSocket1.Active:=false;<br> &nbsp; &nbsp;ClientSocket1.Host:=get_host1(edit1.Text);<br> &nbsp; &nbsp;ClientSocket1.Port:=80;<br> &nbsp; &nbsp;ClientSocket1.Active:=true;<br><br> &nbsp; &nbsp;url1:='';<br><br> &nbsp; &nbsp;self.serfilename:=get_file1(edit1.Text);<br> &nbsp; &nbsp;self.serhost1:=get_host1(edit1.Text);<br> &nbsp; &nbsp;//url1:=url1+'GET http://clq.51.net/textfile.zip HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;//url1:=url1+'GET /textfile.zip HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'GET /'+self.serfilename+' HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;//url1:=url1+'HEAD /'+self.serfilename+' HTTP/1.1'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*'+#13#10;<br> &nbsp; &nbsp;//应该可以不要<br> &nbsp; &nbsp;//url1:=url1+'Accept-Language: zh-cn'+#13#10;<br> &nbsp; &nbsp;//应该可以不要<br> &nbsp; &nbsp;//url1:=url1+'Accept-Encoding: gzip, deflate'+#13#10;<br><br> &nbsp; &nbsp;//不使用缓存,我附加的<br> &nbsp; &nbsp;//与以前的服务器兼容<br> &nbsp; &nbsp;//url1:=url1+'Pragma: no-cache'+#13#10;<br> &nbsp; &nbsp;//新的<br> &nbsp; &nbsp;//url1:=url1+'Cache-Control: no-cache'+#13#10;<br><br> &nbsp; &nbsp;//不使用缓存,我附加的_end;<br><br> &nbsp; &nbsp;url1:=url1+'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)'+#13#10;<br> &nbsp; &nbsp;//接受数据的范围,可选<br> &nbsp; &nbsp;//url1:=url1+'RANGE: bytes=533200-'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'RANGE: bytes='+inttostr(533263)+'-533263'+#13#10;<br> &nbsp; &nbsp;//下面这句必须要有<br> &nbsp; &nbsp;//url1:=url1+'Host: clq.51.net'+#13#10;<br> &nbsp; &nbsp;url1:=url1+'Host: '+self.serhost1+#13#10;<br> &nbsp; &nbsp;//应该可以不要<br> &nbsp; &nbsp;//url1:=url1+'Connection: Keep-Alive'+#13#10;<br> &nbsp; &nbsp;url1:=url1+#13#10;<br> &nbsp; &nbsp;ClientSocket1.Socket.SendText(url1);<br><br><br> &nbsp; &nbsp;//while &nbsp;ClientSocket1.Active=true do<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;zeromemory(@buf1,sizeof(buf1));<br> &nbsp; &nbsp; &nbsp;rec1:=ClientSocket1.Socket.ReceiveBuf(buf1,sizeof(buf1));<br><br> &nbsp; &nbsp; &nbsp;real_reclen1:=real_reclen1+rec1;<br><br> &nbsp; &nbsp; &nbsp;memo1.Lines.Add(strpas(@buf1));<br><br> &nbsp; &nbsp; &nbsp;application.ProcessMessages;<br> &nbsp; &nbsp; &nbsp;//if self.stop1=true then break;<br> &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp;ClientSocket1.Active:=false;<br><br> &nbsp; &nbsp;showmessage('ok');<br><br><br>end;<br><br>procedure TForm1.Button4Click(Sender: TObject);<br>begin<br> &nbsp;self.stop1:=true;<br>end;<br><br>end.
 
我用<br>IdHTTP1.Response.RawHeaders.Values['Content-Length'];<br>IdHTTP1.Request.CustomHeaders.Clear;<br>IdHTTP1.Request.CustomHeaders.Add('Range: bytes=0-'+IntToStr(mBuffer)+#13#10);<br>IdHTTP1.Get(FileURL,mStream);<br>方法取,好象最后一次的mStream的内容很奇怪,很大。<br>为什么啊?
 
什么叫最后一次?你一共用了几次啊?都是从0开始?
 
我设置了一个BUFFER,每次请求BUFFER长度的内容。前面都是正常的。就是最后一次,或者最后一两次不正常。不明白什么原因。
 
把代码贴出来看看吧,按理说不会有这种问题的
 
function TFDownLoadEasy.GetFileBody(FileURL: string): Boolean;<br>var <br> &nbsp;mStream:TFileStream;<br> &nbsp;mCount:int64;<br> &nbsp;mFileSize:int64;<br> &nbsp;mDownLoadSize:int64;<br> &nbsp;mBuffer:integer;<br> &nbsp;I:integer;<br>begin<br> &nbsp;mBuffer:=1024*BlockSize;<br> &nbsp;mFileSize:=GetFileSize(FileUrl); &nbsp;<br> &nbsp;<br> &nbsp;mCount:=mFileSize div mBuffer;<br> &nbsp;if mCount*mBuffer &lt; mFileSize then mCount:=mCount+1;<br> &nbsp;<br> &nbsp;ProgressBar1.Position:=0;<br> &nbsp;ProgressBar1.Min:=0;<br> &nbsp;ProgressBar1.Max:=mCount;<br><br> &nbsp;FileName:= GetLastName(FileURL,'/'); <br> &nbsp;try<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp;mDownLoadSize:=0;<br> &nbsp; &nbsp; &nbsp;FDownLoadEasy.ListBox2.Items.Add('一共要循环:'+IntToStr(mCount));<br> &nbsp; &nbsp; &nbsp;//下载<br> &nbsp; &nbsp; &nbsp;IdHTTP1.Response.RawHeaders.Values['Content-Length'];<br> &nbsp; &nbsp; &nbsp;for I := 1 to mCount do<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;IdHTTP1.Request.CustomHeaders.Clear; &nbsp;//清除<br> &nbsp; &nbsp; &nbsp; &nbsp;if I=1 then<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mStream:=TFileStream.Create(FileName,fmCreate);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IdHTTP1.Request.CustomHeaders.Add('Range: bytes=0-'+IntToStr(mBuffer)+#13#10);<br> &nbsp; &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp; &nbsp;else if I&lt;mCount then begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mStream:=TFileStream.Create(FileName,fmOpenWrite);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IdHTTP1.Request.CustomHeaders.Add('Range: bytes='+IntToStr(I*mBuffer+1)+'-'+IntToStr((I+1)*mBuffer)+#13#10);<br> &nbsp; &nbsp; &nbsp; &nbsp;end<br> &nbsp; &nbsp; &nbsp; &nbsp;else begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mStream:=TFileStream.Create(FileName,fmOpenWrite);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IdHTTP1.Request.CustomHeaders.Add('Range: bytes='+IntToStr(I*mBuffer+1)+'-'+IntToStr(mFileSize)+#13#10);<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp; &nbsp;IdHTTP1.Get(FileURL,mStream);<br> &nbsp; &nbsp; &nbsp; &nbsp;mDownLoadSize:=mDownLoadSize+mStream.Size;<br> &nbsp; &nbsp; &nbsp; &nbsp;FDownLoadEasy.ListBox1.Items.Add('第'+IntToStr(I)+'次循环,下载文件长度:'+IntToStr(mStream.Size));<br> &nbsp; &nbsp; &nbsp; &nbsp;FDownLoadEasy.ListBox2.Items.Add('第'+IntToStr(I)+'次循环,已经下载文件长度:'+IntToStr(mDownLoadSize));<br> &nbsp; &nbsp; &nbsp; &nbsp;ProgressBar1.StepBy(1);<br> &nbsp; &nbsp; &nbsp; &nbsp;//FDownLoadEasy.Refresh;<br> &nbsp; &nbsp; &nbsp; &nbsp;ListBox1.Refresh;<br> &nbsp; &nbsp; &nbsp; &nbsp;ListBox2.Refresh;<br> &nbsp; &nbsp; &nbsp; &nbsp;ProgressBar1.Refresh;<br> &nbsp; &nbsp; &nbsp; &nbsp;FreeAndNil(mStream);<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;Result:=True;<br> &nbsp; &nbsp; &nbsp;MessageBox(handle,'下载成功','下载提示',MB_OK);<br> &nbsp; &nbsp;except on E: Exception do<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;Result:=False;<br> &nbsp; &nbsp; &nbsp; &nbsp;ShowMessage('下载失败,原因是:'+e.Message);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;end;<br> &nbsp;finally<br> &nbsp; &nbsp;//FreeAndNil(mStream);<br> &nbsp; &nbsp;IdHTTP1.Disconnect;<br> &nbsp;end;<br>end;
 
。。。你的Range写错了<br>'Range: bytes='+IntToStr((I-1)*mBuffer+1)+'-'+IntToStr(I*mBuffer)+#13#10;<br>'Range: bytes='+IntToStr((I-1)*mBuffer+1)+'-'+IntToStr(mFileSize)+#13#10
 
错在哪里了?应该怎么写呢?
 
我已经写了该怎么改了啊。你看看你运行时rangestart和rangeend的值都是什么!!!<br>如果rangestart&gt;rangeend的话,就从头下文件了
 
哦,原来如此,非常感谢。
 
多人接受答案了。
 

Similar threads

回复
0
查看
1K
不得闲
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部