c語言winsock 實現解簡域名解析(DNS. v 1.0)
c語言winsock 實現解簡域名解析(DNS. v 1.0)
分類: 個人作品 2010-04-06 22:19 414人閱讀 評論(2) 收藏 舉報
download
/**************************************
** 實現簡單的DNS 學習、測試之用
** VC6.0 winXP 編譯通過
** 20100406 v1.0
** from http://blog.csdn.net/jxfgh
************************************/
#include
#include
#include
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);
// UDP recvfrom
int MyRecvFrom(SOCKET s, char FAR * buf,int len);
//設定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;
//傳送DNS 請求
if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)
{
displayErrWSA("sendto err!");
continue;
}
//接收應答
if ( (Result =MyRecvFrom(sockTo,buf,1024) ) <= 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");
}
closesocket(sockTo);
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)
{
if (addr[0]'9') //addr 中不是IP 地址,域名解析
{
struct sockaddr_in addr_in;
HOSTENT *host = NULL;
host = gethostbyname(addr);//域名解析函式
if ( host->h_addr_list[0]!=NULL )
{
memcpy ( &addr_in.sin_addr.s_addr,
host->h_addr_list[0], host->h_length);
addr = inet_ntoa(addr_in.sin_addr);
}
}
//設定傳送資料到的 套接字及地址結構
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) );
}
//*********************************************/
/*********************** UDP recvform*/
int MyRecvFrom(SOCKET s, char FAR * buf,int len)
{
//設定傳送資料到的 套接字及地址結構
SOCKADDR_IN addrFrom;
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;
}
分類: 個人作品 2010-04-06 22:19 414人閱讀 評論(2) 收藏 舉報
download
/**************************************
** 實現簡單的DNS 學習、測試之用
** VC6.0 winXP 編譯通過
** 20100406 v1.0
** from http://blog.csdn.net/jxfgh
************************************/
#include
#include
#include
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);
// UDP recvfrom
int MyRecvFrom(SOCKET s, char FAR * buf,int len);
//設定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;
//傳送DNS 請求
if ( ( Result =MySendto(sockTo,buf,len,addr,53) ) <= 0)
{
displayErrWSA("sendto err!");
continue;
}
//接收應答
if ( (Result =MyRecvFrom(sockTo,buf,1024) ) <= 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");
}
closesocket(sockTo);
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)
{
if (addr[0]'9') //addr 中不是IP 地址,域名解析
{
struct sockaddr_in addr_in;
HOSTENT *host = NULL;
host = gethostbyname(addr);//域名解析函式
if ( host->h_addr_list[0]!=NULL )
{
memcpy ( &addr_in.sin_addr.s_addr,
host->h_addr_list[0], host->h_length);
addr = inet_ntoa(addr_in.sin_addr);
}
}
//設定傳送資料到的 套接字及地址結構
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) );
}
//*********************************************/
/*********************** UDP recvform*/
int MyRecvFrom(SOCKET s, char FAR * buf,int len)
{
//設定傳送資料到的 套接字及地址結構
SOCKADDR_IN addrFrom;
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;
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25897606/viewspace-704455/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- C語言程式碼例項助手 v1.0免費版C語言
- 掃雷--C語言實現C語言
- C語言實現DES加密C語言加密
- c語言實現階乘C語言
- C語言實現MD5加密,竟如此簡單!C語言加密
- C語言實現一個簡易的Hash table(7)C語言
- ping工具的C語言簡單實現 (ICMP echo)C語言
- C語言實現TCP通訊C語言TCP
- 高精度加法(C語言實現)C語言
- c語言實現this指標效果C語言指標
- C語言實現順序表C語言
- C語言實現連結串列C語言
- 漢諾塔(hanoi) C語言實現C語言
- RTree原始碼——C語言實現原始碼C語言
- C語言實現出入棧操作C語言
- C語言實現檔案加密C語言加密
- 利用棧實現佇列(C語言實現)佇列C語言
- 力扣566. 重塑矩陣-C語言實現-簡單題力扣矩陣C語言
- C語言實現的一個簡單的猜數小遊戲C語言遊戲
- C語言,實現數字譜到簡譜的轉換(二)C語言
- C語言實現推箱子游戲C語言
- C語言__LINE__實現原理C語言
- 排序演算法-C語言實現排序演算法C語言
- C語言實現桌面貪吃蛇C語言
- 高精度減法(C語言實現)C語言
- C語言實現繼承多型C語言繼承多型
- C語言實現萬年曆程式C語言
- C語言實現A*演算法薦C語言演算法
- c語言實現linux抓包C語言Linux
- C語言基礎-C簡介C語言
- C語言_簡單瞭解一下typedefC語言
- 《明解C語言》練習題4-2的實現C語言
- C語言異常與斷言介面的實現C語言
- 用JavaScript實現一門程式語言 2 (λanguage語言簡介)JavaScript
- 力扣896. 單調數列-C語言實現-簡單題力扣C語言
- 騰訊實習筆試題--簡單計算器程式的c語言實現筆試C語言
- 使用Go語言實現簡單MapReduce框架Go框架
- 簡易C語言文法分析C語言