Отправка/получение UDP в .NET

Я новичок в UDP. Используя тестовую среду, я могу отправить/получить одно сообщение UDP. Однако я пытаюсь понять, как получать несколько сообщений UDP. Я бы хотел, чтобы служба MyListener получала пакеты UDP в течение всего дня, когда бы я их ни отправлял. Я ценю любую помощь.

PS. Как указано ниже в ответе, если я поставлю while (true) вокруг своего DoSomethingWithThisText, это будет работать во время отладки. Однако это не сработает при попытке запустить MyListener как службу, потому что Start никогда не пройдет цикл while(true).

Мой сервис прослушивания выглядит так...

public class MyListener
{
    private udpClient udpListener;
    private int udpPort = 51551;

    public void Start()
    {
        udpListener = new UdpClient(udpPort);
        IPEndPoint listenerEndPoint = new IPEndPoint(IPAddress.Any, udpPort);
        Byte[] message = udpListener.Receive(ref listenerEndPoint);

        Console.WriteLine(Encoding.UTF8.GetString(message));
        DoSomethingWithThisText(Encoding.UTF8.GetString(message));
    }
}

Мой отправитель выглядит так:

static void Main(string[] args)
{
    IPAddress ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 });
    int port = 51551;

    //define some variables.

    Console.Read();
    UdpClient client = new UdpClient();
    client.Connect(new System.Net.IPEndPoint(ipAddress, port));
    Byte[] message = Encoding.UTF8.GetBytes(string.Format("var1={0}&var2={1}&var3={2}", new string[] { v1, v2, v3 }));
    client.Send(message, message.Length);
    client.Close();
    Console.WriteLine(string.Format("Sent message");
    Console.Read();
}

person WEFX    schedule 12.08.2011    source источник


Ответы (2)


Вы должны вызвать получение через некоторое время или какой-либо другой цикл.

person Lior Ohana    schedule 12.08.2011
comment
Если я добавлю цикл while(true) вокруг моего DoSomethingWithThisText, это ПОМОЖЕТ, но работает только в отладчике. Если я попытаюсь запустить MyListener как службу, служба истечет по тайм-ауту при запуске, потому что она никогда не преодолеет цикл while(true). - person WEFX; 12.08.2011

В итоге я использовал асинхронные методы Microsoft, найденные здесь — BeginReceive и EndReceive .

Как предлагает Microsoft, я вызываю BeginReceive в моем методе Start следующим образом:

UdpState s = new UdpState();
s.e = listenerEP;
s.u = udpListener;

udpListener.BeginReceive(new AsyncCallback(ReceiveCallback), s);

Однако, чтобы слушатель продолжал получать сообщения, я вызываю BeginReceive AGAIN внутри функции ReceiveCallback, рекурсивно. Это, конечно, потенциальная утечка памяти, но я еще не сталкивался с проблемами при регрессионном тестировании.

private void ReceiveCallback(IAsyncResult ar)
{
    UdpClient u = (UdpClient)((UdpState)ar.AsyncState).u;
    IPEndPoint e = (IPEndPoint)((UdpState)ar.AsyncState).e;

    UdpState s = new UdpState();
    s.e = e;
    s.u = u;
    udpListener.BeginReceive(new AsyncCallback(ReceiveCallback), s); 

    Byte[] messageBytes = u.EndReceive(ar, ref e);
    string messageString = Encoding.ASCII.GetString(messageBytes);

    DoSomethingWithThisText(messageString);
}
person WEFX    schedule 15.08.2011
comment
Здесь нет утечки ресурсов, поскольку вы вызвали EndReceive, все ресурсы, связанные с каждой операцией чтения, очищаются правильно. Обратите внимание, что в наши дни ReadAsync может быть предпочтительнее. - person Ben Voigt; 02.10.2014