2012-05-14 81 views
0

我想从通过UDP向我的PC发送数据的电子设备读取数据。我在Delphi中编写了一个UDP服务器。类EIdSocketError(失败#10049)发生异常。这是我的代码:使用TIdUDPServer读取数据

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; 

我在做什么错?

在此先感谢

+3

我想你需要将IdUDPServer1.Bindings.add的结果分配给一个变量,然后设置它的IP和端口。如果我没有记错,你正在做的是添加两个绑定,一个使用IP,另一个使用Port。 –

+0

我改变了代码如下,但错误是一样的...我假设绑定ip必须是电子设备的ip(不是PC ip):*** var myaddress:TIdSocketHandle; 开始 myaddress:= IdUDPServer1.Bindings.Add; myaddress.IP:='192.168.1.1'; myaddress.Port:= 49152; IdUDPServer1.Bindings.Add.IP:= myaddress.IP; IdUDPServer1.Bindings.Add.Port:= myaddress.Port; end; *** – user1361263

+2

不,使用绑定,您可以指定在哪个以太网适配器上侦听UDP数据包。 – whosrdaddy

回答

5

基思·米勒说,你是滥用Bindings财产。您正在将绑定添加到服务器 - 一个用于端口0上的192.168.1.1,另一个用于端口49152上的0.0.0.0。你需要调用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

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让OS选择一个端口,你可以发现,通过看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; 
+0

我将在我的代码中进行修改,然后我会告诉你我的结果 – user1361263

+0

在我的Delphi 7中可以识别Gstack变量... – user1361263

+0

在您的使用条款中包含'IdStack'单元。 –