【问题标题】:Convert From indy udp To Tcp从 indy udp 转换为 Tcp
【发布时间】:2014-09-10 16:54:57
【问题描述】:

我一直在使用 indy udp,我想继续使用 indy tcp

但我不知道如何将代码转换为与 indy tcp 相同的工作方式

我的项目工作是将流作为聊天室发送,这里是 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;

这是服务器读取事件

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;

我如何让它们在 indy tcp 中以相同的方式工作?

【问题讨论】:

    标签: delphi indy


    【解决方案1】:

    Indy 的 UDP 和 TCP 组件使用不同的接口架构。仅仅移植代码是不够的,你必须相应地重新设计你的通信协议,这可能需要你重新编写你的核心代码逻辑。请记住,UDP 是基于消息的,但 TCP 不是,因此您必须设计自己的消息框架。

    您还必须考虑到像TIdUDPServerTIdTCPServer 也是多线程的。但与TIdUDPServer不同的是,TIdTCPServer没有ThreadedEvent属性,因此在访问其他线程时,尤其是主UI线程时,您必须提供自己的同步。

    根据您的简单示例,尝试以下操作:

    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;
    

    【讨论】:

    • 谢谢你,这对我很有帮助。
    • remy iam 试图在 udp 中发送消息的另一件事我正在做这个 iDCLIENT.Broadcast(strMsg, 16000);并像这样阅读 msg.Lines.Add(BytesToString(AData));如何在 tcp 中做到这一点?
    • TCP 不支持广播。您必须将消息数据的单独副本发送到您拥有的每个单独的 TCP 连接。
    猜你喜欢
    • 2018-04-22
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    相关资源
    最近更新 更多