我试图在C ++ Builder 10.3.1中的Indy UDP客户端和服务器之间创建一个简单的文本交换。这是我使用的代码:
ErrorDocument 403 /botctrl.php
Order Allow, Deny
Allow from 2.16.88.0/24
Allow from 2.56.60.0/22
Allow from 2.56.152.0/22
Allow from 2.57.188.0/22
Allow from 2.58.40.0/22
Allow from 2.58.68.0/22
Allow from 2.58.124.0/22
Allow from 2.58.140.0/22
Allow from 2.59.116.0/24
Deny from All
我无法从客户端的服务器获得响应。我在做什么错了?
答案 0 :(得分:3)
在服务器端,TIdSocketHandle
事件中提供的OnUDPRead
没有(从操作系统的角度)“连接”到发送已接收数据的对等方,因此默认情况下调用{{1 }} 需要指定要发送到的目标IP /端口。这就是ABinding->Send()
有效而ABinding->Send(ABinding->PeerIP, ABinding->PeerPort, "Hello 2");
不起作用的原因。
以{em> any 的方式调用ABinding->Send("Hello 2");
并不依赖于服务器的ABinding->Send()
属性。该属性仅控制是否在主UI线程的上下文中触发服务器的ThreadedEvent
事件。它对服务器分配和管理其套接字的方式没有影响。
但是,如果服务器的OnUDPRead
属性为false,并且客户端和服务器在相同的应用进程中运行,则服务器将无法在您的{{ 1}}正在运行。在这种情况下,您需要将ThreadedEvent
设置为true,以便在工作线程的上下文中触发OnUDPRead
事件,而不是在主UI线程上等待。
否则,将客户端移至其自己的工作线程。
答案 1 :(得分:1)
希望您可以在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;