Основа коммуникационного аспекта PostSharp UDP

Привет, Сегодня я хотел бы показать, как просто общаться по сети UDP.. Я иногда видел, как некоторые разработчики пытаются подготовить такого рода коммуникацию с помощью большего количества кода на C#, что может быть очень просто.. Я хотел бы показать вам только пример.. И спросить тебя, достаточно ли общаться? Конечно, это класс, который можно очень легко использовать в качестве основы PostSharp Communication Aspect. Я думаю, что вы можете легко инкапсулировать этот код в аспект ;).

namespace UdpCommunicationExample
{
  using System;
  using System.Diagnostics;
  using System.Net;
  using System.Net.Sockets;
  using System.Threading;
  using System.Runtime.CompilerServices;
  using System.Threading.Tasks;
  public class UdpCommunicationClient
  {
    private readonly UdpClient udpClient;
    public UdpCommunicationClient(IPEndPoint clientIpEndPoint) {
      udpClient = new UdpClient(clientIpEndPoint);
    }
    [MethodImpl(MethodImplOptions.Synchronized)]
    public bool SendData(byte[] datagram, IPEndPoint serverIpEndPoint) {
      lock (this) {
        while (!udpClient.Client.Poll(100, SelectMode.SelectWrite))
          ;
        var asyncResult = udpClient.BeginSend(
          datagram, datagram.Length,
          serverIpEndPoint, null, null);
        asyncResult.AsyncWaitHandle.WaitOne(Timeout.Infinite);
        return datagram.Length == udpClient.EndSend(asyncResult);
      }
    }
  }
  public class UdpCommunicationServer
  {
    private readonly UdpClient udpClientListener;
    public delegate void UdpCommunicatorDatagramReceived(byte[] datagram);
    public event UdpCommunicatorDatagramReceived DatagramReceived;
    public UdpCommunicationServer(IPEndPoint serverIpEndPoint) {
      udpClientListener = new UdpClient(serverIpEndPoint);
      new Thread(StartUdpListener) { IsBackground = true }.Start();
    }
    private void StartUdpListener() {
      do {
        IPEndPoint ipEndPoint = null;
        var asyncResult = udpClientListener.BeginReceive(null, null);
        asyncResult.AsyncWaitHandle.WaitOne(Timeout.Infinite);
        var datagram = udpClientListener.EndReceive(asyncResult, ref ipEndPoint);
        DatagramRecived(datagram);
      } while (true);
    }
    private void DatagramRecived(byte[] datagram) {
      if (DatagramReceived != null)
        DatagramReceived(datagram);
    }
  }
  public class Program
  {
    static void Main() {
      var serverIpEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2000);
      var clientIpEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 2000);
      var udpComunicationServer = new UdpCommunicationServer(serverIpEndPoint);
      var udpComunicationClient = new UdpCommunicationClient(clientIpEndPoint);
      var packetCount = 0;
      udpComunicationServer.DatagramReceived +=
        datagram => Interlocked.Increment(ref packetCount);
      var stopwatch = Stopwatch.StartNew();
      Parallel.For(0, 20000, i => {
        udpComunicationClient
          .SendData(new byte[] { 1,2,3,4,5,6,7,8,9,10 }, serverIpEndPoint);
        udpComunicationClient
          .SendData(new byte[] { 2,2,3,4,5,6,7,8,9,10 }, serverIpEndPoint);
        udpComunicationClient
          .SendData(new byte[] { 3,2,3,4,5,6,7,8,9,10 }, serverIpEndPoint);
        udpComunicationClient
          .SendData(new byte[] { 4,2,3,4,5,6,7,8,9,10 }, serverIpEndPoint);
        udpComunicationClient
          .SendData(new byte[] { 5,2,3,4,5,6,7,8,9,10 }, serverIpEndPoint);
      });
      stopwatch.Stop();
      Thread.Sleep(4);
      Console.WriteLine(@"Sending {0} trivial UDP packets takes about {1} ms.",
        packetCount,
        stopwatch.ElapsedMilliseconds);
      Console.ReadKey();
    }
  }
}

Итак, на моем ПК выходной сигнал::

Sending 100000 trivial UDP packets takes about 4693 ms.

Как вы думаете, что это? 469 мс достаточно для 10 000 параллельные пакеты? Почему большинство разработчиков пишут больше кода для таких решений??

Хорошо, так, что я немного изменю свои решения на что-то худшее.

[MethodImpl(MethodImplOptions.Synchronized)]
public bool SendData(byte[] datagram, IPEndPoint serverIpEndPoint) {
  lock (this) {
    while (!udpClient.Client.Poll(100, SelectMode.SelectWrite))
      ;
    return datagram.Length == udpClient.Send(
      datagram, datagram.Length,
      serverIpEndPoint);
  }
}
private void StartUdpListener() {
  do {
    IPEndPoint ipEndPoint = null;
    var datagram = udpClientListener.Receive(ref ipEndPoint);
    DatagramRecived(datagram);
  } while (true);
}

И после этих изменений все выглядит очень круто и на выходе получается:

Sending 100000 trivial UDP packets takes about 2358 ms.

п ;).

оставьте ответ

Ваш электронный адрес не будет опубликован. Обязательные поля помечены *

*

Этот сайт использует Akismet для уменьшения спама.. Узнайте, как обрабатываются данные ваших комментариев.