在本地测试UDP#C

时间:2016-11-27 15:11:12

标签: c# unit-testing udp

我正在编写需要使用UDP的单声道C#应用程序。我正在编写我的测试套件,以便确保使用NUnit正确接收数据包。

我用UdpCom类创建了一个最小的工作示例,该类应该立即监听并打印出它在回调方法中接收的字节。

我的小UdpCom课程如下:

using System;
using System.Net;
using System.Net.Sockets;


namespace UdpPractice
{
    public class UdpState
    {
        public UdpClient client;
        public IPEndPoint endpoint;
        public UdpState(UdpClient c, IPEndPoint iep)
        {
            this.client = c;
            this.endpoint = iep;
        }
    }
    public class UdpCom
    {
        public UdpState uState;
        public UdpClient uClient;
        public IPAddress address;
        public int port;
        public IPEndPoint uEndpoint;

        public UdpCom (IPAddress address, int port)
        {
            uEndpoint = new IPEndPoint (address, port);
            uClient = new UdpClient (uEndpoint);
            uState = new UdpState (uClient, uEndpoint);
            uClient.BeginReceive (new AsyncCallback(RxCallback), uState);
        }

        public void RxCallback(IAsyncResult result)
        {
            UdpState rState = (UdpState)(result.AsyncState);
            UdpClient rClient = rState.client;
            IPEndPoint rEndPoint = rState.endpoint;
            byte[] rxBytes = rClient.EndReceive (result, ref rEndPoint);
            Console.WriteLine ("Received Bytes ___________________________");
            Console.WriteLine (rxBytes.ToString ());

            rClient.BeginReceive (new AsyncCallback(RxCallback), rState);
        }
    }
}

我的简单测试实例化了这个类,然后向它发送一个虚拟的字节数据包。我现在没有测试结果,只是在我的RxCallback方法中放置一个断点。

这是我的NUNIT测试:

using NUnit.Framework;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UdpPractice;

namespace UdpTest
{
    [TestFixture ()]
    public class Test
    {
        [Test ()]
        public void TestCase ()
        {
            // Setup Receiver
            IPAddress address = new IPAddress (new byte[] { 127, 0, 0, 1 });
            int port = 14580;
            UdpCom com = new UdpCom (address, port);
            com.uClient.Connect (com.uEndpoint);
            // Set up sender
            UdpClient sender = new UdpClient(new IPEndPoint (address, port));
            sender.Connect (address, port);

            // Dummy Data
            byte [] dummyData = new byte[] {1, 2, 3, 4, 4, 5};

            sender.Send (dummyData, dummyData.Length);
            Thread.Sleep (100);

            // Close
            sender.Close ();
            com.uClient.Close ();
        }
    }
}

我的问题是当我在线路上的RxCallback方法中我正在尝试检索字节时,我得到了这个例外:

System.ObjectDisposedException has been thrown
Cannot access a disposed object.
Object name: System.Net.Sockets.UdpClient

我希望能够将这些字节存储在UdpCom类的队列中,但我首先无法访问它们。

我可能也未能在这里看到一些基本的UDP概念,但它似乎相当直接。

我一直关注的udp示例是:

修改的 我更新了我的类和测试如下,所以我不使用本地环回。但我仍然得到同样的例外。 UdpCom现在是:

using System;
using System.Net;
using System.Net.Sockets;


namespace UdpPractice
{
    public class UdpState
    {
        public UdpClient client;
        public IPEndPoint endpoint;
        public UdpState(UdpClient c, IPEndPoint iep)
        {
            this.client = c;
            this.endpoint = iep;
        }
    }
    public class UdpCom
    {
        public UdpState uState;
        public UdpClient uClient;
        public IPAddress address;
        public int port;
        public IPEndPoint uEndpoint;

        public UdpCom (IPAddress address, int port)
        {
            uEndpoint = new IPEndPoint (address, port);
            uClient = new UdpClient (uEndpoint);
            uState = new UdpState (uClient, uEndpoint);
            uClient.BeginReceive (new AsyncCallback(RxCallback), uState);
        }

        public void RxCallback(IAsyncResult result)
        {
            UdpState rState = (UdpState)(result.AsyncState);
            UdpClient rClient = rState.client;
            IPEndPoint rEndPoint = rState.endpoint;
            byte[] rxBytes = rClient.EndReceive (result, ref rEndPoint);
            Console.WriteLine ("Received Bytes ___________________________");
            Console.WriteLine (rxBytes.ToString ());

            rClient.BeginReceive (new AsyncCallback(RxCallback), rState);
        }
    }
}

,测试是:

using NUnit.Framework;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UdpPractice;

namespace UdpTest
{
    [TestFixture ()]
    public class Test
    {
        [Test ()]
        public void TestCase ()
        {
            // Setup Receiver
            IPAddress address = new IPAddress (new byte[] { 192, 168, 1, 161 });
            int port = 14580;
            UdpCom com = new UdpCom (IPAddress.Any, port);
            // com.uClient.Connect (com.uEndpoint);
            // Set up sender
            UdpClient sender = new UdpClient(new IPEndPoint (address, port));
            sender.Connect (address, port);

            // Dummy Data
            byte [] dummyData = new byte[] {1, 2, 3, 4, 4, 5};

            sender.Send (dummyData, dummyData.Length);
            Thread.Sleep (100);

            // Close
            sender.Close ();
            com.uClient.Close ();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我想我一直在努力解决与如何与UDP通信的基本误解。

UdpCom:

using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;

namespace UdpPractice
{
    public class UdpState
    {
        public UdpClient client;
        public IPEndPoint endpoint;
        public UdpState(UdpClient c, IPEndPoint iep)
        {
            this.client = c;
            this.endpoint = iep;
        }
    }
    public class UdpCom
    {
        public UdpState uState;
        public IPAddress address;
        public int port;
        public IPEndPoint uEndpoint;
        public bool receiveFlag;
        public List<byte[]> rxBytesBuffer;

        public UdpCom (IPAddress address, int port)
        {
            uEndpoint = new IPEndPoint (address, port);
            // uClient = new UdpClient (uEndpoint);
            uState = new UdpState (new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), port)), uEndpoint);
            receiveFlag = false;
            uState.client.BeginReceive (new AsyncCallback(RxCallback), uState);
            rxBytesBuffer = new List<byte[]> ();
        }

        public void RxCallback(IAsyncResult result)
        {
            UdpState rState = (UdpState)result.AsyncState;
            UdpClient rClient = ((UdpState)result.AsyncState).client;
            IPEndPoint rEndPoint = ((UdpState)result.AsyncState).endpoint;
            byte[] rxBytes = rClient.EndReceive (result, ref rEndPoint);
            rxBytesBuffer.Add (rxBytes);
            Console.WriteLine ("Received Bytes ___________________________");
            Console.WriteLine (rxBytes.ToString ());
            receiveFlag = true;
            rClient.BeginReceive (new AsyncCallback(RxCallback), result.AsyncState);
        }
    }
}

测试:

using NUnit.Framework;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UdpPractice;

namespace UdpTest
{
    [TestFixture ()]
    public class Test
    {
        [Test ()]
        public void TestCase ()
        {
            // Setup Listener
            int port = 14580;
            IPEndPoint locep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
            // Server (Listener)
            UdpCom com = new UdpCom (IPAddress.Any, port);
            // Set up sender
            UdpClient sender = new UdpClient();
            // Dummy Data
            byte [] dummyData = new byte[] {1, 2, 3, 4, 4, 5};
            sender.Send (dummyData, dummyData.Length, locep);
            sender.Send (dummyData, dummyData.Length, locep);
            Thread.Sleep (100);
            Assert.AreEqual(true, com.receiveFlag);
        }
    }
}

我需要让监听器监听IPAddress.Any然后我主要使用Send方法和EndPoint参数。我不得不在那里添加延迟,因为否则没有设置接收标志。