简体   繁体   English

在本地测试UDP C#

[英]Testing UDP Locally C#

I am writing a mono C# application that needs to use UDP. 我正在编写一个需要使用UDP的Mono C#应用程序。 I was writing my test suite so that I could make sure packets are received properly with NUnit. 我正在编写测试套件,以便确保可以使用NUnit正确接收数据包。

I made a minimal working example with a UdpCom class that is supposed to just listen right now and print out the bytes it receives in the call back method. 我使用UdpCom类制作了一个最小的工作示例,该类应该立即监听并打印出在回调方法中接收到的字节。

My minimal UdpCom class looks like: 我最小的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);
        }
    }
}

My simple test instantiates this class and then sends it a dummy packet of bytes. 我的简单测试将实例化此类,然后向其发送一个虚拟的字节包。 I am not testing the result right now, just placing a break point in my RxCallback method. 我现在不测试结果,只是在我的RxCallback方法中放置一个断点。

This is my NUNIT test: 这是我的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 ();
        }
    }
}

My Issue is that when I'm in the RxCallback method on the line that I'm trying to retrieve the bytes I am getting this exception: 我的问题是,当我在尝试检索字节的行上使用RxCallback方法时,遇到了以下异常:

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

I want to be able to store these bytes in a queue in my UdpCom class but I am having trouble accessing them in the first place. 我希望能够将这些字节存储在我的UdpCom类的队列中,但是我首先无法访问它们。

I may be failing to udner stand some basic UDP concepts as well here but it seems pretty straght forward. 我可能在这里也无法理解一些基本的UDP概念,但是看起来挺直的。

The udp examples I have been following are: 我一直关注的udp示例如下:

EDIT I updated my class and tests as follows so I don't use the local loopback. 编辑我更新了我的课程并进行了如下测试,所以我不使用本地环回。 But I am still getting the same exception. 但是我仍然遇到同样的例外。 UdpCom is now: 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);
        }
    }
}

and the test is: 测试是:

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 ();
        }
    }
}

I guess I was struggling with a basic misunderstanding with how to communicate with UDP. 我想我在如何与UDP通信方面遇到了基本的误解。

UdpCom: 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);
        }
    }
}

Test: 测试:

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);
        }
    }
}

I needed to make the listener listen to IPAddress.Any and then I mainly used the Send method with the EndPoint argument. 我需要让侦听器侦听IPAddress.Any ,然后主要使用带有EndPoint参数的Send方法。 I had to add the delay in there because otherwise the receive flag wasn't being set. 我必须在其中添加延迟,因为否则未设置接收标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM