2013-03-07 52 views
0

我有一个使用UDP通过wifi与设备通话的地铁应用程序。但是,当我断开设备与网络的连接或者在设备断开连接的情况下启动应用程序时,没有任何反应。 ConnectAsync不会引发异常,应用程序不会抛出异常,应用程序运行起来没有任何问题。 我不能ping另一端,但如果我给它一个格式化的字符串,它会回应。该设备目前连接到可以上网的路由器,但我最终打算使用无路由器的路由器。我从来没有用UDP做任何事情,所以我在这里不知所措。确定UDP主机是否可达?

这是一个UDP监听/写器(在10rem.net皮特明亮的拍摄)的实现

class Network 
    { 
     private DatagramSocket _socket; 
     public bool IsConnected { get; set; } 
     public bool recieved; 
     public string ret; 


     public Network() 
     { 
      IsConnected = false; 

      _socket = new DatagramSocket(); 

      _socket.MessageReceived += OnSocketMessageReceived; 
     } 

     public async void Connect(HostName remoteHostName, string remoteServiceNameOrPort) 
     { 
      try 
      { 
       await _socket.ConnectAsync(remoteHostName, remoteServiceNameOrPort); 
      } 
      catch (Exception e) 
      { 
        var msg = new MessageDialog(e.ToString()); 
        msg.ShowAsync(); 
      } 
      IsConnected = true; 
     } 



     private void OnSocketMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args) 
     { 
       var reader = args.GetDataReader(); 

       var count = reader.UnconsumedBufferLength; 

       var data = reader.ReadString(count); 

       ret = data.Trim(); 

       recieved = true; 

     } 


     DataWriter _writer =null; 
     public async void SendMessage(string message) 
     { 
      if (String.IsNullOrEmpty(message)) return; 
      if (_writer == null) 
      { 
       var stream = _socket.OutputStream; 
       _writer = new DataWriter(stream); 
      } 

      _writer.WriteString(message); 

      await _writer.StoreAsync(); 
     }    

    } 
+0

你确定'ConnectAsync'还没有尝试连接吗? – 2013-03-07 16:20:37

+0

我认为有一个超时,但它只是在连接“挂起”。 – bakedpatato 2013-03-07 16:42:58

回答

1

UDP套接字是“无连接的”,所以该协议不知道是否什么没有连接服务器和客户端。要知道连接是否仍处于“活动”状态,您必须实施自己的连接检测。

我可能会推荐阅读beej的插座指南。这是一个很好的阅读和很有趣: http://beej.us/guide/bgnet/

+0

很酷,谢谢。我不知道如何为这种情况编写连接检测方案;我无法确定设备是否存在于另一端,而不会推送字符并等待响应,并且我无法推送字符,因为“ConnectAsync”和'GetOutputStreamAsync'什么都不做,并且在没有设备的时候阻止它下面的所有代码(因为它应该)。 – bakedpatato 2013-03-07 16:53:21

1

正如之前所说,没有像tcp/ip与sync/ack等来来回沟通,并确保有东西存在的概念。

客户端既没有连接也没有断开连接,只能真正收听或发送。 所以说,你需要实现来自客户端的接收超时。

有一些有趣的笑话与UDP,因为你发送数据,只是基本上扔到太空。数据包的接收顺序无论如何都不重要,或者您在此处也实施了自己的方案。

你需要在这里做的是实际尝试到达设备。如果你在意,那么你可以每X秒做一次。

正如本文指出:How to test a remote UDP Port

(跟上我,低于这个更好的方法,但希望提供多种方式)

 
You can use UdpClient, set a receive timeout on the underlying socket, 
make a connection to that remote server/port, Send some small message 
(byte[] !) and call Receive. 

IF the port is closed you get an exception saying that the connection 
was forcibly closed (SocketException with 
ErrorCode 10054 = WSAECONNRESET)... which means the port is NOT open. 

However-我认为更好的办法是真正同意根据协议ID或客户端每隔X秒发送一些特定数据。如果收到,则更新您的'客户端连接'表,否则认为它们已断开连接,直到客户端发送带有协议ID的数据包。

一个伟大一系列关于这一点,你也许可以很容易地适应C#是: http://gafferongames.com/networking-for-game-programmers/virtual-connection-over-udp/

我相信你的代码上面可重构以及只发送()到一个地址,而不是连接,因为确实没有真正的联系。

0

为了帮助那些偶然发现的人:显然我的google-fu很弱。 This显示了如何为TCP和UDP套接字设置超时。默认行为是永远不会超时(这与我所看到的一致)。

编辑:它不起作用。即使有500ms的超时,我仍然看到“没有异常抛出”的相同行为。