C#编程实现DNS Client和Server(转)

我们大多数人使用DNS主要是用于域名解析,近期有个特殊的需求:通过DNS协议传递特殊数据。翻遍互联网,最终找到了一个强大的C# DNS工具库  ARSoft.Tools.Net library ,感谢CodePlex,感谢 AlexReinert !

关于DNS协议,请参考微软在线文档DNS的体系结构 或 RFC系列文档 。

我的要求很简单,把特定的DNS请求数据包发送到指定的服务器并获得返回结果。为了完成这个验证工作,你需要和我一样具备以下条件:

1.拥有一台具有外网地址的服务器,如:54.243.209.209;

2.设置防火墙策略,放行53/UDP端口的通讯;(非常重要,我测试的时候走了弯路-_-)

3.设置域名subA.mooo.com 的 A记录为 54.243.209.209

4.设置域名subB.mooo.com 的 NameServer为 subA.mooo.com

5.根据以上设置,但我们请求解析xxx.subB.mooo.com的域名时,54.243.209.209会收到来自DNS服务器的DNS请求数据包;

6.响应这个数据包就可以完成一次标准的DNS请求响应;

7.构造特殊的域名就可以实现特征数据的传递;

接下来,分别编写客户端和服务端代码。也可以参考官方文档中的样例:http://arsofttoolsnet.codeplex.com/ 配合WireShark抓包分析,能够很好地帮助您调试程序。

C#编程实现实现DNS请求客户端

新建一个C#项目,使用dotNet Framework 3.5作为运行环境。添加对库文件“ARSoft.Tools.Net.dll”的引用。编写如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ARSoft.Tools.Net.Dns;

namespace MyDNSClient
{
    /// <summary>
    /// @auth shadu{AT}foxmail.com
    /// @desc C# DNS Client
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            //ClientQuery("www.baidu.com");
            ClientQuery("xxx.subB.mooo.com");
            Console.ReadKey();
        }

        public static void ClientQuery(string domain)
        {
            DnsMessage dnsMessage = DnsClient.Default.Resolve(domain, RecordType.A);
            if ((dnsMessage == null) || ((dnsMessage.ReturnCode != ReturnCode.NoError) && (dnsMessage.ReturnCode != ReturnCode.NxDomain)))
            {
                Console.WriteLine("DNS request failed");
            }
            else
            {
                foreach (DnsRecordBase dnsRecord in dnsMessage.AnswerRecords)
                {
                    ARecord aRecord = dnsRecord as ARecord;
                    if (aRecord != null)
                    {
                        Console.WriteLine("DNS request successfully : {0}",aRecord.Address.ToString());
                    }
                }
            }
        }
    }
}

C#编程实现实现DNS响应服务端

新建一个C#项目,使用dotNet Framework 3.5作为运行环境。添加对库文件“ARSoft.Tools.Net.dll”的引用。编写如下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ARSoft.Tools.Net.Dns;
using System.Net;

namespace DNSServer
{
    /// <summary>
    /// @auth shadu{AT}foxmail.com
    /// @desc C# DNS Server
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            using (DnsServer server = new DnsServer(IPAddress.Any, 10, 10, ProcessQuery))
            {
                server.Start();
                Console.WriteLine("Press any key to stop server");
                Console.ReadLine();
            }
        }

        static DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, System.Net.Sockets.ProtocolType protocol)
        {
            message.IsQuery = false;
            DnsMessage query = message as DnsMessage;

            // 官方的样例文档中没有体现DNS请求发起者的IP,我在这里增加了。
            Console.WriteLine("Client Address:{0}", clientAddress.ToString());
            Console.WriteLine("query.Questions.Count:{0}", query.Questions.Count);
            Console.WriteLine("query.Questions.ToString():{0}", query.Questions.ToString());
            Console.WriteLine("query.Questions[0].ToString():{0}", query.Questions[0].ToString());
            Console.WriteLine("query.Questions[0].GetType():{0}", query.Questions[0].GetType().ToString());
            Console.WriteLine("query.Questions[0].Name:{0}", query.Questions[0].Name.ToString());
            Console.WriteLine("query.Questions[0].RecordType:{0}", query.Questions[0].RecordType.ToString());
            Console.WriteLine("query.Questions[0].RecordClass {0}", query.Questions[0].RecordClass.ToString());

            if (query.Questions[0].Name.Contains("subB.mooo.com"))
            {

                Console.WriteLine("Contains subB.mooo.com");
                query.AnswerRecords.Add(new ARecord("xxx.subB.mooo.com", 3600, IPAddress.Parse("9.9.9.9")));
                message.ReturnCode = ReturnCode.NoError;
                return message;

            }
            else
            {
                Console.WriteLine("!!! not Contains mooo");
                message.ReturnCode = ReturnCode.ServerFailure;
                Console.WriteLine(message.ReturnCode.ToString());

                return message;
            }
        }
    }
}

服务端效果如图:

时间: 2024-12-25 11:22:54

C#编程实现DNS Client和Server(转)的相关文章

UDP编程中client和server中使用recvfrom和sendto的区别

client中:      sendto(sfd,buf,strlen(buf),0,(struct sockaddr *)&saddr,len);      recvfrom(sfd,buf,sizeof(buf),0,NULL,NULL);server中:      recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr *)&caddr,&len); 将网络字节序的IP地址转换成字符串输出 // inet_ntoa : struct ip

Socket编程】使用C++实现Server端和Client端

我是在Visual Stdio 2013上建立了两个工程,分别编译运行下面的两个main文件,然后进行测试的 服务端:Server.cpp #include #include using std::cout; using std::cin; using std::endl; #include using std::string; #pragma comment(lib,"ws2_32.lib") void main() { //创建套接字 WORD myVersionRequest;

SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数

原文:SQL Server中的CLR编程--用.NET为SQL Server编写存储过程和函数 很早就知道可以用.NET为SQL Server2005及以上版本编写存储过程.触发器和存储过程的,不过之前开发的系统要么因为历史原因用的是SQL2000要么根本用不着在SQL Server中启用CLR,所以一直没有尝试.最近因为项目的原因,在这方面做了一个调研,现在在这里分享一下心得. 首先要说明的是要在SQL Server中启用CLR必须是在SQL Server2005及以上版本,其次在默认情况下是

【AD】【Server2008R2】 PDC NTP Client/NTP Server的设置 ...

上家公司有碰到过PDC主机时间异常导致客户端时间异常的问题,当时没有解决.最近正好看到,就想试试能否解决一下. 论坛搜索了,照着帖子中的都测试了,没有成功.网上也搜了很久,最后一篇文章给了我不少启发. http://gnaw0725.blog.51cto.com/156601/660266下面的内容是我经过反反复复的测试后得出的结论.与上述链接中的内容并不完全一致.有条件的你可以在虚拟机中测试,相信我的测试不会让你失望. 帖子中会反复出现的命令: w32tm 这个命令需要开启"Windows T

Netty Client和Server端实现

本文基于Nett4.0.26.Final版本浅析Client与Server端通讯,先看服务器端: public class Server { public static void run(int port) { /**Netty创建ServerSocketChannel,默认SelectionKey.OP_ACCEPT*/ EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoop

分布式数据库数据从属与client与server的数据同步

老实说,眼下市面上很多产品,的确是不成熟的产品. 用过一些,给人蛋痛的感觉. 导言 分布还是集总 今天我们来探讨一个非常重要的问题. 每一个程序猿都有其思想,我的思想之中的一个,就是分布式. 分布式,面对的一个问题,就数据的同步. 比方说.我们人类是分布式的,我们每一个细胞都在无时无刻与其他细脑交换数据. 而现实世界.我们的设计是什么样子?一般都是集总式. 首先来说,这样的方式,与现实世界并不一致.所以.带来的最严重的一个影响就是效率的问题. 自己这些年,一直在无线通信领域. 无线通信.有两个重

iOS 中client和server的 Web Service 网络通信 (1)

当你打开你手机上新浪微博应用或者知乎应用是.你是否会去想这些显示在手机上的图片和数据时从哪里来的?又是通过如何的方法实现的?好.那么接下来就介绍是如何实现的.过程又是怎么样的.      当我们浏览着关注或者好友的微博时.那些图片和数据不是凭空出现的,而是通过你的client向server请求后由新浪微博的server返回本地所获得,通过数据的解析就行在client上进行显示,甚至是操作.而这些,就是我们通常所说的 Web Service. Web Service 技术是一种通过 Web 协议提

jvm的client和server

最近研究c++代码调用java的jar,发现64位的下的jvm在server路径,而32位的jvm则存在client路径下面,于是十分好奇,查了下,这里做个记录 JVM Server模式与client模式启动,最主要的差别在于:-Server模式启动时,速度较慢,但是一旦运行起来后,性能将会有很大的提升.原因是: 当虚拟机运行在-client模式的时候,使用的是一个代号为C1的轻量级编译器, 而-server模式启动的虚拟机采用相对重量级,代号为C2的编译器. C2比C1编译器编译的相对彻底,,

Python Socket Client及Server简单编程

本文主要介绍使用Python语言编写Socket协议Server及Client的简单实现方法. 1. Python Socket编程简介 Socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 三种流行的套接字类型是:stream,datagram和raw.stream和datagram套接字可以直接与TCP协议进行接口,而raw套接字则接口到IP协议. Python Socket模块提供了对低层BSD套接字样式网络的访问,使用