我正在编写需要使用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 ();
}
}
}
答案 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
参数。我不得不在那里添加延迟,因为否则没有设置接收标志。