使用TIdUDPServer读取数据

use*_*263 0 delphi udp indy delphi-7

我想从通过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;
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

提前致谢

Rem*_*eau 5

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

var
  Binding: TIdSocketHandle

Binding := IdUDPServer1.Bindings.Add;
Binding.IP := ...;
Binding.Port := ...;
Run Code Online (Sandbox Code Playgroud)

要么:

with IdUDPServer1.Bindings.Add do
begin
  IP := ...;
  Port := ...;
end;
Run Code Online (Sandbox Code Playgroud)

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

IdUDPServer1.DefaultPort := ...;
IdUDPServer1.Bindings.Add.IP := ...;
Run Code Online (Sandbox Code Playgroud)

话虽如此,套接字错误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' 
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用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;
Run Code Online (Sandbox Code Playgroud)

更新:如果将服务器绑定到端口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;
Run Code Online (Sandbox Code Playgroud)