一.域名解析
DNS域名解析,實現了主機域名地址到IP地址轉換的過程。、
比如我們訪問百度 www.baidu.com
主機向域名服務器請求服務,請求域名服務器解析www.baidu.com的IP地址;域名服務器接收到該請求後,在本地數據庫中查找或者向其他域名服務器請求服務,以找到www.baidu.com對應的IP地址;域名服務器向主機返回解析出的IP地址;主機使用該IP地址與服務器建立連接,獲取數據。解析過程如下圖所示:
概念瞭解了,詳細的原理以後在深入研究,目前要考慮的是我們的編程中怎麼應用。
二.Linux中編程應用
我們主要使用以下幾個函數:
1.gethostbyname()//利用這個函數完成域名到IP地址的轉換。
函數名 |
struct hostent *gethostbyname(const char *name); |
所需頭文件 |
#include <netdb.h> |
功能 |
用域名或主機名獲取主機的完整信息(IP地址等) |
傳入參數 |
傳入值是域名或者主機名,例如"www.baidu.com"等等 |
返回值 |
成功時返回hostent結構體,失敗返回NULL |
2.gethostbyaddr()
函數名 |
struct hostent *gethostbyaddr(const char * addr, int len, int type); |
||||||
所需頭文件 |
#include <sys/socket.h> |
||||||
功能 |
通過IP獲取主機的完整信息 |
||||||
傳入參數 |
|
||||||
返回值 |
成功時返回hostent結構體,失敗返回NULL |
以上兩個函數返回的都是一個結構體hostent ,這個結構體中肯定是包含主機的完整信息,那麼這個結構體長什麼模樣呢?
struct hostent
{
char *h_name; //主機的規範名
char ** h_aliases; //主機的別名
short h_addrtype; //IP地址的類型(ipv4,ipv6)
short h_length; //主機地址的長度
char ** h_addr_list; //主機的ip地址(網絡字節序格式)
};
#define h_addr h_addr_list[0]
注:h_addr_list其實是一個指針數組,指向主機多個網絡地址
當我們用完之後,使用void endhostent(void) 函數將hostent結構體進行釋放
利用 void herror(cost char *s); const char *hsterror(int err);來打印出錯信息
其他的函數我們之後在進行分析,看下實例是具體怎麼應用到編程中的吧。
例:
#include "net.h"
int main(int argc,char *argv[])
{
struct sockaddr_in sin;
int fd;
int ret;
struct hostent *hs = NULL; //定義hostent 結構體
char buf[BUFSIZ] = "hello world";
if(argc < 2){
printf("please input %s + ip 192.168.x.xxx\n",argv[0]);
exit(1);
}
//將輸入的域名進行轉化
if ((hs = gethostbyname (argv[1])) == NULL) {
herror ("gethostbyname error"); //用這個打印報錯信息
exit (1);
}
//socket
if((fd = socket(AF_INET,SOCK_STREAM, 0) )< 0){
perror ("socket");
exit (1);
}
//connect
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons (SERV_PORT);
sin.sin_addr.s_addr = *(uint32_t *) hs->h_addr; //轉化成IP
endhostent (); //釋放結構體
hs = NULL; //防止野指針
if( connect (fd, (struct sockaddr *)&sin,sizeof(sin)) < 0){
perror ("connect ");
exit (1);
}
printf("connect success\n");
//write
if((ret =write (fd, buf, strlen(buf))) < 0){
perror("write");
exit(1);
}
//close
close (fd);
exit(0);
}