紧急求助。ICS中HTTPClient 如何控制下载速度。(200分)

  • 主题发起人 主题发起人 xwings
  • 开始时间 开始时间
X

xwings

Unregistered / Unconfirmed
GUEST, unregistred user!
如题。我用ICS的HTTPClient。 响应他的OnDocData事件。 没有使用stream
我现在在OnDocData中sleep(time)就可以控制下载速度。但是此时程序的消息被阻塞。
导致程序没有响应。请有经验的高手指点一下吧。很急很急。 多谢。

300分伺候。
 
其实接收的通讯速度是由操作系统控制的,操作系统会有 buffer 暂存下来的
如果在程序里要伪延时可以用
while (条件(比如判断间隔时间)) do Application.ProcessMessages;
来实现,但注意不要在此期间再次响应 OnDocData,否则会造成重入且无法延时。
可以问一下你为什么要延时吗?
 
你的意思我明白.不过你的方法是错误的.因为Application.ProcessMessages 的时候 系统还是会去处理
ICS的OnDocData消息响应的.然后很快造成缓冲溢出异常.

我延时的原因是想控制下载速度类似FlashGet的速度限制.
 
你只要设一个全局标志啊,表示你正在响应 OnDocData
另外 FlashGet 等速度限制是在 Tcp/IP 协议一级的, socket 有流量选项的
要设 Socket 的选项,操作系统来控制,而不通过伪延时
 
设置全局变量? 呵呵.如何设置啊? 设置了ICS又如何响应?

我知道FlashGet肯定不是用这种方式限速的.不过TCP底层控制还是很麻烦的呀.
 
var
inDocData : boolean = false;

procedure OnDocData...
begin
if inDocData then exit;
inDocData := true;
try
.......
{你的处理代码}
.......
finally
inDocData := false;
end;
end;
 
呵呵.我想这样肯定不行的. 不处理的话.他还会继续下载的呀.
 
1。“伪延时”这个词我在第一帖就告诉你了,如果要真正的流量控制要在 socket 选项里设置。OK?
不管你怎么延时,对方数据来了操作系统照样还是会接收的,除非连接前 socket 属性设置好,相当于告诉对方 socket 要以怎样的流量来发送。
2。这样处理不会出错,数据会被缓存着,等你下次来取。
 
我的做法:把整个 HTTPClient 放到一个单独的线程里面,这样就不怕阻塞你的主线程了
 
beta:
这个问题俺想过,HTTPClient 本身就是基于消息机制实现的,内部自身有好几处地方都会调用 Application.ProcessMessage 这样的代码,你可以看一下它的 HttpProt.PAS
放入一个线程不太可能吧?
当然,自己做一个 socket 另当别论。
 
呵呵。单独的线程我也做过了。不行。

修改ics的消息处理代码我也改过了。还可以。

不过研究ics的源码时发现实际上ics支持速度控制的。 我倒!! 我白做了那么多工作。

现在简单了。 一个 wosocket.pause 和 resume 即可。哈哈。

问题解决。。
 
是吗,用wosocket.pause 和 resume 来控制?
比如:我想将速度限制在2K,你是如何控制的,xwings,能否说一下你的思路,
或者你程序的逻辑判断是怎么写的?谢谢!
 
procedure THttpStream.HttpCli1DocData(Sender: TObject; Buffer: Pointer;
Len: Integer);
begin
if FReady = True then Exit;
FOldTime := timeGetTime;
trace(format('Data Size: %u',[len]));
if Assigned(FOndata) then FOnData(Self,Buffer,Len);
Inc(FPosition,Len);
if FLimitedSpeed<> 0 then
DoLimitedSpeed(Len);
end;

procedure THttpStream.DoLimitedSpeed(len:Integer);
var
UseTime :DWORD;
expTime :DWORD;
begin
if FPaused then
begin
FHttpCli.WSocket.Pause;
Exit;
end;
UseTime := timeGetTime - FOldTime;
expTime := len *1000 div (LimitedSpeed*1024);
if expTime > UseTime + 2 then
begin
FHttpCli.WSocket.Pause;
Delay(min(2000,expTime - UseTime));
FHttpCli.WSocket.Resume;
end;
// DB_WriteIntln(0,expTime - UseTime);
end;

procedure Delay(m:Cardinal);
var
tick : Cardinal;
begin
tick := TimeGetTime;
while TimeGetTime - tick < m do
begin
Application.ProcessMessages;
Sleep(2);
end;
end;

应该可以理解了吧? :)
 
多谢xwings,还想问一下,
THttpStream是你自建立的一个线程吗?
 
不是线程。只是一个class
 
xwings:Your Mail Address?
 
总是退回来
 
xwings@163.net
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
756
import
I
后退
顶部