如何从 Indy udp 服务器获取响应字符串?

How to get response string from Indy udp server?

我正在尝试在 C++ Builder 10.3.1 中创建 Indy UDP 客户端和服务器之间的简单文本交换。这是我使用的代码:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    IdUDPClient1->Send("Hello");
    UnicodeString resp = IdUDPClient1->ReceiveString();
    ShowMessage(resp);
}

void __fastcall TForm1::IdUDPServer1UDPRead(TIdUDPListenerThread *AThread,
    const TIdBytes AData, TIdSocketHandle *ABinding)
{
    UnicodeString req = BytesToString(AData);

    if(req == "Hello"){
        // why this don't work?
        ABinding->Send("Hello 2");

        // the following works if ThreadedEvent = true
        // AThread->Server->Send(ABinding->PeerIP, ABinding->PeerPort, "Hello 2");
    }
}

我无法在客户端获得服务器的响应。我做错了什么?

希望您能采纳Delphi中的回答。刚才翻译不了

有一对项目,VclIdUDPServerVclIdUDPClient,如下,我拿到这两个来交流。在同一台机器和两台机器上测试。请注意,这是让两人聊天的最少代码。

VclIdUDPServer

procedure TForm1.FormCreate(Sender: TObject);
var
  Binding: TIdSocketHandle;
begin
  Binding := IdUDPServer1.Bindings.Add;
  Binding.IP := '192.168.2.109';
  Binding.Port:= 49000;
  IdUDPServer1.OnUDPRead:= IdUDPServer1UDPRead;
  IdUDPServer1.Active:=True;
end;

procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
var
  req: string;
begin
  req := BytesToString(AData);
  Memo2.Lines.Add(req);
  if req = 'Hello' then
    ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, 'Yes sir!', ABinding.IPVersion);
  end;
end;

VclIdUDPClient

procedure TForm2.FormCreate(Sender: TObject);
begin
  IdUDPClient1.Host:='192.168.x.xxx'; // set to your ip
  IdUDPClient1.Port:=49000;
  IdUDPClient1.Active:=True;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  rep: string;
begin
  IdUdpClient1.Send('Hello');
  rep := IdUdpClient1.ReceiveString();
  Memo1.Lines.Add(rep);
end;

在服务器端,OnUDPRead 事件中提供的 TIdSocketHandle 不是 "connected"(从 OS 的角度来看)到发送接收到数据,因此默认调用ABinding->Send() 需要 指定要发送到的目标IP/Port。这就是 ABinding->Send(ABinding->PeerIP, ABinding->PeerPort, "Hello 2"); 有效而 ABinding->Send("Hello 2"); 无效的原因。

调用ABinding->Send()不依赖于服务器的ThreadedEvent属性任何方式。 属性 仅控制服务器的 OnUDPRead 事件是否在主 UI 线程的上下文中触发。它对服务器如何分配和管理其套接字没有影响

但是,如果服务器的ThreadedEvent 属性为false,并且客户端和服务器运行在同一个应用程序进程中,服务器将无法触发它OnUDPRead 事件,而你的 Button1Click() 是 运行。在这种情况下,您需要将 ThreadedEvent 设置为 true,以便在工作线程的上下文中触发 OnUDPRead 事件,而不是等待主 UI 线程。

否则,将客户端移至其自己的工作线程。