#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <windows.h>
#pragma warning( disable : 4996)
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
/*
* WSADATA结构被用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息。
* 这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。
*/
WSADATA wsaData;
int iResult;
DWORD dwError; /*每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位*/
int i = 0;
struct hostent *remoteHost; /*域名*/
char *host_name; /*主机名*/
struct in_addr addr; /*ip*/
char **pAlias;
//---------------------注意下面的话------------------------
// 开始卡在这里卡了好久,这里是检查输入的参数,原来网上的版本是 2 意思是你还得输入一个参数,
//就像 get_ip.exe wwwbaidu.com 这里就是两个参数,前面的加上后面的域名
// Validate the parameters
if (argc != 1) {
printf("usage: GetHostIP hostname\n");
return 1;
}
// 此处应添加的程序如下
// 1. 当初始化winsocket
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);/* & 取地址*/
// 2. 检查该socket是否初始化成功,即该socket是否等于0;如果初始化不成功,应当给出错误报警,并结束程序。
if (iResult != 0) {
printf("初始化失败!\n");
return 1;
}
/结束///
//host_name = argv[1];
cout << "输入要查询的域名: ";
char host[20];//定义一个数组存放输入的域名,并把值传递给 host_name
cin >> host;
host_name = host;
//host_name = "www.baidu.com";
printf("Calling gethostbyname with %s\n", host_name);
// 此处应添加的程序如下
// 1. 利用函数gethostbyname(),获取给定主机名的指针。
remoteHost = gethostbyname(host_name);
// 2. 应当熟悉该结构指针的结构
// 其中该函数申明如下:struct hostent* gethostbyname(const char *name)
// 此处应添加的程序如下
// 1. 如果上面函数返回的主机结构指针为空(NULL),则做如下处理:
// a. 利用函数 int WSAGetLastError ( void ) 检查当前是否发生网络错误,
// b. 返回的发生的错误类型并作相应的处理,比如,若没有找到主机的错误(此时该函数返回WSAHOST_NOT_FOUND)
if (remoteHost == NULL) {
dwError = WSAGetLastError();
if (dwError != 0) {
if (dwError == WSAHOST_NOT_FOUND) {
printf("Host not found\n");
return 1;
}
else if (dwError == WSANO_DATA) {
printf("No data record found\n");
return 1;
}
else {
printf("Function failed with error: %ld\n", dwError);
return 1;
}
}
}
else {
printf("Function returned:\n");
printf("\tOfficial name: %s\n", remoteHost->h_name);
for (pAlias = remoteHost->h_aliases; *pAlias != 0; pAlias++) {
printf("\tAlternate name #%d: %s\n", ++i, *pAlias);
}
printf("\tAddress type: ");
switch (remoteHost->h_addrtype) {
case AF_INET:
printf("AF_INET\n");
break;
case AF_NETBIOS:
printf("AF_NETBIOS\n");
break;
default:
printf(" %d\n", remoteHost->h_addrtype);
break;
}
printf("\tAddress length: %d\n", remoteHost->h_length);
i = 0;
if (remoteHost->h_addrtype == AF_INET)
{
while (remoteHost->h_addr_list[i] != 0) {
addr.s_addr = *(u_long *)remoteHost->h_addr_list[i++];
printf("\tIP Address #%d: %s\n", i, inet_ntoa(addr));
}
}
else if (remoteHost->h_addrtype == AF_NETBIOS)
{
printf("NETBIOS address was returned\n");
}
}
system("pause"); /*防止窗体关闭函数*/
return 0;
}
照着书敲的代码愣是改了半天,VS大法好啊,环境就调了半天
把遇到的问题一起上传上来吧
编译器报错C4996
报错的情况通常为:
1 错误 8 error C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use_CRT_SECURE_NO_WARNINGS. See online help for details.
此时,通常有3种方式可以解决:
(1)使用VS提供的 编译器选择性提供warning功能 link: http://msdn.microsoft.com/en-us/library/2c8f766e.aspx例:使用 #pragma warning( disable : 4996) 即可消除。
(2) 设置预处理选项:a. Project properties->Configuration Properties->C/C++->Preprocessor->Preprocessor Definitionsb. 点击按钮 (...)c. 输入:_CRT_SECURE_NO_WARNINGS。 注:使用 "\n" 相隔
(3)在引用库文件开头写一个宏定义
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
来自 <https://zhidao.baidu.com/question/434204650624968924.html>
//---------------------注意下面的话------------------------
// 开始卡在这里卡了好久,这里是检查输入的参数,原来网上的版本是 2 意思是你还得输入一个参数,
//就像 get_ip.exe wwwbaidu.com 这里就是两个参数,前面的加上后面的域名
// Validate the parameters
if (argc != 1) {
printf("usage: GetHostIP hostname\n");
return 1;
}
好久没碰C++,绕不过这个坎,劝大家好好学学吧—》
这个是网上的版本,大家参考吧
// GetHostIP.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char **argv)
{
//-----------------------------------------
// Declare and initialize variables
/*
* WSADATA结构被用来储存调用AfxSocketInit全局函数返回的Windows Sockets初始化信息。
* 这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。
*/
WSADATA wsaData;
int iResult;
DWORD dwError; /*每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位*/
int i = 0;
struct hostent *remoteHost; /*域名*/
char *host_name; /*主机名*/
struct in_addr addr; /*ip*/
char **pAlias;
// Validate the parameters
if (argc != 2) {
printf("usage: GetHostIP hostname\n");
return 1;
}
// 此处应添加的程序如下
// 1. 当初始化winsocket
iResult = WSAStartup(MAKEWORD(2,2),&wsaData);/* & 取地址*/
// 2. 检查该socket是否初始化成功,即该socket是否等于0;如果初始化不成功,应当给出错误报警,并结束程序。
if(iResult!=0){
printf("初始化失败!\n");
return 1;
}
/结束///
host_name = argv[1];
printf("Calling gethostbyname with %s\n", host_name);
// 此处应添加的程序如下
// 1. 利用函数gethostbyname(),获取给定主机名的指针。
remoteHost = gethostbyname(host_name);
// 2. 应当熟悉该结构指针的结构
// 其中该函数申明如下:struct hostent* gethostbyname(const char *name)
// 此处应添加的程序如下
// 1. 如果上面函数返回的主机结构指针为空(NULL),则做如下处理:
// a. 利用函数 int WSAGetLastError ( void ) 检查当前是否发生网络错误,
// b. 返回的发生的错误类型并作相应的处理,比如,若没有找到主机的错误(此时该函数返回WSAHOST_NOT_FOUND)
if(remoteHost == NULL){
//printf("gethostbynameError:%d",WSAGetLastError());
return 1;
}else{
// 2. 如果返回的主机指针不为空,则做如下处理:
// a. 打印出如下参数:主机名和IP地址,若该主机对应于多个ip地址,应当分别列出。
printf("主机名:%s\n",remoteHost->h_name);
for(i=0;;i++){
if(remoteHost->h_addr_list[i]!=0)
{
/*从缓存中把 p 拷贝到addr中
*同时addr.S_un.Saddr
* in_addr ipAddr;
* ipAddr.S_un.S_addr = inet_addr("127.0.0.1");
* 就是把字符串形式的ip地址转化为0xXXXXXXXX形式的地址格式。
*/
addr.s_addr = *(u_long*)remoteHost->h_addr_list[i];
printf("ip #%d:%s\n",i,inet_ntoa(addr)); /* inet_ntoa() 函数将网络地址转成二进制的数字相关函数:inet_aton, inet_ntoa */
}
/*
for(i=0;;i++){
char *p = remoteHost->h_addr_list[i];
if(p==NULL) break;
/*从缓存中把 p 拷贝到addr中
*同时addr.S_un.Saddr
* in_addr ipAddr;
* ipAddr.S_un.S_addr = inet_addr("127.0.0.1");
* 就是把字符串形式的ip地址转化为0xXXXXXXXX形式的地址格式。
*
memcpy(&addr.S_un.S_addr,p,remoteHost->h_length);
printf("ip地址为:%s\n",inet_ntoa(addr));
*/
}
}
// 此处应添加的程序如下
// 程序完成后应当适当测试,需要进行的测试如下:
// 1. 测试主机结构指针获取失败
// 2. 测试包含多个IP地址的主机
// 3. 你能想到的任何可能出现的异常情况
/结束///
system("pause"); /*防止窗体关闭函数*/
return 0;
}