【问题标题】:Reading data with TIdUDPServer使用 TIdUDPServer 读取数据
【发布时间】:2012-05-14 14:15:04
【问题描述】:

我想从通过 UDP 向我的电脑发送数据的电子设备读取数据。我在 Delphi 中编写了一个 UDP 服务器。 EIdSocketError 类中发生异常(失败 #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;

我做错了什么?

提前致谢

【问题讨论】:

  • 我认为您需要将 IdUDPServer1.Bindings.add 的结果分配给一个变量,然后设置其 IP 和端口。如果我没记错的话,你正在做的是添加两个绑定,一个是 IP,一个是端口。
  • 我把代码改了如下,但是还是一样的错误...我假设绑定的ip必须是电子设备的ip(不是PC的ip):var myaddress:TIdSocketHandle;开始我的地址:=IdUDPServer1.Bindings.Add;我的地址.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”),但我仍然没有收到来自外部设备的数据...代码?
  • 请使用您正在使用的最新代码更新您的问题。

标签: delphi udp delphi-7 indy


【解决方案1】:

正如 Keith Miller 所说,您在滥用 Bindings 属性。您正在向服务器添加 2 绑定 - 一个用于端口 0 上的 192.168.1.1,另一个用于端口 0.0.0.0 上的 0.0.0.0。对于要绑定的每个 IP/端口对,您只需调用一次 Bindings.Add(),例如:

var
  Binding: TIdSocketHandle

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

或者:

with IdUDPServer1.Bindings.Add do
begin
  IP := ...;
  Port := ...;
end;

如果你提前设置了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,并根据需要为它们单独创建单独的 Bindings

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;

【讨论】:

  • 我会修改我的代码,我会告诉你我的结果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
  • 2021-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-08-17
  • 2020-09-17
  • 1970-01-01
相关资源
最近更新 更多