简体   繁体   English

转换indy udp为tcp

[英]Convert From indy udp To Tcp

i have been using indy udp and i want to move on to indy tcp 我一直在使用indy udp,我想继续使用indy tcp

but i dont know how to convert the code to work in the same way with indy tcp 但是我不知道如何将代码转换为以indy tcp的相同方式工作

my project work to send stream as chat room here is the udp code 我的项目工作是发送流作为聊天室,这里是udp代码

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 tcp中以相同的方式工作?

Indy's UDP and TCP components use different interface architectures. Indy的UDP和TCP组件使用不同的接口体系结构。 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. 请记住,UDP是基于消息的,但TCP不是基于消息的,因此您必须设计自己的消息框架。

You also have to take into account that like TIdUDPServer , TIdTCPServer is also multi-threaded. 您还必须考虑到像TIdUDPServer一样, TIdTCPServer也是多线程的。 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. 但是与TIdUDPServer不同, TIdTCPServer没有ThreadedEvent属性,因此在访问其他线程(尤其是主UI线程)时必须提供自己的同步。

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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