title: Delphi: Why Socket.ReadString(10) sometimes don't get the right data
body: <p><strong>Server:</strong></p>
  
  <pre><code>procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
  var
    len : integer;
    rest_packet : string;
    packet_length : string;
  begin
  
          try
            // length 10, it will be the rest packet length: 0000000545
            // So the bug is in ReadBytes(10) , some times it do not receive the length 0000000015 but receive a mix of data+length, something like: "00015Hello" or "loWorldApp" etc.
            packet_length := AContext.Connection.Socket.ReadString(10);
          except
            on E:Exception do begin Exit; end;
          end;
  
          // Convert string to int: 0000000545 , to 545
          try
            len := StrToInt(packet_length);
          except
            on E:Exception do begin Exit; end;
          end;
  
  
          // get reset of data, size: 545
          try
            rest_packet := AContext.Connection.Socket.ReadString(len);
          except
            on E:Exception do begin Exit; end;
          end;
  </code></pre>
  
  <p><strong>Client:</strong></p>
  
  <p>Client is sending data in multithreading to server, about 13 clients is sending data to server thrue one Socket connection. Clients are sending data like this:</p>
  
  <pre><code>    EnterCriticalSection(CS);
      // Memo1.Lines.Add(packet); // i can see here that all works fine.
      Ftunnel.Socket.Write(packet);
      LeaveCriticalSection(CS);
  </code></pre>
  
  <p>CS - is global, and created like this:</p>
  
  <pre><code>initialization
    InitializeCriticalSection(CS);
  finalization
    DeleteCriticalSection(CS);
  </code></pre>
  
  <p>Structure of the packet is:</p>
  
  <p>LengthDATA</p>
  
  <p>example:</p>
  
  <p>0000000015HelloWorldApple</p>
  
  <p>So the bug is in ReadBytes(10) , some times it do not receive the length 0000000015 but receive a mix of data+length, something like: "00015Hello" or "loWorldApp" etc.</p>
  
  <p>Why this is happening, what I'm doing wrong ?</p>
  
  <p>ReadTimeout is default -1</p>
  
  <p>Here how is look Client code:</p>
  
  <pre><code>procedure ss_thread.Execute;
  var ss : TIdTCPClient;
      unix_time : integer;
      data : TIdBytes;
      packet, s : string;
  begin
      // connecting to website to get a data
      ss := TIdTCPClient.Create(nil);
      try
        with TIdTcpClient(ss) do
        begin
          Host := '127.0.0.1';
          Port := 80;
          Connect;
        end;
      except
        on E:Exception do
        begin
          ss.Disconnect;
          exit;
        end;
      end;
  
  
      // writing a data from server to connected web site server
      try
        ss.Socket.Write(Fff_data);
      except
        on E:Exception do begin end;
      end;
  
  
      unix_time := DateTimeToUnix(NOW);
  
  
      // getting data from web site server, all looks thread safe?
      while True do
      begin
        ss.Socket.CheckForDataOnSource(5);
        if not ss.Socket.InputBufferIsEmpty then
        begin
          SetLength(data, 0);
          ss.Socket.InputBuffer.ExtractToBytes(data);
          s := TIdEncoderMIME.EncodeBytes(data);
          packet := make_my_length(s) + s;
          ss.Socket.InputBuffer.Clear;
          unix_time := DateTimeToUnix(NOW);
          try
              // sending data from web site, to server
              EnterCriticalSection(CS);
              tunnel.Socket.Write(packet);
              LeaveCriticalSection(CS);
          except
            on E:Exception do begin end;
          end;
        end;
  
        // disconnecting if no more data for 120sec
        if (DateTimeToUnix(NOW) - unix_time) &gt; 120 then
        begin
          ss.Disconnect;
          break;
        end;
  
        // killing thread if web site server disconnected us
        if not ss.Connected then
        begin
          break;
        end;
  
        // disconnecting from web site server and killing thread if tunnel died
        if not tunnel.Connected then
        begin
          ss.Disconnect;
          break;
        end;
  
  
      end;
  
  // terminate thread
  Terminate;
  end;
  </code></pre>
  
  <p>make my length code, works good:</p>
  
  <pre><code>function make_my_length(s:string):string;
  var len, i : integer;
      res : string;
  begin
    if s='' then
    begin
      Result := '';
      Exit;
    end;
    res := '';
    len := Length(s);
    if len &lt; 10 then
      for i:=1 to (10 - len) do
      begin
        res := res + '0';
      end;
    Result := res + s;
  end;
  </code></pre>
  
  <p>Delphi 2010, Indy 10, Win7</p>