0

UDP通信をテストするために2つの小さなアプリケーション(クライアントとサーバー)を作成しましたが、それらの間の「接続」(ええ、実際の接続はありません)が理由もなく頻繁に失われることがわかりました。

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を使用して通信を監視しているため、接続が失われたときにクライアントマシンがパケットを受信しないことを確認できます。

サーバーアプリはインターネットに直接接続されているサーバー上で実行されますが、クライアントはルーターの背後にあるローカルネットワーク内のマシンです。それらのどれもファイアウォールを実行していません。

誰かがここで何が起こっているのか手がかりを持っていますか?

ありがとうございました!

編集-追加データ:

同じネットワーク内の複数のマシンでクライアントアプリをテストしましたが、接続が常に失われます。また、他のルーターの背後にある他のネットワークでクライアントアプリをテストしましたが、問題はありません。私のルーターはLinksysRV042であり、問​​題は発生していません。実際、問題が発生しているのはこのアプリだけです。


解決した問題-短い答え:

それはハードウェアの問題でした。

4

1 に答える 1

1

ソースコードに明白な問題は見当たりません。それが本当なら:

  1. サーバーはパケットを送信し続けます (サーバー上の WireShark によって確認されます)
  2. クライアントがパケットを受信しない (クライアントの WireShark で確認)

..その場合、問題は 2 台のマシン間のネットワーク機器に関連している可能性があり、特にルーター/ファイアウォールの背後にある場合、UDP フローを常に期待どおりに処理するとは限りません。

トラブルシューティングには、次のアプローチをお勧めします。

  1. クライアントとサーバーを同じシステムで実行し、ループバック インターフェイスを使用します (UDP コードがループバックで動作することを確認します)。
  2. 同じイーサネット スイッチに接続された 2 つの異なるシステムでクライアントとサーバーを実行します (UDP 通信がスイッチ ローカルで機能することを確認します)。

すべてがスイッチ ローカルで機能する場合は、ネットワーク構成に問題があることを確信できます。

于 2012-06-26T19:36:29.890 に答える