Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Jul : another implementation if IOHandleThrottle.Send

www.cryer.info
Managed Newsgroup Archive

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;

Replies:

www.cryer.info
Managed Newsgroup Archive