0

我想从通过 UDP 向我的 PC 发送数据的电子设备读取数据。我在 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;

我究竟做错了什么?

提前致谢

4

1 回答 1

8

正如基思米勒所说,您正在滥用该Bindings财产。您正在向服务器添加2 个绑定 - 一个用于192.168.1.1on port 0,另一个用于0.0.0.0on port 49152。您只需为Bindings.Add()要绑定的每个 IP/端口对调用一次,例如:

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根据需要单独为它们创建单独的 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;

更新:TIdSocketHandle.Port如果您将服务器绑定到端口 0 以让操作系统选择一个端口,您可以在服务器激活后通过查看属性来发现选择了哪个端口:

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;
于 2012-05-14T20:05:10.473 回答