If the first part of your code is essentially the body of your main function you shouldn't be surprised that it ends. Put a
Console.Readline();
before the closing }
of main
to wait.
recv
will be called asynchronously as soon as some data arrived. Then you need to read the received data from the very UDP client that was waiting. In order to access this client you'll hand it over via the state parameter of BeginReceive
client.BeginReceive(new AsyncCallback(recv), client);
and finally get it from the callbacks IAsyncResult parameter
UdpClient client = (UdpClient)res.AsyncState;
It may be easier (but less flexible) to store the client in a class field.
Now you get your data from
byte[] received = client.EndReceive(res, ref RemoteIpEndPoint);