c语言winsock 实现域名解析
作者:admin 日期:2010-05-16
c语言实现域名解析
- #include <stdio.h>
- #include <Winsock2.h>
- #include <windows.h>
- typedef struct _DNSHEAD{ //dns 头部
- USHORT ID;
- USHORT tag; // dns 标志(参数)
- USHORT numQ; // 问题数
- USHORT numA; // 答案数
- USHORT numA1; // 权威答案数
- USHORT numA2; // 附加答案数
- }DnsHead;
- typedef struct _DNSQUERY //dns 查询结构
- {
- // char name[64];
- // //查询的域名,这是一个大小在0到63之间的字符串;
- USHORT type;
- //查询类型,大约有20个不同的类型
- USHORT classes;
- //查询类,通常是A类既查询IP地址。
- }DnsQuery;
- #pragma comment(lib,"ws2_32.lib")
- // 初始化操作
- bool initWSA();
- //显示错误
- void displayErrWSA(char *str);
- //创建套接字
- SOCKET CreateSocket(int type);
- //UDP sendto
- int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port);
- //TCP 连接
- bool MyConnect(SOCKET s, char *addr,USHORT );
- // UDP recvfrom
- int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port);
- //设置DNS 头部
- bool SetDNSHead(char *name,char *buf);
- int main(int arg,char *are[])
- {
- int Result=0;
- char buf[1024]={0};
- char addr[16] = "61.187.72.8";// dns 服务器地址
- char *name = 0; //要查询的域名
- if ( !initWSA() )//初始化
- {
- displayErrWSA("initWSA err!");
- return 1;
- }
- //创建套接字
- SOCKET sockTo ;
- if ( (sockTo = CreateSocket(SOCK_DGRAM)) == 0)
- {
- displayErrWSA("CreatSocket err!");
- return 1;
- }
- while (1)
- {
- if (arg < 2)
- {
- char temp[1024]={0};
- printf("\n请输入要查询的域名:");
- scanf("%s",temp);
- if (temp[0] == 'q' ||temp[0] == 'Q')
- {
- break;
- }
- name = temp;
- }
- else
- {
- arg = 1;
- name = are[1];
- }
- //设置dns 头部
- SetDNSHead(name,buf);
- //发送出去的请求数据长度
- int len = sizeof(DnsHead)+sizeof(DnsQuery)+strlen(name)+2;
- // for (int i =0;i<50;i+=2)
- // {
- // printf("%02x",(UCHAR)buf[i]);
- // printf("%02x ",(UCHAR)buf[i+1]);
- // }
- //发送DNS 请求
- if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)
- {
- displayErrWSA("sendto err!");
- continue;
- }
- //接收应答
- if ( (Result =MyRecvFrom(sockTo,buf,1024,addr,53) ) <= 0)
- {
- displayErrWSA("recvfrom err!");
- continue;
- }
- //简单的取得返回的 IP 地址( 收到的最后4字节 )
- DnsHead *DnsH = (DnsHead *)buf;
- if (DnsH->numA == 0)
- {
- printf("无法解析 %s 的IP 地址。\n",name);
- continue;
- }
- char *getIP =(char *)buf +Result - 4;
- printf("%s 的IP地址为: ",name);
- for (int Result= 0 ;Result<4 ;Result++)
- {
- printf("%u.",(UCHAR )getIP[Result]);
- }
- printf("\n");
- }
- return 0;
- }
- // 初始化操作
- bool initWSA()
- {
- WORD wVersionRequested;
- WSADATA wsaData;
- int Result;
- wVersionRequested = MAKEWORD( 2, 2 );
- Result = WSAStartup( wVersionRequested, &wsaData );
- if(Result != 0 )
- {
- return false;
- }
- if( LOBYTE( wsaData.wVersion) != 2 ||
- HIBYTE(wsaData.wVersion)!= 2 )
- {
- WSACleanup();
- return false;
- }
- return true;
- }
- //*********************************************/
- /**************** 创建套接字 */
- SOCKET CreateSocket(int type)
- {
- SOCKET sock=socket(AF_INET,type,0);
- if (sock == INVALID_SOCKET )
- {
- return 0;
- }
- return sock;
- }
- //*********************************************/
- /***************** UDP sendto*/
- int MySendto(SOCKET sockTo, const char FAR * buf,int len,char *addr,USHORT port)
- {
- //设置发送数据到的 套接字及地址结构
- SOCKADDR_IN addrTo;
- addrTo.sin_addr.S_un.S_addr=inet_addr(addr);
- addrTo.sin_family=AF_INET;
- addrTo.sin_port=htons(port);
- return sendto( sockTo, buf, len, 0,
- (sockaddr*)&addrTo, sizeof(sockaddr) );
- }
- //*********************************************/
- /************************** TCP 连接*/
- bool MyConnect(SOCKET sockTo, char *addr,USHORT port)
- {
- int Result;
- //设置连接到的 套接字及地址结构
- SOCKADDR_IN addrTo;
- addrTo.sin_addr.S_un.S_addr=(inet_addr(addr));
- addrTo.sin_family=AF_INET;
- addrTo.sin_port=htons(port);
- //连接
- Result = connect(sockTo,(sockaddr *)&addrTo,sizeof(SOCKADDR_IN));
- if(SOCKET_ERROR == Result)
- {
- return false;
- }
- return true;
- }
- //*********************************************/
- /*********************** UDP recvform*/
- int MyRecvFrom(SOCKET s, char FAR * buf,int len,char *addr,USHORT port)
- {
- //设置发送数据到的 套接字及地址结构
- SOCKADDR_IN addrFrom;
- addrFrom.sin_addr.S_un.S_addr=inet_addr(addr);
- addrFrom.sin_family=AF_INET;
- addrFrom.sin_port=htons(port);
- int addrlen = sizeof(SOCKADDR_IN);
- return recvfrom( s, buf, len, 0, (SOCKADDR *)&addrFrom, &addrlen);
- }
- //*********************************************/
- /********************** 设置DNS 头部 */
- int ChName(char *fname,char *tname);//域名转化
- bool SetDNSHead(char *name,char *buf)
- {
- memset(buf,0,sizeof(DnsHead));
- //设置头部
- DnsHead *DnsH = (DnsHead *)buf;
- DnsH->ID = (USHORT)1;
- DnsH->tag = htons(0x0100);
- DnsH->numQ = htons(1);
- DnsH->numA = 0;
- DnsQuery *DnsQ =(DnsQuery *) ( buf+ sizeof(DnsHead) );
- int NameLen = ChName(name,(char *)DnsQ);
- //设置查询信息
- DnsQ = (DnsQuery *)( (char *)DnsQ + NameLen );
- DnsQ->classes = htons(1);
- DnsQ->type = htons(1);
- return true;
- }
- //显示错误信息
- void displayErrWSA(char *str)
- {
- printf("\n%s,err = %d\n",str,WSAGetLastError());
- getchar();
- }
- //域名转化
- int ChName(char *fname,char *tname)
- {
- int j =0;
- int i =strlen(fname)-1;
- tname[i+2] = 0;
- int k = i+1;
- for (; i>=0;i--,k--)
- {
- if (fname[i] == '.')
- {
- tname[k] = j;
- j=0;
- }
- else
- {
- tname[k] = fname[i];
- j++;
- }
- }
- tname[k] = j;
- return strlen(tname)+1;
- }
评论: 0 | 查看次数: 13169