Измерение сетевого трафика с помощью Indy - PullRequest
5 голосов
/ 18 февраля 2009

Я использую TIdTCPCmdServer для обработки всего взаимодействия с клиентскими приложениями. Я хотел бы, чтобы мой сервер регистрировал все виды вещей, включая сетевой трафик. Есть ли простой или умный способ узнать, сколько байтов TCPCmdServer фактически получил и отправил? Я могу думать только о коде как

ASender.SendReply;
Inc (FTraffic, Sizeof (ASender.NormalReply.Code) +
               Sizeof (Char) * ASender.NormalReply.Text.Length));

, что, на мой взгляд, крайне некрасиво, потому что эти обновления трафика будут распространяться по всему моему коду, а также довольно сложны.

Есть предложения?

Спасибо за вашу помощь.

Ответы [ 3 ]

7 голосов
/ 18 февраля 2009

Посмотрите на классы перехвата Инди. Вы должны иметь возможность создать собственный класс перехвата, который переопределяет методы Receive () и Send (), и в дополнение к вызову методов базового класса реализует расчет трафика. Уже есть классы перехвата для ведения журнала, вы должны подключить свой пользовательский класс таким же образом.

Документация TIdConnectionIntercept должна быть хорошей отправной точкой. Существует также очень простой пример здесь о том, как создать и подключить перехват во время выполнения.

4 голосов
/ 18 февраля 2009

Оберните TCPCmdServer в класс, который регистрирует трафик.

Вы можете получить свой класс из TCPCmdServer и переопределить методы отправки и получения, если они виртуальные.

Что-то вроде:

type
  TTcpCmdServerWithLogging = class(TTcpCmdServer)
    ...
    procedure SendReply; override;

implementation
    procedure SendReply;
    begin
      inherited SendReply;
      Inc (FTraffic, Sizeof (NormalReply.Code) +
           Sizeof (Char) * NormalReply.Text.Length)); 
    end;

Если они не виртуальные, то создайте новый класс, который создает экземпляр TCPCmdServer и предоставляет необходимые методы и свойства.

3 голосов
/ 18 февраля 2009

Большое спасибо вам обоим за ваши ответы. Я решил реализовать его так, как это описал mghie - путем реализации собственного класса перехватчиков для моих соединений. Просто для тех, кто заинтересован в решении, я приведу здесь некоторый исходный код:

type
  TCountTrafficInterceptor = class (TIdConnectionIntercept)
  public
    type TIntPointer = ^Longint;
  private
    FTraffic : TIntPointer;
  public
    constructor Create (TrafficVar : TIntPointer);
    procedure Send (var ABuffer : TIdBytes); override;
    procedure Receive (var ABuffer : TIdBytes); override;
  end;

constructor TCountTrafficInterceptor.Create (TrafficVar : TIntPointer);
begin
  FTraffic := TrafficVar;
end;

procedure TCountTrafficInterceptor.Send (var ABuffer : TIdBytes);
begin
  inherited Send (ABuffer);
  FTraffic^ := FTraffic^ + Length (ABuffer);
end;

procedure TCountTrafficInterceptor.Receive (var ABuffer : TIdBytes);
begin
  inherited Receive (ABuffer);
  FTraffic^ := FTraffic^ + Length (ABuffer);
end;

А в методе OnConnect TIdTCPCmdServer:

AContext.Connection.IOHandler.Intercept := 
  TCountTrafficInterceptor.Create (@FNetworkTraffic);

Отлично работает, именно то решение, которое я искал. Еще раз спасибо за ваши ответы.

Кстати: как я могу использовать (в) знак в моих сообщениях? Я всегда получаю цитату из блока, когда пытаюсь его набрать ...

...