0

コードの読み取り/書き込みをより快適にするために、これらすべての関数をヘルパー クラスにスタックして、クライアント/サーバーのメイン ユニットでこれらのばかげた関数をすべて回避できるようにしました。インポートされたユニットに配置しました。 2 つのメイン ユニットによるものです。

たとえば、ServerSocket イベント内にいる場合は、次のように使用できます。

Socket.SendString();

  { Extend TCustomWinSocket to make it more comfterable to read and tidy code }
  TCustomWinSocketHelpher = class Helper for TCustomWinSocket
  private
    procedure SendStringLenth(StrLen: Integer);
  public
    function ReceiveStringLength: Integer;
    function ReceiveString(const StrLen: Integer): String;
    function ReceiveStream(StreamLen: Integer; Callback: TUpdateProgBarProc): TMemoryStream;

    procedure SendString(const Str: string);
    procedure SendStreamEx(ASendStream: TStream);
  end;

(*************************** TCustomWinSocketHelpher BEGIN ***************************)

function TCustomWinSocketHelpher.ReceiveString(const StrLen: Integer): String;
var
  S: UTF8String;
begin
  SetLength(S, StrLen);
  ReceiveBuf(PAnsiChar(S)^, StrLen);
  Result := UTF8ToString(S);
end;

function TCustomWinSocketHelpher.ReceiveStringLength: Integer;
begin
  ReceiveBuf(Result, SizeOf(Result));
  Result := ntohl(Result);
end;

function TCustomWinSocketHelpher.ReceiveStream(StreamLen: Integer; Callback: TUpdateProgBarProc): TMemoryStream;
const
  ChunkSize = 4096;
var
  PData: PByte;
  ReadAmount: Integer;
begin
  Result := TMemoryStream.Create;
  GetMem(PData, ChunkSize);
  try
    while StreamLen > 0 do
    begin
      ReadAmount := ReceiveBuf(PData^, Min(ChunkSize, StreamLen));
      if (ReadAmount > 0) then
      begin
        Result.WriteBuffer(PData^, ReadAmount);
        Callback(ReadAmount); // update gui
        Dec(StreamLen, ReadAmount); // update loop condition
      end else
      begin
        OutputDebugString(PChar('ReadAmount ' + Inttostr(ReadAmount)));
      end;
    end;
  finally
    FreeMem(PData);
  end;
end;

procedure TCustomWinSocketHelpher.SendStringLenth(StrLen: Integer);
begin
  StrLen := htonl(StrLen);
  SendBuf(StrLen, SizeOf(StrLen));
end;

procedure TCustomWinSocketHelpher.SendString(const Str: string);
var
  S: UTF8String;
  Len: Integer;
begin
  S := UTF8Encode(Str);
  Len := Length(S);
  SendStringLenth(Len);
  SendBuf(PAnsiChar(S)^, Len);
end;

procedure TCustomWinSocketHelpher.SendStreamEx(ASendStream: TStream);
begin
  ASendStream.Position := 0;
  SendStream(ASendStream);
end;

(*************************** TCustomWinSocketHelpher END ***************************)
4

1 に答える 1

2

はい、ヘルパー クラスを定義することは完全に安全です。

于 2013-03-14T15:33:06.997 に答える