简体   繁体   中英

Convert From indy udp To Tcp

i have been using indy udp and i want to move on to indy tcp

but i dont know how to convert the code to work in the same way with indy tcp

my project work to send stream as chat room here is the udp code

procedure TForm1.recorderData(Sender: TObject; const Buffer: Pointer;
  BufferSize: Cardinal; var FreeIt: Boolean);
begin
Freeit :=True;
if IDUDPCLIENT.active then
IDUDPCLIENT.SendBuffer(RawToBytes(Buffer^, Buffersize))
else
stop.Caption := 'error';
end;

and this is the server on read event

procedure TForm1.UDPReceiverUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
var
  AudioDataSize: Integer;
  AudioData : Pointer;
begin
  try
    EnterCriticalSection(Section);
    try
      AudioDataSize := Length(AData);
      if AudioDataSize > 10 then
      begin
        try
          if not Player.Active then
          begin
            Player.Active := True;
            Player.WaitForStart;
          end;
        except
        end;
        if BlockAlign > 1 then Dec(AudioDataSize, AudioDataSize mod BlockAlign);
        AudioData := AudioBuffer.BeginUpdate(AudioDataSize);
        try
          BytesToRaw(AData, AudioData^, AudioDataSize);
        finally
          AudioBuffer.EndUpdate;
        end;
      end else
      begin
        Player.Active := False;
        Player.WaitForStop;
      end;
    finally
      LeaveCriticalSection(Section);
    end;
  except
  end;
end;

how i make them work in the same way in indy tcp ?

Indy's UDP and TCP components use different interface architectures. It is not enough to just port the code, you have to re-design your communication protocol accordingly, which may require you to re-write your core code logic. Remember that UDP is message-based, but TCP is not, so you have to design your own message framing.

You also have to take into account that like TIdUDPServer , TIdTCPServer is also multi-threaded. But unlike TIdUDPServer , TIdTCPServer does not have a ThreadedEvent property, so you have to provide your own synchronizing when accessing other threads, especially the main UI thread.

Based on your simple example, try something like this:

procedure TForm1.recorderData(Sender: TObject; const Buffer: Pointer; BufferSize: Cardinal; var FreeIt: Boolean);
begin
  FreeIt := True;
  try
    if IdTCPClient1.Connected then
    begin
      IdTCPClient1.IOHandler.Write(BufferSize);
      IdTCPClient1.IOHandler.Write(RawToBytes(Buffer^, BufferSize));
      Exit;
    end;
  except
  end;
  stop.Caption := 'error';
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  AudioDataSize: Integer;
  AudioDataBytes: TIdBytes;
  AudioData: Pointer;
begin
  AudioDataSize := AContext.Connection.IOHandler.ReadLongInt();
  AContext.Connection.IOHandler.ReadBytes(AudioDataBytes, AudioDataSize);

  EnterCriticalSection(Section);
  try
    if AudioDataSize > 10 then
    begin
      try
        if not Player.Active then
        begin
          Player.Active := True;
          Player.WaitForStart;
        end;
      except
      end;
      if BlockAlign > 1 then Dec(AudioDataSize, AudioDataSize mod BlockAlign);
      AudioData := AudioBuffer.BeginUpdate(AudioDataSize);
      try
        BytesToRaw(AudioDataBytes, AudioData^, AudioDataSize);
      finally
        AudioBuffer.EndUpdate;
      end;
    end else
    begin
      Player.Active := False;
      Player.WaitForStop;
    end;
  finally
    LeaveCriticalSection(Section);
  end;
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM