好的,这是我的第一个堆栈溢出问题,请随时提出更好的方法来问或我下次应该包括什么。大多数时候我可以谷歌来得到我的答案,但这一个是有点棘手......处理来自UdpClient.BeginReceive()的传入消息()
我正在写一个Windows应用程序在C#中侦听一个UDP端口,然后处理传入的UDP消息。更具体地说,我使用UDPClient
类,并使用BeginReceive方法进行侦听。接收回调反过来激发它自己的消息接收事件,然后再次重置UDP客户端。这个“MessageReceived”事件随后由处理器对象处理。
我认为这是所有非常聪明,直到我的经理提出了一些问题,以我如:
- 这多少信息可以接收一次?如果我们获得的不仅仅是这些,会发生什么
- 如果处理时间过长,消息是排队还是会丢失?
- 如果处理时间过长会发生什么?
我们不能丢失消息,因为最后一个仍在处理中,我们不能建立起来,直到系统崩溃,因为它的内存不足。他希望听到的(以及理所当然的)是某种验证,即有一种确定的方式来处理消息的“风暴”。不幸的是,我不知道该怎么去得到答案。我已经包含了我认为是下面的相关代码。
所以:
- 有谁知道答案,上述问题?
- 我在哪里可以做一些研究来找到这些答案和/或一些模式以遵循这种事情?
- 我可以使用哪种工具来观察调试/性能分析的处理过程?
如果我在设计中犯了一个大错误,我应该怎么做才能对它进行排序(即引入一个队列,使用线程池等)?
public void ReceiveCallback(IAsyncResult ar) { //Cast the item back to the listener UdpListener listener = (UdpListener)ar.AsyncState; //If we are supposed to be listening, then get the data from the socket //Listen is false during shutdown if (Listen) { //The try catch is placed inside the listen loop so that if there is an error in the processing it will //recover and listen again. this may cause more exceptions but we can be sure that it will not // stop listening without us knowing try { //Address and port from the external system IPEndPoint ep = listener.EndPoint; //Get the data from the async read Byte[] receiveBytes = listener.Client.EndReceive(ar, ref ep); //Reset the socket to listen again listener.Client.BeginReceive(new AsyncCallback(ReceiveCallback), listener); //Execute the event to pass external components the message HeartbeatEventArgs hea = new HeartbeatEventArgs(DateTime.Now, ep, receiveBytes); OnHeartbeatReceived(hea); //Ack back to the external system HeartbeatAcknowledgement(new IPEndPoint(ep.Address, ep.Port), receiveBytes); } catch (Exception e) { log.Error(e.Message); //Reset the socket to listen again } } }
听者是只是一个包装围绕UDPClient
。具体如下:
#region UdpClient Wrapper (UdpListener)
/// <summary>
/// UdpListener is used to control the asynchronous processing of a UDPClient object.
/// </summary>
public class UdpListener
{
/// <summary>
/// IPEndpoint on which to accept a connection. Usually set to "Any".
/// </summary>
public IPEndPoint EndPoint { get; set; }
/// <summary>
/// The socket based client object that is used for communication
/// </summary>
public UdpClient Client { get; set; }
public UdpListener(int port)
{
EndPoint = new IPEndPoint(IPAddress.Any, port);
Client = new UdpClient(EndPoint);
}
}
#endregion
感谢,
Dinsdale
好的,这是一个开始!我知道UDP不保证任何可靠性。我无法控制使用的协议。如果收到我们不希望从应用程序端丢失的消息,那么问题就很简单。所以我应该在处理消息之前先清除我的网络缓冲区(即将消息放入队列?) – Dinsdale 2013-02-18 23:34:40
这将是一个好方法。将消息移动到队列中,然后异步处理它们。您可以监控您的队列大小,以确保您有足够的容量。衡量的另一个指标是单个消息在队列中等待处理的时间。如果其中任何一个很大,那么你将不得不修改你的架构。 – 2013-02-18 23:51:43