Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Jul : another implementation if IOHandleThrottle.Send
| Subject: | another implementation if IOHandleThrottle.Send |
| Posted by: | "York" (nospam@nospam.com) |
| Date: | Sun, 29 Jul 2007 07:54:05 |
Hello,
The current implementation of IOHandletThrottle may not be working
precisely.
It takes a buffer and sends it using the chained handler send method.
If the time for sending is less than 1000ms then it waits up to 1000ms else
it does not. This however is working correctly if the buffer to be sent is
less than or equal to the BytesPerSecond. If it is higher than that it send
without splitting the buffer into smaller portions of BytesPerSecond each.
So I am sugesting another implementation of the TIdIOHandlerThrottle.Send
method which takes a buffer and splits it into portions and sends each
portion.
I am using this approach quite successfully and it really shows a relatively
precise bandwidth ballancing... Please let me know what your openion on this
is?
Thank you
function TIdIOMyCustomHandlerThrottle.Send(var ABuf; ALen: Integer):
Integer;
var
SendTime: Cardinal;
Buf: Pointer;
lcNumBlocks: Integer;
lcLastBlockSize: Integer;
I, j: Integer;
lcBPS: Integer;
begin
Result := 0;
if Assigned(FChainedHandler) then
begin
lcBPS := BytesPerSec div 2;
{let us calculate for 500ms but not for 1000s.
A smaller value could even be better for server implementations where
multiple connections should be sending at one and the same time}
if (lcBPS > 0) then
begin
GetMem(Buf, ALen);
try
Move(ABuf, Buf^, ALen);
lcNumBlocks := ALen div lcBPS;
lcLastBlockSize := ALen - lcNumBlocks * lcBPS;
i := 1;
j := 0;
while j < ALen - 1 do
begin
SendTime := IdGlobal.GetTickCount;
if (i <= lcNumBlocks) and (lcNumBlocks > 0) then
begin
Result := Result + FChainedHandler.Send( Pointer((Longint(Buf) +
j))^, lcBPS);
j := j + lcBPS;
end
else begin
Result := Result + FChainedHandler.Send( Pointer((Longint(Buf) +
j))^, lcLastBlockSize);
j := j + lcLastBlockSize;
end;
SendTime := GetTickDiff(SendTime, IdGlobal.GetTickCount);
if SendTime < 500 then
begin
IdGlobal.Sleep(500 - SendTime);
end;
inc(i);
end;
finally
FreeMem(Buf, ALen);
end;
end
else begin
Result := FChainedHandler.Send(ABuf, ALen);
end;
end
else begin
Result := 0;
end;
end;