简体   繁体   English

处理来自UdpClient.BeginReceive()的传入消息

[英]Processing incoming messages from UdpClient.BeginReceive()

Okay, this is my first stack overflow question so please feel free to suggest better ways to ask or what I should include next time. 好的,这是我的第一个堆栈溢出问题,所以请随时提出更好的提问方式或下次我应该包括哪些内容。 Most of the time I can Google to get my answers but this one is a little trickier... 在大多数情况下,我可以通过Google获得答案,但是这一点有些棘手...

I am writing a windows application in C# that listens on a UDP port and then process the incoming UDP messages. 我正在用C#编写Windows应用程序,该应用程序侦听UDP端口,然后处理传入的UDP消息。 More specifically, I am using the UDPClient class and listening using the BeginReceive method. 更具体地说,我使用的是UDPClient类和使用BeginReceive方法听。 The receive callback is in turn firing it's own message received event and then resetting the UDP client again. 接收回调依次触发它自己的消息接收事件,然后再次重置UDP客户端。 This "MessageReceived" event is subsequently handled by a processor object. 此“ MessageReceived”事件随后由处理器对象处理。

I thought that was all pretty smart until my manager posed some questions to me such as: 在经理向我提出一些问题之前,我一直认为这很聪明。

  • How many messages can this receive at one time? 一次可以收到多少封邮件? What happens if we get more than that? 如果我们得到的更多,会发生什么?
  • Are the messages queued or will they be lost if processing takes too long? 消息是否排队,如果处理时间太长,消息会丢失吗?
  • What does happen if the processing takes too long? 如果处理时间太长会怎样?

We cannot be losing the messages because the last one was still processing, and we can't be building up until the system crashes because it's out of memory either. 我们不能丢失消息,因为最后一条消息仍在处理中,我们也无法建立消息,直到系统崩溃为止,因为它也没有内存。 What he would like to hear (and rightfully so) is some sort of verification that there is a deterministic way to deal with a "storm" of messages. 他想听到的消息(正确地如此)是某种验证,表明存在确定性的方式来处理“风暴”消息。 Unfortunately, I have no idea where to go with this to get an answer. 不幸的是,我不知道在哪里可以得到答案。 I have included what I think is the relevant code below. 我在下面包括了我认为是相关的代码。

So: 所以:

  1. Does anyone know the answers to the questions above? 有人知道上述问题的答案吗?
  2. Where would I do some research to find these answers and/or some patterns to follow for this sort of thing? 我将在哪里进行研究以找到这些问题的答案和/或遵循的模式?
  3. What kind of tools could I use to watch the processing for debugging/performance profiling? 我可以使用哪种工具来监视调试/性能分析的过程?
  4. If I have made a huge mistake in my design, what should I do to sort it out (ie introduce a queue, use a thread pool etc)? 如果我在设计中犯了一个严重错误,该怎么办才能解决问题(即引入队列,使用线程池等)?

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

listner is just a wrapper around UDPClient . 听者只是周围的包装UDPClient As follows: 如下:

#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

Thanks, 谢谢,

Dinsdale Dinsdale

If losing messages is a concern, then UDP isn't for you. 如果担心丢失消息,那么UDP不适合您。 UDP guarantees only that if the message arrives, it will be complete. UDP仅保证如果消息到达,它将是完整的。 It does not guarantee message order or delivery. 它不保证消息的顺序或传递。 In other words, if a client sends two messages, you might receive them out of order, or only the first, or only the last (or none at all). 换句话说,如果客户端发送两个消息,则您可能会无序接收它们,或者仅接收第一个消息,或者仅接收最后一个消息(或根本不接收)。 If you need to guarantee delivery and order, use TCP instead (TCP comes with it's own set of guarantees and gotchas). 如果您需要保证交货和订购,请改用TCP(TCP附带了它自己的保证和陷阱)。

With regard how many messages it can process, you will have an upper limit. 关于它可以处理多少条消息,您将有一个上限。 If you aren't processing messages faster than they are arriving, then they will be queued, either in your application layer or in the UDP networking layer. 如果您处理消息的速度比到达消息的速度快,那么它们将在应用程序层或UDP网络层中排队。 Once the network buffers are full, your network interface will simply begin throwing away messages. 一旦网络缓冲区已满,您的网络接口就会开始丢弃消息。

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

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