如何从 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中的回答。刚才翻译不了
有一对项目,VclIdUDPServer
和VclIdUDPClient
,如下,我拿到这两个来交流。在同一台机器和两台机器上测试。请注意,这是让两人聊天的最少代码。
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 线程。
否则,将客户端移至其自己的工作线程。
我正在尝试在 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中的回答。刚才翻译不了
有一对项目,VclIdUDPServer
和VclIdUDPClient
,如下,我拿到这两个来交流。在同一台机器和两台机器上测试。请注意,这是让两人聊天的最少代码。
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 线程。
否则,将客户端移至其自己的工作线程。