iocp 非阻塞Socket异步接收限速

网上找遍了也没找到关于异步非阻塞Socket的限速资料,于是,自己写了一份

限速100M/S,误差15M/S

限速50M/S,误差5M/S

限速10M/S,误差0.3M/S

限速5M/S,误差0.02M/S

限速越小,精度越准



function TJsTCPContext.PostWSARecvEvent(IoReQuest:TJsIoReQuest;var ErrorCode:Cardinal):Boolean;
var dwFlags,dwSize:Cardinal;
  UseSleep:Boolean;
  SleepTime,SleepStartTime,SleepEndTime,i:Int64;
begin
  ErrorCode:=0;
  Result:=not Disconnecting;
  if not Result then Exit;
  dwFlags:=0;
  dwSize:=0;
  IoReQuest.SetupRead;
  IoReQuest.SetOperation(IRecv);
  IoReQuest.Socket:=FSocket;
  IoReQuest.Context:=Self;
  QueryPerformanceCounter(SpeedTotal.RecvEndTime);
  if SpeedTotal.Limit_Recv_Speed<>0 then begin
    (*
    限速小于10M/S时,使用休眠,减少CPU占用,提升准确度(大量Socket同时传输时,会影响吞吐量)
    Sleep精度太大,超过10M时,会影响计算结果,导致结果偏差过大

    限速大于10M/S时,不使用休眠,但会增加CPU占用
    *)
    UseSleep:=SpeedTotal.Limit_Recv_Speed<=(1024*1024*10);
    if UseSleep then begin
      QueryPerformanceCounter(SleepStartTime);
      uSleep(1);
      QueryPerformanceCounter(SleepEndTime);
      SleepTime:=Trunc((SleepEndTime-SleepStartTime)*1000*1000/iFreq);
    end;
    //接收一次使用多少微秒
    SpeedTotal.RecvUseTime:=Trunc((SpeedTotal.RecvEndTime-SpeedTotal.RecvStartTime)*1000*1000/iFreq);
    if UseSleep then
      i:=Trunc((SpeedTotal.Limit_Recv_Speed/(1000*1000))*(SpeedTotal.RecvUseTime+SleepTime))
    else
      //根据限速条件,估算每次接收要准备多大的缓冲区,才能达到限速上限
      i:=Trunc((SpeedTotal.Limit_Recv_Speed/(1000*1000))*(SpeedTotal.RecvUseTime));
    //本次接收大小=(限速大小/(1000000微秒,即1秒))*接收一次的微秒耗时
    if (i<=0) then i:=1
    else if (i>Max_PackSize) then
      i:=Max_PackSize;
    IoReQuest.FWSABuf.len:=i;
  end;
  QueryPerformanceCounter(SpeedTotal.RecvStartTime);
  Result:=WSARecv(FSocket,@IoReQuest.FWSABuf,1,dwSize,dwFlags,PWSAOverlapped(@IoReQuest.IOData),nil)<>Socket_Error;
  if not Result then begin
    ErrorCode:=WSAGetLastError;
    Result:=ErrorCode=WSA_IO_PENDING;
  end;
  if Result then begin
    {$IFDEF Calc_IO_Count}
    InterlockedIncrement(Recv_IO_Count);
    {$ENDIF}
    InterlockedIncrement(Pending_IO_Count);
  end;
end;


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值