以下是博主對網(wǎng)絡(luò)編程實(shí)踐的一些理解與體會,個人理解比較多,如有出錯歡迎不吝賜教。
獲取給定域名的遠(yuǎn)端IP地址 實(shí)驗(yàn)環(huán)境整體格式visual studio 2022
廢話不多說先直接上代碼,代碼分析在后頭
#include#include#include#include#pragma comment(lib, "ws2_32.lib")//引入靜態(tài)鏈接庫,裝載DDL
#pragma warning(disable: 4996) //禁用第4996號錯誤,很關(guān)鍵
using namespace std;
int main()
{// 聲明和初始化變量
WSADATA wsaData;
int iResult;
DWORD dwError;
int i = 0;
struct hostent* remotehostname;
char hostname[50]; //用于存儲輸入的域名
struct in_addr addr;
// 初始化 Winsock
//MAKEWORD(2, 2)表示網(wǎng)絡(luò)庫版本為2.2,環(huán)境的網(wǎng)絡(luò)庫信息存在wsaData結(jié)構(gòu)體中。
//如果函數(shù)調(diào)用成功,則返回0
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
//判斷初始化是否成功
if (iResult != 0)
{cout<<"WSAStartup failed: "<dwError = WSAGetLastError();//獲取上次錯誤操作的錯誤號
if (dwError != 0)
{ if (dwError == WSAHOST_NOT_FOUND) //WSAHOST_NOT_FOUND=11001L 指示關(guān)鍵字沒有找到
{ cout<<"Host not found"< cout<<"No data record found"< cout<<"Function failed with error: %ld"<// 輸出地址類型和地址長度
cout<<"Official name: "<h_name<h_aliases[i])
cout<< "Alternate name "<< i + 1<< ": "<< remotehostname->h_aliases[i++]<< endl;
printf("Address type: ");
switch (remotehostname->h_addrtype)//判斷遠(yuǎn)端ip的地址類型
{ case AF_INET: //如果是ipv4類型的
cout<< "ipv4(AF_INET)"<< endl;
break;
case AF_NETBIOS:
cout<< "AF_NETBIOS"<< endl;
break;
default:
cout<< remotehostname->h_addrtype<< endl;
break;
}
cout<< "Address length: "<h_length<h_addrtype == AF_INET)
{ while (remotehostname->h_addr_list[i])
{ //兩種輸出點(diǎn)分十進(jìn)制ip地址的方式
addr.s_addr = *(u_long*)remotehostname->h_addr_list[i++];
cout<< "IP Address "<< i<< ": "<< inet_ntoa(addr)<h_addr_list[i++];
//printf("IP Address: %u.%u.%u.%u\n", cp[0], cp[1], cp[2], cp[3]);
}
}
else if (remotehostname->h_addrtype == AF_NETBIOS)
{ cout<< "NETBIOS address was returned"<< endl;
}
}
iResult = WSACleanup();//終止Windows Sockets DLL 的使用,釋放資源
if (iResult != 0)
{cout<< "WSACleanup failed: "<< iResult<< endl;
return -1;
}
return 0;
}
運(yùn)行結(jié)果展示代碼調(diào)試存在的問題#pragma warning(disable: 4996)
禁用第4996號錯誤。將SDL檢查設(shè)置為否(C/C++ ->常規(guī) ->SDL檢查->否->應(yīng)用)
SDL檢查在VS中默認(rèn)是打開狀態(tài),用于強(qiáng)制編譯器警告。
hostname = argv[1];
remotehostname = gethostbyname(hostname);
如果使用這種這種方式獲取域名,會發(fā)現(xiàn)運(yùn)行后無域名輸入,直接退出了程序。
因?yàn)榫幾g器默認(rèn)argv[1]輸入的值為空值(NULL),因此判定為沒有域名輸入,退出函數(shù)。
解決方法:
在命令參數(shù)中設(shè)置想要輸入的域名(屬性->調(diào)試->設(shè)置命令參數(shù)->確定)
- 對WSAStartup()函數(shù)的理解
(1) 函數(shù)原型為:int WSAAPI WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
(2) 該函數(shù)是一切的開始,任何網(wǎng)絡(luò)編程項(xiàng)目首先需要做的事情就是調(diào)用該函數(shù)對Winsock進(jìn)行初始化。
- 對gethostbyname()函數(shù)的理解
(1) 函數(shù)原型:struct hostent *gethostbyname(const char *hostname);
(2) 函數(shù)參數(shù):給定的遠(yuǎn)端域名。注意域名形式是const char類型,不是字符串string類型,如果類型不對需要進(jìn)行轉(zhuǎn)換。
(3) 函數(shù)返回值:一個hostent類型結(jié)構(gòu)體,用于存放關(guān)于域名解析的各種信息。
(4) 該函數(shù)是最常用的函數(shù)之一,搭配gethostname()函數(shù)使用可以提高程序的可移植性。
- 對hostent結(jié)構(gòu)體的理解
結(jié)構(gòu)體內(nèi)容
struct hostent
{char *h name;
char **h aliases;
int h addrtype;
int h length;
char **h addr list;
};
(1) *h_name:用于存放正式主機(jī)名,一維字符串?dāng)?shù)組,輸出時直接輸出即可。
(2) **h_aliases:用于存放遠(yuǎn)端域名的別名,由于一個域名的別名可能有很多,因此用二維字符串?dāng)?shù)組來存放。輸出的時候按行掃描即可。
(3) h_addrtype:用于存放主機(jī)IP地址類型,ipv4,ipv6等。
(4) h_length:用于存放地址字節(jié)長度,對于IPV4是四字節(jié)(32位)
(5) **h_addr_list:用于存放主機(jī)域名對應(yīng)的IP地址,由于域名可能有多個,因此對應(yīng)的IP地址也可能有多個,用二維字符串?dāng)?shù)組存放。
- 對IP地址輸出的理解
存儲在**h_addr_list中的IP地址是不能直接輸出的,需要轉(zhuǎn)換為我們所熟知的點(diǎn)分十進(jìn)制表示方式才可以進(jìn)行輸出。
轉(zhuǎn)換方法一般有兩種:(注:以下代碼粘貼到上述源代碼中即可運(yùn)行)
(1) 使用系統(tǒng)提供的in_addr結(jié)構(gòu)體
addr.s_addr = *(u_long*)remotehostname->h_addr_list[i++];
cout<< "IP Address "<< i<< ": "<< inet_ntoa(addr)<
首先將字符顯式強(qiáng)轉(zhuǎn)為u_long類型,存儲到結(jié)構(gòu)體的s_addr變量中,然后調(diào)用inet_ntoa()函數(shù)將結(jié)構(gòu)體進(jìn)行轉(zhuǎn)換,輸出轉(zhuǎn)換后的點(diǎn)分十進(jìn)制IP地址。
(2) 使用BYTE類型進(jìn)行強(qiáng)轉(zhuǎn)
BYTE* cp = (BYTE*)&*(u_long*)remotehostname->h_addr_list[i++];
printf("IP Address: %u.%u.%u.%u\n", cp[0], cp[1], cp[2], cp[3]);
首先任然是將字符顯式強(qiáng)轉(zhuǎn)為u_long類型,不過之后再次對其進(jìn)行強(qiáng)轉(zhuǎn),轉(zhuǎn)換為BYTE*類型,最后按位置輸出字符串中的數(shù)值。
總結(jié)你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧