【问题标题】:Lost UDP 'connection' between client app and server app客户端应用程序和服务器应用程序之间丢失 UDP“连接”
【发布时间】:2012-06-28 04:29:16
【问题描述】:

我编写了两个小应用程序(一个客户端和一个服务器)来测试 UDP 通信,我发现它们之间的“连接”(是的,我知道,没有真正的连接)经常无缘无故丢失。

我知道 UDP 是一个不可靠的协议,但是这里的问题似乎不是丢包,而是应用程序之间的通信通道丢失。

这是客户端应用程序代码:

    class ClientProgram
    {
        static void Main(string[] args)
        {
            var localEP = new IPEndPoint(GetIPAddress(), 0);

            Socket sck = new UdpClient(localEP).Client;
            sck.Connect(new IPEndPoint(IPAddress.Parse("[SERVER_IP_ADDRESS]"), 10005));

            Console.WriteLine("Press any key to request a connection to the server.");
            Console.ReadLine();

            // This signals the server this clients wishes to receive data
            SendData(sck);

            while (true)
            {
                ReceiveData(sck);
            }
        }

        private static void ReceiveData(Socket sck)
        {
            byte[] buff = new byte[8];
            int cnt = sck.Receive(buff);

            long ticks = BitConverter.ToInt64(buff, 0);

            Console.WriteLine(cnt + " bytes received: " + new DateTime(ticks).TimeOfDay.ToString());
        }

        private static void SendData(Socket sck)
        {
            // Just some random data
            sck.Send(new byte[] { 99, 99, 99, 99 });
        }

        private static IPAddress GetIPAddress()
        {
            IPHostEntry he = Dns.GetHostEntry(Dns.GetHostName());
            if (he.AddressList.Length == 0)
                return null;

            return he.AddressList
                .Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip))
                .FirstOrDefault();
        }
    }

这是服务器应用程序代码:

    class ServerProgram
    {
        private static int SLEEP = 5;
        static void Main(string[] args)
        {
            // This is a static IP address
            var localEP = new IPEndPoint(GetIPAddress(), 10005);

            Socket sck = new UdpClient(localEP).Client;

            // When this methods returs, a client is ready to receive data
            var remoteEP = ReceiveData(sck);

            sck.Connect(remoteEP);

            while (true)
            {
                SendData(sck);
                System.Threading.Thread.Sleep( ServerProgram.SLEEP * 1000);
            }
        }

        private static EndPoint ReceiveData(Socket sck)
        {
            byte[] buff = new byte[8];
            EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);

            int cnt = sck.ReceiveFrom(buff, ref clientEP);

            Console.WriteLine(cnt + " bytes received from " + clientEP.ToString());

            return (IPEndPoint)clientEP;
        }

        private static void SendData(Socket sck)
        {
            DateTime n = DateTime.Now;
            byte[] b = BitConverter.GetBytes(n.Ticks);
            Console.WriteLine("Sending " + b.Length + " bytes : " + n.TimeOfDay.ToString());
            sck.Send(b);
        }

        private static IPAddress GetIPAddress()
        {
            // Same as client app...
        }
    }

(这里只是测试代码,不要注意死循环或者缺少数据验证)

问题是在发送了几条消息后,客户端停止接收它们。服务器继续发送,但客户端卡在sck.Receive(buff)。如果我将 SLEEP 常量更改为高于 5 的值,则“连接”在大多数情况下会在 3 或 4 条消息后丢失。

我可以确认客户端机器在连接丢失时没有收到任何数据包,因为我使用 Wireshark 监控通信。

服务器应用程序在直接连接到 Internet 的服务器上运行,但客户端是本地网络中的一台机器,位于路由器后面。他们都没有运行防火墙。

有人知道这里会发生什么吗?

谢谢!

编辑 - 附加数据:

我在同一网络中的多台机器上测试了客户端应用程序,但连接总是丢失。我还在其他路由器后面的其他网络中测试了客户端应用程序,那里没有问题。我的路由器是Linksys RV042,从来没有遇到过问题,事实上,这个应用程序是唯一有问题的。


问题已解决 - 简短回答:

这是硬件问题。

【问题讨论】:

    标签: c# sockets connection udp client-server


    【解决方案1】:

    我在源代码中没有发现任何明显的问题。如果是真的:

    1. 服务器一直在发送数据包(由服务器上的 WireShark 确认)
    2. 客户端从不接收数据包(由客户端上的 WireShark 确认)

    ..那么问题可能与两台机器之间的网络设备有关,它们并不总是按预期处理 UDP 流,尤其是在路由器/防火墙后面时。

    我会推荐以下故障排除方法:

    1. 在同一系统上运行客户端和服务器并使用环回接口(确认 UDP 代码在环回上有效)
    2. 在插入同一以太网交换机的两个不同系统上运行客户端和服务器(确认 UDP 通信在交换机本地工作)

    如果在本地交换机上一切正常,您可以确定您遇到了网络配置问题。

    【讨论】:

    • 感谢您的建议!我尝试在同一台机器上和同一局域网的不同机器上运行这两个应用程序,一切正常。当服务器在其他网络上时会出现问题。
    • 这是有道理的。我假设您已经在 Linksys 中打开了 UDP 端口,因为您可以进行短时间的通信。正如我提到的,许多网络设备处理 UDP 流的能力很差——这些 Linksys 路由器中的大多数都针对 TCP 进行了优化。我会尝试重写程序以使用 TCP 并查看路由器是否可以处理。应该是一个足够简单的测试。其他选项包括寻找更新的路由器固件、致电 Linksys 支持或完全更换路由器。
    • 嗯,原来是硬件问题!我尝试在没有路由器的情况下将我的计算机直接连接到调制解调器,它工作正常。我还用另一个相同型号的路由器替换了路由器,它也可以工作!
    • 硬件故障是最糟糕的——这些奇怪的、不确定的问题!很高兴我能帮忙..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 2019-03-16
    • 1970-01-01
    • 2021-06-02
    相关资源
    最近更新 更多