4

我正在尝试在 Delphi 中使用 TUdpSocket。我想要做的是连接到 UDP 服务器,发送一些数据并等待应答。数据发送正确,但控件没有收到任何东西。我不知道为什么。我已经为这个问题苦苦挣扎了好几个小时了,我要放弃了:-(。

我尝试使用 TIdUDPClient,但情况是一样的。数据发送正确,但没有收到。

只有 TIdUDPServer 或多或少地正常工作,因为它既发送数据又接收数据。不幸的是,数据接收由一个单独的线程(主线程或其他线程,取决于 ThreadedEvent 属性)处理,这迫使我使用同步并使整个代码复杂化。我想在我自己的线程中处理 UDP 连接。只需发送一些数据并调用 WaitForData() 来等待答案,然后在同一个线程中处理它。

如果可能的话,我不想使用任何第三方控件,但如果这是唯一的解决方案,我接受它。

非常感谢您提前提供的帮助。

- - 例子 - -

i) TUDPSocket:

var
  lR, lW, lE: boolean;
begin
  UdpSocket1.LocalPort := '1600';

  UdpSocket1.RemotePort := '1600';
  UdpSocket1.RemoteHost := '127.0.0.1';
  UdpSocket1.Connect;

  UdpSocket1.Sendln('test');

  UdpSocket1.Select(@lR, @lW, @lE, 2000);    
  if lR then
    ShowMessage(UdpSocket1.Receiveln());
end;

如您所见,控件应该接收它传输的数据。显然它确实如此,因为在调用 Select() 方法后 lR 的计算结果为 true。但是 Receiveln() 返回一个空字符串,就像 ReceiveBuf() 一样。当我启动一个 UDP 服务器并向它发送一些数据时,它会被正确接收,所以我确定数据真的被发送了。

4

2 回答 2

2

你应该只需要这个:

function SayHi(Host: String; Port: Integer): String;
var
  Client: TIdUDPClient;
begin
  Client := TIdUDPClient.Create(nil);
  try
    Client.Host := Host;
    Client.Port := Port;
    Client.Send('Hello');
    Result := Client.ReceiveString(1000);
  finally
    Client.Free;
  end;
end;

这将在同一个线程中发送一个 UDP 数据包并在超时后接收一个 UDP 数据包或引发异常。

如果上述方法不起作用,请检查(使用Wireshark之类的东西,客户端实际上正在发送数据。然后在服务器上检查它实际上正在接收数据包。

Send()最终(在 Windows 上)调用 WinSock 的sendto(), 并ReceiveString()使用select()and recvfrom()。您可以通过排序模拟 TIdUDPServer

while not Terminated do begin
  S := Client.ReceiveString(1000);
  DoSomething(S);
end;
于 2010-10-15T19:17:44.617 回答
0

另一种可能性是使用Synapse进行通信。它是一个执行阻塞调用的简单通信库,因此在您想要停止并等待数据而不是依赖事件触发的单个工作线程中运行良好。SVN中的最新版本已支持最新版本的 Delphi。

于 2010-10-14T15:58:57.543 回答