Delphi 使用TIdUDPServer读取数据

Delphi 使用TIdUDPServer读取数据,delphi,udp,delphi-7,indy,Delphi,Udp,Delphi 7,Indy,我想从通过UDP向我的电脑发送数据的电子设备读取数据。我已经在Delphi中编程了一个UDP服务器。类EIdSocketError Failure 10049中发生异常。这是我的密码: procedure TForm1.Button1Click(Sender: TObject); begin IdUDPServer1.Bindings.add.IP := '192.168.1.1'; //Electronic device ip IdUDPServer1.Bindings.add.

我想从通过UDP向我的电脑发送数据的电子设备读取数据。我已经在Delphi中编程了一个UDP服务器。类EIdSocketError Failure 10049中发生异常。这是我的密码:

procedure TForm1.Button1Click(Sender: TObject);
begin
   IdUDPServer1.Bindings.add.IP := '192.168.1.1';  //Electronic device ip
   IdUDPServer1.Bindings.add.Port:= 49152;         //Electronic device port   
   IdUDPServer1.OnUDPRead:= UDPRead;
   IdUDPServer1.Active:=True;

end;

procedure TForm1.UDPRead (Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);
var
   bytes_received: integer;
begin
   bytes_received:=AData.size;
end;
我做错了什么


提前感谢

正如Keith Miller所说,您误用了Bindings属性。您正在向服务器添加2个绑定—一个用于端口0上的192.168.1.1,另一个用于端口49152上的0.0.0.0。您需要调用绑定。只为要绑定到的每个IP/端口对添加一次,例如:

var
  Binding: TIdSocketHandle

Binding := IdUDPServer1.Bindings.Add;
Binding.IP := ...;
Binding.Port := ...;
或:

如果提前设置DefaultPort属性,则可以将上述操作简化为:

IdUDPServer1.DefaultPort := ...;
IdUDPServer1.Bindings.Add.IP := ...;
话虽如此,套接字错误10049是WSAEADDRNOTAVAIL,这意味着您首先使用了错误的IP地址。您需要指定一个属于运行TIdUDPServer的PC的IP—设备将向其发送UDP数据包的IP。您可以绑定到单个通配符IP 0.0.0.0,也可以只绑定一个空白字符串,该字符串告诉TIdUDPServer绑定到所有可用的本地IP:

IdUDPServer1.DefaultPort := ...;
IdUDPServer1.Bindings.Add.IP := ''; // or: '0.0.0.0' 
或者,您可以使用Indy的GStack.LocalAddresses属性来确定本地可用的IP,并根据需要分别为它们创建单独的绑定

IdUDPServer1.Bindings.Clear;
IdUDPServer1.DefaultPort := ...;

with GStack.LocalAddresses do
begin
  for I := 0 to Count-1 do
    IdUDPServer1.Bindings.Add.IP := Strings[I];
end;
更新:如果将服务器绑定到端口0以让操作系统选择端口,则可以在激活服务器后通过查看TIdSocketHandle.port属性来发现选择了哪个端口:

var
  Binding: TIdSocketHandle
  ListeningPort: TIdPort;

IdUDPServer1.Bindings.Clear;

Binding := IdUDPServer1.Bindings.Add;
Binding.IP := ...;
Binding.Port := 0;
{
or: 
IdUDPServer1.DefaultPort := 0;
Binding := IdUDPServer1.Bindings.Add;
Binding.IP := ...;
}

IdUDPServer1.Active := True;

ListeningPort := Binding.Port;

我认为您需要将IdUDPServer1.Bindings.add的结果分配给一个变量,然后设置其IP和端口。如果我没记错的话,你正在做的是添加两个绑定,一个是IP绑定,一个是端口绑定。。。我假设绑定ip必须是电子设备的ip,而不是PC ip:var myaddress:TIdSocketHandle;开始myaddress:=IdUDPServer1.Bindings.Add;myaddress.IP:=“192.168.1.1”;我的地址.端口:=49152;IdUDPServer1.Bindings.Add.IP:=myaddress.IP;IdUDPServer1.Bindings.Add.Port:=myaddress.Port;终止不,通过绑定,您可以指定在哪个以太网适配器上侦听UDP数据包。我已将绑定ip地址更改为“0.0.0.0”和“127.0.0.1”,但我仍然没有从外部设备接收任何数据。。。我的代码中有任何错误吗?请用您正在使用的最新代码更新您的问题。我将对我的代码进行修改,并向您展示我的结果
var
  Binding: TIdSocketHandle
  ListeningPort: TIdPort;

IdUDPServer1.Bindings.Clear;

Binding := IdUDPServer1.Bindings.Add;
Binding.IP := ...;
Binding.Port := 0;
{
or: 
IdUDPServer1.DefaultPort := 0;
Binding := IdUDPServer1.Bindings.Add;
Binding.IP := ...;
}

IdUDPServer1.Active := True;

ListeningPort := Binding.Port;