所用函数
- gethostname()
- getaddrinfo( )
1.查询本机的主机名称及IP地址,并从键盘输入某网站的域名解析其IP地址。
gethostname()
该函数用来查询本地计算机主机名字。
函数原型
int gethostname(char *name, int namelen)
函数参数
Name:指向用于存放主机名字的缓冲区,就是一字符数组。
Namelen:是缓冲区的大小,也就是字符数组name的大小。
返回值
函数调用成功则返回0。函数调用失败,则返回SOCKET_ERROR,进一步的出错信息可调用WSAGetLastError()获取。
hostent结构包含对应给定主机名的IP地址等信息,其定义如下:
struct hostent
{
char *h_name; //主机的规范名
char **h_aliases; //主机的别名
int h_addrtype; //主机ip地址的类型(AF_INET)
int h_length; //主机ip地址的长度(4)
char **h_addr_list; //主机ip地址列表(网络字节序)
};
其中,字符指针h_name指向主机的正规名字;
指向字符数组的指针h_aliases指向的是 一个以空指针结尾的可选主机名队列;
h_addrtype保存主机地址的类型,对于Windows Sockets来说,其值总是AF_INET;
h_legnth 是每个地址的长度(字节数),对应于类型AF_INET来说,这个域的值为4;
指针h_addr_list 指向的是一个以空指针结尾的主机地址的列表,列表中的地址是以网络字节顺序排列的。
int main()
{
struct hostent* hptr;
char** pptr;
char hostname[256];
//初始化WinSock DLL
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2); //生成版本号2.2
if (WSAStartup(wVersionRequested, &wsaData) != 0)return 0;
if (gethostname(hostname, sizeof(hostname)))
{
cout << "gethostname calling error" << endl;
WSACleanup();return 0;
}
cout << "主机名为:" << hostname << endl;
if ((hptr = gethostbyname(hostname)) == NULL)
{
cout << "名字解析失败" << endl;
WSACleanup();
return 0;
}
/***输出IP地址***/
pptr = hptr->h_addr_list;
cout << "本机IP地址:" << endl;
while (*pptr != NULL)
{
cout << inet_ntoa(*(struct in_addr*)(*pptr)) << endl;
pptr++;
}
cout << "输入要解析的域名:" << endl;
cin >> hostname;
if ((hptr = gethostbyname(hostname)) == NULL)
{
cout << "名字解析失败" << endl;
WSACleanup();
return 0;
}
/***输出IP地址***/
pptr = hptr->h_addr_list;
cout << "主机IP地址:" << endl;
while (*pptr != NULL)
{
cout << inet_ntoa(*(struct in_addr*)(*pptr)) << endl;
pptr++;
}
WSACleanup();
return 0;
}
2.查询本机的所有IPv6地址
getaddrinfo( )
函数原型:int getaddrinfo(const char *hostname,const char *service,const struct addrinfo *hints,struct addrinfo **result)
函数参数:
const char *hostname, //一个主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)
const char *service, //服务名可以是十进制的端口号,NULL
const struct addrinfo *hints,//可以是一个空指针,也可以是一个指向某个addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。
struct addrinfo **result //返回一个指向addrinfo结构体链表的指针
);
int get_ipv6()
{
struct addrinfo hint;
struct sockaddr_in6* sinp6;
struct addrinfo* ailist, * aip;
const char* port = "1"; //端口号
int ilRc;
char hostname[255] = { 0 }; //主机名
hint.ai_family = AF_INET6; //hint 的限定设置
hint.ai_socktype = SOCK_STREAM; //这里可是设置 socket type 比如 SOCK_DGRAM
hint.ai_flags = AI_PASSIVE; // flags 的标志很多。常用的有AI_CANONNAME;
hint.ai_protocol = 0; //设置协议 一般为0,默认
hint.ai_addrlen = 0; //下面不可以设置,为0,或者为NULL
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
gethostname(hostname, sizeof(hostname));
ilRc = getaddrinfo(hostname, port, &hint, &ailist); //通过主机名获得地址信息
if (ilRc < 0)
{
char str_error[100];
strcpy(str_error, (char*)gai_strerror(errno));
printf("str_error = %s", str_error);
return 0;
}
if (ailist == NULL)
{
printf("sorry not find the IP address,please try again \n");
}
for (aip = ailist; aip != NULL; aip = aip->ai_next) //显示获取的信息
{
aip->ai_family = AF_INET6;
sinp6 = (struct sockaddr_in6*)aip->ai_addr;
int i;
printf("ipv6 addr = ");
for (i = 0; i < 16; i++)
{
if (((i - 1) % 2) && (i > 0))
{
printf(":");
}
printf("%02x", sinp6->sin6_addr.u.Byte[i]);
}
printf(" \n");
printf(" \n");
}
return -1;
}