You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Indy的TIdFTPServer统计展示客户端上传下载的流量比特率汇总

实现TIdFTPServer全局流量比特率统计方案

核心实现逻辑

TIdFTPServer 本身未提供全局流量统计的内置接口,需要通过监听传输事件累加字节计数,再按时间窗口计算比特率。由于服务端每个客户端连接都运行在独立子线程,所有统计变量的读写都需要加锁保证线程安全。

步骤1:定义统计相关变量(Delphi示例)

在主窗口类中定义64位统计变量、线程锁和计时基准值:

private
  // 累计总上传字节数
  FTotalUploadBytes: Int64;
  // 累计总下载字节数
  FTotalDownloadBytes: Int64;
  // 上一次计算比特率的时间戳
  FLastCalcTime: TDateTime;
  // 上一次计算比特率时的总传输字节数
  FLastTotalBytes: Int64;
  // 当前总比特率(单位bps)
  FCurrentBitrate: Int64;
  // 线程安全锁
  FStatCrit: TCriticalSection;

步骤2:绑定传输事件并累加字节数

绑定TIdFTPServer的OnTransfer事件,每次传输数据块时累加对应统计值:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  FStatCrit := TCriticalSection.Create;
  FTotalUploadBytes := 0;
  FTotalDownloadBytes := 0;
  FLastCalcTime := Now;
  FLastTotalBytes := 0;
  // 绑定传输事件回调
  IdFTPServer1.OnTransfer := FTPTransferCallback;
end;

procedure TMainForm.FTPTransferCallback(AContext: TIdContext;
  ATransfer: TIdFTPTransfer; ABuffer: TBytes; ACount: Integer);
begin
  FStatCrit.Enter;
  try
    case ATransfer.Operation of
      ftpStore: Inc(FTotalUploadBytes, ACount); // 客户端上传
      ftpRetrieve: Inc(FTotalDownloadBytes, ACount); // 客户端下载
    end;
  finally
    FStatCrit.Leave;
  end;
end;

步骤3:定时计算比特率并更新界面

添加TTimer组件,设置更新间隔为1000ms,在定时器回调中计算比特率并更新UI:

procedure TMainForm.StatUpdateTimerTimer(Sender: TObject);
var
  LNow: TDateTime;
  LTimeDiffSec: Double;
  LTotalBytesNow: Int64;
  LBytesDelta: Int64;
begin
  FStatCrit.Enter;
  try
    LNow := Now;
    LTotalBytesNow := FTotalUploadBytes + FTotalDownloadBytes;
    LTimeDiffSec := SecondsBetween(LNow, FLastCalcTime);
    
    if LTimeDiffSec > 0 then
    begin
      LBytesDelta := LTotalBytesNow - FLastTotalBytes;
      // 字节转比特:1字节=8比特
      FCurrentBitrate := Round(LBytesDelta * 8 / LTimeDiffSec);
      
      // 更新界面显示
      lblUploadTotal.Caption := Format('累计上传:%s', [FormatFileSize(FTotalUploadBytes)]);
      lblDownloadTotal.Caption := Format('累计下载:%s', [FormatFileSize(FTotalDownloadBytes)]);
      lblTotalBitrate.Caption := Format('当前总比特率:%.2f Mbps', [FCurrentBitrate / 1024 / 1024]);
      
      // 更新统计基准值
      FLastCalcTime := LNow;
      FLastTotalBytes := LTotalBytesNow;
    end;
  finally
    FStatCrit.Leave;
  end;
end;

注意事项

  • 必须使用64位整数存储统计值,避免大流量场景下32位整数溢出
  • 所有对统计变量的读写操作都要加锁,避免多线程并发访问导致的数据异常
  • 比特率更新间隔建议设置为1~2秒,过短的更新间隔会带来不必要的性能开销
  • C++ Builder 实现逻辑完全一致,仅语法有差异

内容的提问来源于stack exchange,提问作者Денис Бердяев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 06:54:03