好的,这是我的第一个堆栈溢出问题,所以请随时提出更好的提问方式或下次我应该包括的内容。大多数时候我可以谷歌得到我的答案,但这一个有点棘手......
我正在用 C# 编写一个 Windows 应用程序,它侦听 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 } } }
listner 只是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
谢谢,
丁斯代尔