In this page, I will describe how to use the DNS Implementation.

First of all, what we need is the address of the DNS Server (can be a multicast address) :
//First of all, let's say from where we are going to send/receive messages
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 5353)
//DNS uses the Udp protocol so we create a UDP client
client = new UdpClient();
//Setting reuse address enables to have a binding on port 5353 (already used by the official Apple Bonjour service).
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
client.Client.Bind(endpoint);

Now, it depends if you want to have some synchonous or asynchronous way to send/receive DNS queries. I personnaly have opted in an asynchronous way, using events to notify of a new message incoming.

Here is the code to connect to a multicast DNS service
client.MulticastLoopback = true;
client.JoinMulticastGroup(EndPoint.Address, 10);

To join to a classic DNS service, here is the code that should work (not tested) :
client.Connect(EndPoint);

In both previous cases, the EndPoint is an IPEndPoint containing the address and port on which you want to connect to.
// this is the mDNS address, you're up to change it to whatever you want.
// Here I use the 5353 port because I am based on a multicast DNS, but you may use 53 port to use a classic DNS service.
public static readonly IPEndPoint EndPoint = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353);

Now we are connected to the DNS service, we can send/receive DNS messages.

First, let's ask some one for a name
Message message = new Message();
// Construction of an ID for the request (I took the 2 first bytes of a guid)
List<byte> guid = Guid.NewGuid().ToByteArray().Take(2).ToList();
message.ID = (ushort)(guid[0] * byte.MaxValue + guid[1]); = requestId;
//I use Mulhouse here to represent a name I would like to resolve. Why Mulhouse ? Because this is where I live.
message.Questions.Add(new Question("Mulhouse"));
// The EndPoint is the DNS Service. (the EndPoint variable declared as static readonly above.
Send(message, EndPoint);

Ok now, our request have been sent, we need to receive a request.
So the first thing we need is to wait for something. As I said before, I have chosen an asynchronous way to receive messages.
client.BeginReceive(StartReceiving, null);


        private void StartReceiving(IAsyncResult result)
        {
            //Let's just make sure we have received all datas.
            result.AsyncWaitHandle.WaitOne();
            // Here I create a dummy endpoint because the EndReceive method requests one. This will be assigned to the endpoint that have sent the message (query/answer)
            IPEndPoint src = new IPEndPoint(IPAddress.Any, 0);
            byte[] response = client.EndReceive(result, ref src);
            // Now I have received the message, I treat it.
            Treat(response, src);
        }

Here comes the most interesting part. The message treatment.
        protected void Treat(byte[] bytes, IPEndPoint from)
        {
            Message m;
            try
            {
                m = Message.FromBytes(bytes);
            }
            catch (Exception)
            {
                //BadRequestReceived
                return;
            }
            m.From = from;
            // If the message we received is the requestID we sent, then it is the answer we were expecting otherwise...
            ushort requestId = this.requestId;
            if ((m.ID == requestId && m.QueryResponse == Qr.Answer) || m.ID == 0)
            {
                // AnswerReceived is the event to raise when an anwser is received
                if (AnswerReceived != null)
                    AnswerReceived(m);
            }
            if ((m.ID != requestId || m.ID == 0) && m.QueryResponse == Qr.Query)
            {
                this.requestId = 0;
                // QueryReceived is the event to raise when a query is received
                if (QueryReceived != null)
                    QueryReceived(m);
            }

{code:c#}
{code:c#}
{code:c#}
{code:c#}
{code:c#}
{code:c#}
{code:c#}
{code:c#}

Last edited Oct 21, 2009 at 9:35 PM by neonp, version 2

Comments

No comments yet.