1

我有一个地铁应用程序使用 UDP 通过 wifi 与设备通信。但是,当我断开设备与网络的连接或在设备断开连接的情况下启动应用程序时,什么也没有发生。ConnectAsync 不会引发异常,应用程序不会引发异常,应用程序运行起来就像没有任何问题一样。我无法 ping 另一端,但如果我给它一个格式化的字符串,它会响应。该设备当前连接到可以访问 Internet 的路由器,但我最终计划使用没有 Internet 访问权限的路由器。我从来没有用UDP做过任何事情,所以我在这里不知所措。

这是一个 UDP 侦听器/编写器的实现(取自 Pete Bright 在 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();
        }            

    }
4

3 回答 3

2

UDP 套接字是“无连接”的,因此协议不知道服务器和客户端是否连接。要知道 aa 连接是否仍然“活动”,您必须实施自己的连接检测。

我可能会推荐阅读 beej 的套接字指南。这是一本很好的书,很有趣: http ://beej.us/guide/bgnet/

于 2013-03-07T16:22:02.910 回答
1

如前所述,没有像 tcp/ip 中带有 sync/ack 等的概念来来回通信并确保存在某些东西。

客户端既没有连接也没有断开连接,只是真正地监听或发送。因此,话虽如此,您需要从客户端实现接收超时。

UDP 有一些有趣的笑话,因为您发送数据实际上只是将其扔到太空中。接收数据包的顺序也无关紧要,否则您也被困在此处实施自己的方案。

您在这里需要做的实际上是尝试访问设备。如果您关心,那么您可以每 X 秒执行一次。

如此处所述:如何测试远程 UDP 端口

(跟我来,下面有一个更好的方法,但想提供多种方法)

您可以使用 UdpClient,在底层套接字上设置接收超时,
连接到该远程服务器/端口,发送一些小消息
 (byte[] !) 并调用 Receive。

如果端口关闭,您会收到一个异常,说明连接
被强行关闭(SocketException with
 错误代码 10054 = WSAECONNRESET)... 这意味着端口未打开。

但是-我认为更好的方法是实际上就协议 ID 或客户端每 X 秒发送的某些特定数据达成一致。如果收到,则更新您的“客户端连接”表,否则认为它们已断开连接,直到客户端发送带有协议 id 的数据包。

您可能可以轻松适应 c# 的一个很棒的系列在: http: //gafferongames.com/networking-for-game-programmers/virtual-connection-over-udp/

我相信您上面的代码也可以重构为仅将 Send() 发送到地址而不是连接,因为确实没有真正的连接。

于 2013-03-08T00:05:57.247 回答
0

To help out people that stumble upon this:Apparently my google-fu is pretty weak. This shows how to set timeouts for TCP and UDP sockets. Default behavior is to never time out(which is consistent with what I saw).

Edit: It doesn't work. Even with a timeout of 500ms I'm still seeing the same behavior of "no exception thrown".

于 2013-03-08T19:10:47.933 回答