2010-10-14 54 views
4

我想在Delphi中使用TUdpSocket。我想要做的是连接到UDP服务器,发送一些数据并等待回答。数据正确发送,但控件不会收到任何内容。我不知道为什么。我一直在努力解决这个问题好几个小时,现在我要放弃了:-(。处理TUdpSocket

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

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

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

非常感谢您提前给予您的帮助。

----实例---

ⅰ)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服务器并向它发送一些数据时,它会被正确接收,所以我确信数据是真正发送的。

+0

模拟TIdUDPServer我曾与一个线程ICS类似的事情,所以不能直接回答。不过,你可能需要包括一个消息泵在你的线程中,以便套接字获得它需要工作的通知。 – mj2008 2010-10-14 10:06:14

+1

你如何知道数据发送正确?服务器和客户端都在同一个子网上吗?你确定防火墙(本地或网内)不会阻止你的udp流量吗? – jachguate 2010-10-14 23:01:42

+0

jachguate说了什么:使用类似Wireshark的东西来确保服务器机器实际接收数据包。如果有,并且您可以看到响应触及客户端的NIC,那么您可能会遇到未处理套接字通知的问题。 – 2010-10-15 12:32:58

回答

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()recvfrom()。你可以通过sort've

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

是的,这正是我想得到的。如果只是它的工作;-(。因为它没有.Client.Send()完美的作品,但Cleint.ReceiveString()从来没有。真的不明白它是Indy版本的问题吗?我的版本有bug吗?谢谢! – 2010-10-15 20:28:36

+0

我仍然在使用Indy 9,但我无法想象Indy 10的工作方式有很大不同,我会添加一些更多的答案细节 – 2010-10-15 21:20:47

+0

我使用Indy 10(BDS 2006)。我d不知道为什么,但它不能这样工作:-(。更令人惊讶的是,我也尝试使用TUDPSocket的Select()方法。它返回布尔值,如ReadReady,WriteReady。当一些数据被发送到我打开的端口时,ReadReady被设置为true,但是当我调用任何Receive ...()方法时,不会收到任何数据。这是一个谜团:-)。但是让我们忘记它。我不想再打扰你了。非常感谢您的宝贵时间! – 2010-10-17 08:46:29

0

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