这段代码在Delphi 7下运行良好:
procedure TForm1.FormCreate(Sender: TObject);
//var IdUDPClient1: TIdUDPClient;
begin
idudpclient1.host := '127.0.0.1';
idudpclient1.port := 1234;
idudpclient1.Binding.Port := 1234;
idudpclient1.Binding.Bind;
idudpclient1.Send('Hello');
end;
在 Delphi 10 Seattle 32 位 Windows 下运行完全相同的代码 给出套接字运行时错误 10022:无效参数, 进而 无法绑定(bind)套接字,地址和端口已被使用。
有什么想法吗?
最诚挚的问候 托马斯·里德尔
最佳答案
在 Indy 10 中,当您访问 Binding
属性时,套接字将被创建并绑定(bind)(如果尚未创建)。因此,您尝试在已绑定(bind)的套接字上调用 Bind()
。
当底层套接字 API bind()
失败时,会引发“无效参数”错误。根据 MSDN 的 bind()
文档:
WSAEINVAL
An invalid argument was supplied.This error is returned of the socket
s
is already bound to an address.
TIdSocketHandle.Bind()
调用 TIdSocketHandle.TryBind()
,并且 TryBind()
捕获“无效参数”错误,因此您仅当您在调试器中运行代码时才应该看到它。 “无法绑定(bind)套接字”错误是 Indy 自己的错误,如果 TryBind()
失败,TIdSocketHandle.Bind()
会引发该错误。
您根本不应该直接设置Binding.Port
,或直接调用Binding.Bind()
。使用 TIdUDPClient.BoundPort
属性(也可以选择使用 TIdUDPClient.BoundIP
):
procedure TForm1.FormCreate(Sender: TObject);
//var IdUDPClient1: TIdUDPClient;
begin
IdUDPClient1.Host := '127.0.0.1';
IdUDPClient1.Port := 1234;
//IdUDPClient1.BoundIP := '127.0.0.1';
IdUDPClient1.BoundPort := 1234;
IdUDPClient1.Send('Hello');
end;
当TIdUDPClient
分配其套接字时,它将为您调用Bind()
,将BoundPort
分配给Binding.Port
(以及 BoundIP
到 Binding.IP
)。
您的代码在 Delphi 7 中工作的原因是因为您使用的是 Indy 9(或更早版本)而不是 Indy 10。在那些早期的 Indy 版本中,访问 Binding
属性仅分配套接字,它也没有绑定(bind)套接字,因此您可以手动绑定(bind)它。现在情况已不再如此。
关于delphi - 西雅图的 UDP 与 Delphi 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37716491/