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

я проблемы с получением массива байтов, связанного с файлом PNG. Когда код выполняется вOnClientRead событие работает нормально, уже при передаче для потока происходит ошибкаMemoryStream что говорит:

Недостаточно памяти при расширении потока памяти.

С этой точки зрения:

if SD.State = ReadingSize then

Я хочу знать, как решить эту конкретную проблему, а также как я могу проверить, получаю ли я данные, которые содержат файл или простойString?

Код:

type
  TSock_Thread = class(TThread)
  private
    Socket: TCustomWinSocket;
  public
    constructor Create(aSocket: TCustomWinSocket);
    procedure Execute; override;
  end;

type
  TInt32Bytes = record
    case Integer of
      0: (Bytes: array[0..SizeOf(Int32)-1] of Byte);
      1: (Value: Int32);
  end;

  TSocketState = (ReadingSize, ReadingStream);

  TSocketData = class
  public
    Stream: TMemoryStream;
    Png: TPngImage;
    State: TSocketState;
    Size: TInt32Bytes;
    Offset: Integer;
    constructor Create;
    destructor Destroy; override;
  end;

 { ... }

constructor TSock_Thread.Create(aSocket: TCustomWinSocket);
begin
  inherited Create(true);
  Socket := aSocket;
  FreeOnTerminate := true;
end;

procedure TSock_Thread.Execute;
var
  s: String;
  BytesReceived: Integer;
  BufferPtr: PByte;
  SD: TSocketData;
  Item: TListItem;
begin
  inherited;

  while Socket.Connected do
  begin
    if Socket.ReceiveLength > 0 then
    begin
      s := Socket.ReceiveText;

     { SD := TSocketData(Socket.Data);

      if SD.State = ReadingSize then
      begin
        while SD.Offset < SizeOf(Int32) do
        begin
          BytesReceived := Socket.ReceiveBuf(SD.Size.Bytes[SD.Offset],
            SizeOf(Int32) - SD.Offset);
          if BytesReceived <= 0 then
            Exit;
          Inc(SD.Offset, BytesReceived);
        end;
        SD.Size.Value := ntohl(SD.Size.Value);
        SD.State := ReadingStream;
        SD.Offset := 0;
        SD.Stream.Size := SD.Size.Value;
      end;

      if SD.State = ReadingStream then
      begin
        if SD.Offset < SD.Size.Value then
        begin
          BufferPtr := PByte(SD.Stream.Memory);
          Inc(BufferPtr, SD.Offset);
          repeat
            BytesReceived := Socket.ReceiveBuf(BufferPtr^,
              SD.Size.Value - SD.Offset);
            if BytesReceived <= 0 then
              Exit;
            Inc(BufferPtr, BytesReceived);
            Inc(SD.Offset, BytesReceived);
          until SD.Offset = SD.Size.Value;
        end;
        try
          SD.Stream.Position := 0;
          SD.Png.LoadFromStream(SD.Stream);
          SD.Stream.Clear;
        except
          SD.Png.Assign(nil);
        end;
        Item := Form1.ListView1.Selected;
        if (Item <> nil) and (Item.Data = Socket) then
          Form1.img1.Picture.Graphic := SD.Png;
        SD.State := ReadingSize;
        SD.Offset := 0;
      end;  }

    end;
    Sleep(100);
  end;

end;

procedure TForm1.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
var
  TST: TSock_Thread;
begin
  TST := TSock_Thread.Create(Socket);
  TST.Resume;
end;

ОБНОВИТЬ:

Код в ответе не работает для меня, потому чтоServerType=stThreadBlocking блокирует все клиентские соединения с сервером. И из-за этого я ищу что-то подобное (ServerType=stNonBlocking, TThread а такжеOnAccept мероприятие):

type
  TSock_Thread = class(TThread)
  private
    Png: TPngImage;
    Socket: TCustomWinSocket;
  public
    constructor Create(aSocket: TCustomWinSocket);
    procedure Execute; override;
     procedure PngReceived;
  end;

// ...

// ===============================================================================

constructor TSock_Thread.Create(aSocket: TCustomWinSocket);
begin
  inherited Create(true);
  Socket := aSocket;
  FreeOnTerminate := true;
end;

// ===============================================================================

procedure TSock_Thread.PngReceived;
var
  Item: TListItem;
begin
  Item := Form1.ListView1.Selected;
  if (Item <> nil) and (Item.Data = Socket) then
    Form1.img1.Picture.Graphic := Png;
end;

procedure TSock_Thread.Execute;
var
  Reciving: Boolean;
  DataSize: Integer;
  Data: TMemoryStream;
  s, sl: String;
begin
  inherited;
  while Socket.Connected do
  begin
    if Socket.ReceiveLength > 0 then
    begin
      s := Socket.ReceiveText;
      if not Reciving then
      begin

        SetLength(sl, StrLen(PChar(s)) + 1);
        StrLCopy(@sl[1], PChar(s), Length(sl) - 1);
        DataSize := StrToInt(sl);
        Data := TMemoryStream.Create;
        Png := TPngImage.Create;
        Delete(s, 1, Length(sl));
        Reciving := true;
      end;
      try
        Data.Write(s[1], Length(s));
        if Data.Size = DataSize then
        begin
          Data.Position := 0;
          Png.LoadFromStream(Data);
          Synchronize(PngReceived);
          Data.Free;
          Reciving := false;
        end;
      except
        Png.Assign(nil);
        Png.Free;
        Data.Free;
      end;
    end;
    Sleep(100);
  end;

end;

procedure TForm1.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);
var
  TST: TSock_Thread;
begin
  TST := TSock_Thread.Create(Socket);
  TST.Resume;
end;

Этот код имеет ошибку преобразования данных в этой строке:DataSize := StrToInt(sl);

Как я могу это исправить?

Ответы на вопрос(1)

Ваш ответ на вопрос