delphi - 西雅图的 UDP 与 Delphi 7

标签 delphi udp indy10 delphi-10-seattle

这段代码在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 (以及 BoundIPBinding.IP)。

您的代码在 Delphi 7 中工作的原因是因为您使用的是 Indy 9(或更早版本)而不是 Indy 10。在那些早期的 Indy 版本中,访问 Binding 属性仅分配套接字,它也没有绑定(bind)套接字,因此您可以手动绑定(bind)它。现在情况已不再如此。

关于delphi - 西雅图的 UDP 与 Delphi 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37716491/

相关文章:

node.js - Node : Sending UDP packet on timer,无限循环

C++ Socket recv()顺序错误

c# - 从另一个应用程序接收的UDP数据包中读取远程IP

delphi - 为什么我必须发送两个连续的 HTTP Get 请求才能进行身份验证?

delphi - TEdit onclick 全选?

delphi - 是否可以在delphi 7调试器中查看调用堆栈?

delphi - 如果文本宽度大于 TEdit 的宽度,如何显示一些指示符

asp.net-mvc - delphi web服务从.net mvc应用程序获取不同的日期时间

Delphi 2007 和更新的 Indy 10

delphi - TIdThreadComponent OnTerminate 和 OnStopped 在哪个线程中执行?