zoukankan      html  css  js  c++  java
  • 简单的缓冲区助手类

    //代码修改于 ICS 网络通信控件 中的TBuff类
     
        在某些有性能要求的地方,我们会开辟一块缓冲区,也就是分配一块内存,数据在都在此内存中操作,避免频繁的内存分配释放操作。
    尤其在写服务器端程序时,这点显得非常重要,如果是普通的客户端程序,本文所说的方法,就不要考虑了,毕竟是操作有些繁琐。
    这个助手类的目的是提高性能,同时还有个特点,助手类内部会进行内存边界的检测,保证在往缓冲区内写数据的时候,不会发生溢出,
    听过说 著名的“缓冲区溢出”攻击吧。另外一个特点是,缓冲区的大小是在创建的时候,一次分配好,而不能进行修改。目的是配合内存
    池使用,减少内存碎片的产生。但类的内部提供了,动态改变缓冲区大小的功能。只不过在这里被屏蔽掉了。要恢复此功能,很简单
    修改代码如下: 
     
      1 unit WSockBuf;
      2 interface
      3 uses
      4   SysUtils;
      5 type
      6   TFixedBuffer = class
      7   private
      8     FBuf      : Pointer;
      9     FBufSize  : Integer;
     10     FWrCount  : Integer;
     11     FRdCount  : Integer;
     12     procedure   SetBufSize(newSize : Integer);
     13    // function    Remove(Len : Integer) : Integer;
     14     function    Peek(var Len : Integer) : Pointer;
     15   public
     16     procedure   Clear();
     17     constructor Create(nSize : Integer=4096); virtual;
     18     destructor  Destroy; override;
     19     function    Write(Data : Pointer; Len : Integer) : Integer;
     20     function    WriteStr(const Data:string):Integer;
     21     function    Read(Data : Pointer; Len : Integer) : Integer;
     22     function    ReadStr(Len:Integer=0):string; //Len <=0,读取全部数据
     23   public
     24     property    Buf:Pointer read FBuf;
     25     property    Position:Integer read FWrCount;
     26     property    BufSize : Integer read FBufSize;// write SetBufSize;
     27   end;
     28 implementation
     29 
     30 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
     31 constructor TFixedBuffer.Create(nSize : Integer);
     32 begin
     33   inherited Create;
     34   FWrCount  := 0;
     35   FRdCount  := 0;
     36   SetBufSize(nSize);
     37 end;
     38 
     39 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
     40 destructor TFixedBuffer.Destroy;
     41 begin
     42     if Assigned(Buf) then
     43         FreeMem(Buf, FBufSize);
     44     inherited Destroy;
     45 end;
     46 
     47 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
     48 procedure TFixedBuffer.SetBufSize(newSize : Integer);
     49 var
     50     newBuf : Pointer;
     51 begin
     52     if newSize <= 0 then
     53         newSize := 1514;
     54     if newSize = FBufSize then
     55         Exit;
     56     if FWrCount = FRdCount then begin
     57         { Buffer is empty }
     58         if Assigned(Buf) then
     59             FreeMem(Buf, FBufSize);
     60         FBufSize := newSize;
     61         GetMem(FBuf, FBufSize);
     62     end
     63     else begin
     64         { Buffer contains data }
     65         GetMem(newBuf, newSize);
     66         Move(Buf^, newBuf^, FWrCount);
     67         if Assigned(Buf) then
     68             FreeMem(Buf, FBufSize);
     69         FBufSize := newSize;
     70         FBuf      := newBuf;
     71     end;
     72 end;
     73 
     74 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
     75 function TFixedBuffer.Write(Data : Pointer; Len : Integer) : Integer;
     76 var
     77     Remaining : Integer;
     78     Copied    : Integer;
     79 begin
     80     Remaining := FBufSize - FWrCount;
     81     if Remaining <= 0 then
     82         Result := 0
     83     else begin
     84         if Len <= Remaining then
     85             Copied := Len
     86         else
     87             Copied := Remaining;
     88         Move(Data^, (PChar(Buf) + FWrCount)^, Copied);
     89         FWrCount := FWrCount + Copied;
     90         Result  := Copied;
     91     end;
     92 end;
     93 
     94 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
     95 function TFixedBuffer.Read(Data : Pointer; Len : Integer) : Integer;
     96 var
     97     Remaining : Integer;
     98     Copied    : Integer;
     99 begin
    100     Remaining := FWrCount - FRdCount;
    101     if Remaining <= 0 then
    102         Result := 0
    103     else begin
    104         if Len <= Remaining then
    105             Copied := Len
    106         else
    107             Copied := Remaining;
    108         Move((PChar(Buf) + FRdCount)^, Data^, Copied);
    109         FRdCount := FRdCount + Copied;
    110         if FRdCount = FWrCount then begin
    111             FRdCount := 0;
    112             FWrCount := 0;
    113         end;
    114         Result := Copied;
    115     end;
    116 end;
    117 
    118 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
    119 function TFixedBuffer.Peek(var Len : Integer) : Pointer;
    120 var
    121     Remaining : Integer;
    122 begin
    123     Remaining := FWrCount - FRdCount;
    124     if Remaining <= 0 then begin
    125         Len    := 0;
    126         Result := nil;
    127     end
    128     else begin
    129         Len    := Remaining;
    130         Result := Pointer(PChar(Buf) + FRdCount);
    131     end;
    132 end;
    133 (*
    134 function TFixedBuffer.Remove(Len : Integer) : Integer;
    135 var
    136     Remaining : Integer;
    137     Removed   : Integer;
    138 begin
    139     Remaining := FWrCount - FRdCount;
    140     if Remaining <= 0 then
    141         Result := 0
    142     else begin
    143         if Len < Remaining then
    144             Removed := Len
    145         else
    146             Removed := Remaining;
    147         FRdCount := FRdCount + Removed;
    148         if FRdCount = FWrCount then begin
    149             FRdCount := 0;
    150             FWrCount := 0;
    151         end;
    152         Result := Removed;
    153     end;
    154 end;
    155 *)
    156 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
    157 function TFixedBuffer.WriteStr(const Data: string): Integer;
    158 begin
    159   Result := Write(Pointer(Data),Length(Data));
    160 end;
    161 function TFixedBuffer.ReadStr(Len: Integer): string;
    162 begin
    163   if Len <= 0 then len := system.MaxLongint;
    164   Peek(Len);
    165   if Len > 0 then
    166   begin
    167     SetLength(Result,Len);
    168     Read(Pointer(Result),Len);
    169   end
    170   else Result := '';
    171 end;
    172 procedure TFixedBuffer.Clear;
    173 begin
    174   FWrCount  := 0;
    175   FRdCount  := 0;
    176 end;
  • 相关阅读:
    MySql学习2
    Java学习:JDBC
    MySql学习
    Java学习:网络编程
    Java学习:反射
    Java学习:多线程(2)
    Java学习:多线程
    .net后台webclient用post方式发送文件和数据
    实用
    day&day
  • 原文地址:https://www.cnblogs.com/lwm8246/p/2756253.html
Copyright © 2011-2022 走看看