c语言实现域名解析


对原文进行了一点小修改,原文可能是在C++环境编译的,比如“.cpp”后缀的文件编译的,“.cpp”文件默认以C++方式编译,所以原文如果复制保存为“.c”后缀的,编译是通不过的,很多错误。以下是修改过后的代码,DNS请修改为自己所在区域的DNS地址,经测试,直接使用路由IP也可。域名输入例如:“www.baidu.net”,不含引号。测试“www.csdn.net”得到的IP在浏览器打开不是csdn,不知道为什么,其他域名未测试。

c语言实现域名解析:

[cpp]  view plain copy
  1. #include   <stdio.h>  
  2. #include   <Winsock2.h>  
  3. #include   <windows.h>  
  4.   
  5. typedef enum {false = 0, true = !false}bool;  
  6. typedef struct _DNSHEAD{        //dns 头部  
  7.     USHORT ID;  
  8.     USHORT tag; // dns 标志(参数)  
  9.     USHORT numQ;        // 问题数  
  10.     USHORT numA;        // 答案数  
  11.     USHORT numA1;       // 权威答案数  
  12.     USHORT numA2;       // 附加答案数  
  13. }DnsHead;  
  14. typedef struct _DNSQUERY    //dns 查询结构  
  15. {  
  16.     //    char   name[64];  
  17.     //      //查询的域名,这是一个大小在0到63之间的字符串;  
  18.     USHORT type;  
  19.     //查询类型,大约有20个不同的类型  
  20.     USHORT classes;  
  21.     //查询类,通常是A类既查询IP地址。  
  22.       
  23. }DnsQuery;  
  24.   
  25. #pragma comment(lib,"ws2_32.lib")  
  26.   
  27. // 初始化操作  
  28. bool initWSA();  
  29.   
  30. //显示错误  
  31. void displayErrWSA(char *str);  
  32.   
  33. //创建套接字  
  34. SOCKET CreateSocket(int type);  
  35.   
  36. //UDP sendto  
  37. int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port);  
  38.   
  39. //TCP 连接  
  40. bool MyConnect(SOCKET s, char *addr,USHORT );  
  41.   
  42. // UDP recvfrom  
  43. int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port);  
  44.   
  45. //设置DNS 头部  
  46. bool SetDNSHead(char *name,char *buf);  
  47.   
  48. int main(int arg,char *are[])  
  49. {  
  50.     int Result=0;  
  51.     char buf[1024]={0};  
  52.     char addr[16] = "192.168.1.1";// dns 服务器地址  
  53.     char *name = 0; //要查询的域名  
  54.     SOCKET sockTo;  
  55.     int len;  
  56.     DnsHead *DnsH;  
  57.     char *getIP;  
  58.     //int i;  
  59.       
  60.     if ( !initWSA() )//初始化  
  61.     {  
  62.         displayErrWSA("initWSA err!");  
  63.         return 1;  
  64.     }  
  65.       
  66.     //创建套接字  
  67.     if ( (sockTo = CreateSocket(SOCK_DGRAM)) == 0)  
  68.     {  
  69.         displayErrWSA("CreatSocket err!");  
  70.         return 1;  
  71.     }  
  72.     while (1)  
  73.     {  
  74.         if (arg < 2)  
  75.         {  
  76.             char temp[1024]={0};  
  77.             printf("\n请输入要查询的域名:");  
  78.             scanf("%s",temp);  
  79.             if (temp[0] == 'q' ||temp[0] == 'Q')  
  80.             {  
  81.                 break;  
  82.             }  
  83.             name =  temp;  
  84.         }  
  85.         else  
  86.         {  
  87.             arg = 1;  
  88.             name =  are[1];  
  89.         }  
  90.           
  91.         //设置dns 头部  
  92.         SetDNSHead(name,buf);  
  93.           
  94.         //发送出去的请求数据长度  
  95.         len = sizeof(DnsHead)+sizeof(DnsQuery)+strlen(name)+2;  
  96.           
  97.         //      for (int  i =0;i<50;i+=2)  
  98.         //      {  
  99.         //          printf("x",(UCHAR)buf[i]);  
  100.         //          printf("x ",(UCHAR)buf[i+1]);  
  101.         //      }  
  102.         //发送DNS 请求  
  103.         if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)  
  104.         {  
  105.             displayErrWSA("sendto err!");  
  106.             continue;  
  107.         }  
  108.           
  109.         //接收应答  
  110.         if ( (Result =MyRecvFrom(sockTo,buf,1024,addr,53) ) <=  0)  
  111.         {  
  112.             displayErrWSA("recvfrom err!");  
  113.             continue;  
  114.         }  
  115.           
  116.         //简单的取得返回的 IP 地址( 收到的最后4字节 )  
  117.         DnsH = (DnsHead *)buf;  
  118.         if (DnsH->numA == 0)  
  119.         {  
  120.             printf("无法解析 %s 的IP 地址。\n",name);  
  121.             continue;  
  122.         }  
  123.         getIP =(char *)buf +Result - 4;  
  124.         printf("%s 的IP地址为: ",name);  
  125.         for (Result= 0 ;Result<4 ;Result++)  
  126.         {  
  127.             printf("%u.",(UCHAR )getIP[Result]);  
  128.         }  
  129.         printf("\n");  
  130.     }  
  131.     return 0;  
  132. }  
  133.   
  134. // 初始化操作  
  135. bool initWSA()  
  136. {  
  137.     WORD   wVersionRequested;  
  138.     WSADATA   wsaData;  
  139.     int Result;  
  140.     wVersionRequested = MAKEWORD( 2, 2 );  
  141.     Result = WSAStartup( wVersionRequested, &wsaData );  
  142.     if(Result   !=   0 )  
  143.     {  
  144.         return false;  
  145.     }  
  146.       
  147.     if( LOBYTE( wsaData.wVersion) != 2 ||  
  148.         HIBYTE(wsaData.wVersion)!= 2 )  
  149.     {  
  150.         WSACleanup();  
  151.         return false;  
  152.     }  
  153.     return true;  
  154. }  
  155.   
  156. SOCKET CreateSocket(int type)  
  157. {  
  158.     SOCKET  sock=socket(AF_INET,type,0);  
  159.     if (sock == INVALID_SOCKET )  
  160.     {  
  161.         return 0;  
  162.     }  
  163.     return sock;  
  164. }  
  165.   
  166. int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port)  
  167. {  
  168.     //设置发送数据到的 套接字及地址结构  
  169.     SOCKADDR_IN   addrTo;  
  170.     addrTo.sin_addr.S_un.S_addr=inet_addr(addr);  
  171.     addrTo.sin_family=AF_INET;  
  172.     addrTo.sin_port=htons(port);  
  173.       
  174.     return sendto(  sockTo, buf, len, 0,  
  175.         (struct sockaddr *)&addrTo, sizeof(struct sockaddr)  );  
  176. }  
  177.   
  178. bool MyConnect(SOCKET sockTo, char *addr,USHORT port)  
  179. {  
  180.       
  181.     int   Result;  
  182.       
  183.     //设置连接到的 套接字及地址结构  
  184.     SOCKADDR_IN   addrTo;  
  185.     addrTo.sin_addr.S_un.S_addr=(inet_addr(addr));  
  186.     addrTo.sin_family=AF_INET;  
  187.     addrTo.sin_port=htons(port);  
  188.       
  189.     //连接  
  190.     Result = connect(sockTo,(struct sockaddr *)&addrTo,sizeof(SOCKADDR_IN));  
  191.     if(SOCKET_ERROR == Result)  
  192.     {  
  193.         return false;  
  194.     }  
  195.     return true;  
  196. }  
  197.   
  198. int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port)  
  199. {  
  200.       
  201.     //设置发送数据到的 套接字及地址结构  
  202.     int addrlen;  
  203.     SOCKADDR_IN   addrFrom;  
  204.     addrFrom.sin_addr.S_un.S_addr=inet_addr(addr);  
  205.     addrFrom.sin_family=AF_INET;  
  206.     addrFrom.sin_port=htons(port);  
  207.     addrlen = sizeof(SOCKADDR_IN);  
  208.     return recvfrom( s, buf, len, 0, (SOCKADDR *)&addrFrom, &addrlen);  
  209. }  
  210.   
  211. int  ChName(char *fname,char *tname);//域名转化  
  212. bool SetDNSHead(char *name,char *buf)  
  213. {  
  214.     DnsHead *DnsH;  
  215.     DnsQuery *DnsQ;  
  216.     int NameLen;  
  217.     memset(buf,0,sizeof(DnsHead));  
  218.       
  219.     //设置头部  
  220.     DnsH = (DnsHead *)buf;  
  221.     DnsH->ID = (USHORT)1;  
  222.     DnsH->tag = htons(0x0100);  
  223.     DnsH->numQ = htons(1);  
  224.     DnsH->numA = 0;  
  225.       
  226.     DnsQ =(DnsQuery *) ( buf+ sizeof(DnsHead) );  
  227.     NameLen = ChName(name,(char *)DnsQ);  
  228.       
  229.     //设置查询信息  
  230.     DnsQ = (DnsQuery *)( (char *)DnsQ + NameLen );  
  231.     DnsQ->classes = htons(1);  
  232.     DnsQ->type = htons(1);  
  233.     return true;  
  234. }  
  235.   
  236. //显示错误信息  
  237. void displayErrWSA(char *str)  
  238. {  
  239.     printf("\n%s,err = %d\n",str,WSAGetLastError());  
  240.     getchar();  
  241. }  
  242.   
  243. //域名转化  
  244. int  ChName(char *fname,char *tname)  
  245. {  
  246.       
  247.     int j =0;  
  248.     int i =strlen(fname)-1;  
  249.     int k = i+1;  
  250.     tname[i+2] = 0;  
  251.     for (; i>=0;i--,k--)  
  252.     {  
  253.         if (fname[i] == '.')  
  254.         {  
  255.             tname[k] = j;  
  256.             j=0;  
  257.         }  
  258.         else  
  259.         {  
  260.             tname[k] = fname[i];  
  261.             j++;  
  262.         }  
  263.     }  
  264.     tname[k] = j;  
  265.     return strlen(tname)+1;  
  266. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值