处理TUdpSocket

发布于 2024-09-27 13:52:39 字数 924 浏览 7 评论 0原文

我正在尝试在 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 服务器并向其发送一些数据时,它会被正确接收,因此我确定数据确实已发送。

I'm trying to use the TUdpSocket in Delphi. What I want to do is connect to a UDP server, send some data and wait for answer. Data is sent correctly, but the control does not receive anything. I don't know why. I've been struggling with this problem for many hours now and I'm going to give up :-(.

I tried to use TIdUDPClient, but the situation is the same. Data is sent properly, but none is received.

Only does TIdUDPServer work more or less properly for it both sends and receives data. Unfortunately data reception is handled by a separate thread (main or other, depending on the ThreadedEvent property) which forces me to use synchronization and complicate the whole code. I would like to handle UDP connection in my own thread. Just send some data and call WaitForData() to wait for an answer and then handle it in the same thread.

And if opossible, I don't want to use any third party controls, but if it is the only solution, I accept it.

Thank you very, very much for your help in advance.

---- Examples ---

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;

As you can see, the control should receive the data it transmits. And apparently it does, for the lR evaluates to true after the Select() method is called. But Receiveln() returns an empty string, as ReceiveBuf() does. When i start a UDP server and send some data to it, it is received properly, so I'm certain that the data is really sent.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海里的那抹蓝 2024-10-04 13:52:39

您应该只需要这样:

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()recvfrom() 您可以通过以下方式模拟 TIdUDPServer:

while not Terminated do begin
  S := Client.ReceiveString(1000);
  DoSomething(S);
end;

You should need nothing more than this:

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;

which will, in the same thread, send a UDP packet and either receive a UDP packet or raise an exception after a timeout.

If the above doesn't work, check (using something like Wireshark that the client's actually sending the data. Then check on the server that it's actually receiving the packet.

Send() ultimately (on Windows) calls WinSock's sendto(), and ReceiveString() uses select() and recvfrom(). You could sort've simulate a TIdUDPServer by

while not Terminated do begin
  S := Client.ReceiveString(1000);
  DoSomething(S);
end;
给我一枪 2024-10-04 13:52:39

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

Another possibility would be to use Synapse for your communication. It is a simple communications library which performs blocking calls, so works well in a single worker thread where you want to stop and wait for data rather than rely on an event to fire. The latest versions in SVN have support for the latest versions of Delphi.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文