需要包含的头文件:
#include <iostream>
#include <WinSock2.h>
#parama comment(lib,"ws2_32.lib")
#include <iphlpapi.h>
#parama comment(lib,"Iphlpapi.lib")
这里注意,如果还要包含Windows.h的话,一定要写在这几个后面.
API:
-
WSAStartup:
WSAStart函数通过启动Winsock DLL的使用。
- 函数原型:
int WSAAPI WSAStartup( [in] WORD wVersionRequested, [out] LPWSADATA lpWSAData );
参数:
-
wVersionRequested:调用方可以使用的最高版本的Windows套接字规范,高序字节指定次要版本号,低序字节指定主版本号。
-
lpWSAData:
指向WSADATA数据结构的指针
- 函数原型:
-
WSACleanup:
WSACleanup函数终止使用Winsock2 DLL。
- 函数原型:
int WSAAPI WSACleanup();
- 函数原型:
-
gethostname:
gethostname函数检索本地计算机的标准主机名
-
函数原型:
int WSAAPI gethostname( [out] char *name, [in] int namelen );
-
参数:
name:接受本地主机名的缓冲区的指针。
namelen:name参数指向的缓冲区的长度(以字节为单位)。
-
返回值:如果函数成功,则返回0
-
-
gethostbyname:
gethostbyname函数从主机数据库中检索与主机名对应的主机信息。
-
函数原型:
hostent *WSAAPI gethostbyname( const char *name );
-
参数:name(主机名)
-
返回值:如果函数成功,则返回执行上述hostent的结构的指针。否则,它将返回一个null指针。
-
hostent结构:
函数使用hostent结构来存储有关给定主机的信息,例如主机名,IPv4地址等,应用程序绝不应该尝试修改次结构。
typedef struct hostent { char *h_name; char **h_aliases; short h_addrtype; short h_length; char **h_addr_list; } HOSTENT, *PHOSTENT, *LPHOSTENT;
- h_name:主机的官方名称。
- h_aliases:以NULL结尾的备用名称数组。
- h_addrtype:要返回的地址类型。
- h_length:每个地址的长度(以字节为单位)。
- h_addr_list:主机的以NULL结尾的地址列表,注意这里地址按照网络字节顺序返回
-
-
inet_ntoa:
inet_ntoa函数将IPv4网络地址转换为标准点分十进制格式的ASCII字符串。
-
getaddrinfo:
getaddrinfo函数提供从主机名到地址的,与协议无关的转换。
-
函数原型:
INT WSAAPI getaddrinfo( [in, optional] PCSTR pNodeName, [in, optional] PCSTR pServiceName, [in, optional] const ADDRINFOA *pHints, [out] PADDRINFOA *ppResult );
-
参数:
- pNodeName:指向以NULL结尾的ANSI字符串的指针,该字符串包含主机名称或者数字主机地址字符串(对于Internet协议,数字主机地址字符串应该是点十进制IPv4或者IPv6)。
- pServiceName:指向以NULL结尾的ANSI字符串的指针,该字符串包含表示为字符串的服务名称或者端口号。
- pHints:指向addrinfo结构的指针,该结构提供有关调用方支持的套接字类型的提示。
- ppResult:只想包含有关主机的相应信息的一个或多个addrinfo结构的链接列表的指针。
-
addrinfo结构体:
addrinfo函数使用addrinfo接哦古来保存主机地址信息。
typedef struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo *ai_next; } ADDRINFOA, *PADDRINFOA;
- ai_flags:匹配所有IP地址
- ai_family:地址系列
- ai_socktype:套接字类型
- ai_protocol:协议类型
- ai_addrlen:ai_addr成员指向的缓冲区的长度
- ai_canonname:主机的规范名称
- ai_addr:指向aockaddr结构的指针
- ai_next:指向链接列表中的下一个结构的指针
-
返回值:成功返回0,失败将返回非零Windows套接字错误代码。
-
-
GetAdaptersInfo:
GetAdapterInfo函数检索本地计算机的适配器信息。
- 函数原型:
IPHLPAPI_DLL_LINKAGE ULONG GetAdaptersInfo( [out] PIP_ADAPTER_INFO AdapterInfo, [in, out] PULONG SizePointer );
- 参数:
- AdapterInfo:指向接受IP_ADAPTER_INFO结构的链表缓冲区的指针
- SizePointer:只想ULONG变量的指针,该变量指定pAdapterInfo指向的缓冲区大小。
- 返回值:如果函数成功,返回ERROR_SUCCESS(NO_ERROR)
- IP_ADAPTER_INFO 结构:参见IP_ADAPTER_INFO结构
- 函数原型:
-
GetNetworkParams:
GetNetworkParams函数检索本地计算机的网络参数。
- 函数原型:
IPHLPAPI_DLL_LINKAGE DWORD GetNetworkParams( [out] PFIXED_INFO pFixedInfo, [in] PULONG pOutBufLen );
- 参数:
- pFixedInfo:指向包含FIXED_INFO结构的缓冲区的指针。
- pOutbufLen:指向ULONG变量的指针,该变量指定FIXED_INFO结构的大小。
- 返回值:如果函数成功,返回ERROR_SUCCESS
- 函数原型:
与主机相关网络信息编程实战
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>
#include <WS2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include <iphlpapi.h>
#pragma comment(lib,"Iphlpapi.lib")
#include <Windows.h>
int main() {
//Winsock Dll初始化
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA WsaData;
WSAStartup(wVersionRequested, &WsaData);
//获取主机名
char szHostName[MAX_PATH] = { 0 };
if (gethostname(szHostName, MAX_PATH) == 0) {
std::cout << "主机名;" << szHostName << std::endl;
}
//获取主机IP地址
hostent* pHost = gethostbyname(szHostName);
for (int i = 0; pHost != NULL && pHost->h_addr_list[i] != NULL; i++) {
char* szHostIP = inet_ntoa(*(in_addr*)pHost->h_addr_list[i]);
std::cout << "主机IP:" << szHostIP << std::endl;
}
//通过网址获取IP地址
char* hostname = (char*)"www.vultop.com";
ADDRINFOA hInts;
ADDRINFOA* result;
ADDRINFOA* node;
in_addr addr;
memset(&hInts, 0, sizeof(ADDRINFOA));
hInts.ai_socktype = SOCK_STREAM;
hInts.ai_family = AF_INET;
hInts.ai_flags = AI_PASSIVE;
hInts.ai_protocol = NULL;
if (getaddrinfo(hostname, NULL, &hInts, &result) == 0) {
for (node = result; node != NULL; node = node->ai_next) {
addr.s_addr = ((sockaddr_in*)(node->ai_addr))->sin_addr.s_addr;
std::cout << "网站地址:" << hostname << "::" << inet_ntoa(addr) << std::endl;
}
}
freeaddrinfo(result);
//获取网卡(适配器)相关信息
PIP_ADAPTER_INFO AdapterInfo = NULL;
ULONG ulLength = sizeof(PIP_ADAPTER_INFO);
//第一次传入的时候需要判断是否需要开辟空间
ULONG uRet = GetAdaptersInfo(NULL, &ulLength);
if (uRet = ERROR_BUFFER_OVERFLOW) {
AdapterInfo = (IP_ADAPTER_INFO*)malloc(ulLength);
}
uRet = GetAdaptersInfo(AdapterInfo, &ulLength);
if (uRet = NO_ERROR) {
while (AdapterInfo) {
std::cout << "网卡名称:" << AdapterInfo->AdapterName << std::endl;
std::cout << "网卡描述:" << AdapterInfo->Description << std::endl;
std::cout << "MAC地址:" << std::endl;
for (int i = 0; i < AdapterInfo->AddressLength; i++) {
printf("%02X", AdapterInfo->Address[i]);
if (i < 5) {
printf("-");
}
}
std::cout << std::endl;
std::cout << "适配器类型:" << AdapterInfo->Type << std::endl;
std::cout << "ip地址:" << AdapterInfo->IpAddressList.IpAddress.String << std::endl;
std::cout << "子网掩码:" << AdapterInfo->IpAddressList.IpMask.String << std::endl;
AdapterInfo = AdapterInfo->Next;
std::cout << std::endl;
}
}
//检索本地计算机的网络参数
DWORD uLength = 0;
FIXED_INFO* pFixedInfo = NULL;
DWORD dwRet = GetNetworkParams(NULL, &uLength);
if (dwRet == ERROR_BUFFER_OVERFLOW) {
pFixedInfo = (FIXED_INFO*)new BYTE[uLength];
}
GetNetworkParams(pFixedInfo, &uLength);
char szText[500] = "本地计算机的DNS地址:\n";
IP_ADDR_STRING* pCurrentDnsServer = &pFixedInfo->DnsServerList;
while (pCurrentDnsServer != NULL) {
char szTemp[100] = "";
sprintf(szTemp, "%s\n", pCurrentDnsServer->IpAddress.String);
strcat(szText, szTemp);
pCurrentDnsServer = pCurrentDnsServer->Next;
}
std::cout << szText << std::endl;
delete[] pFixedInfo;
//终止Winsock DLL的使用
WSACleanup();
system("pause");
return 0;
}
- IP协议信息统计:
//IP协议信息统计 //MIB_IPSTATS结构存储特定计算机上运行的 IP 协议的相关信息。 MIB_IPSTATS IPStats; GetIpStatistics(&IPStats); /* DWORD dwForwarding; IPV4或者IPV6,每个协议的转发状态 DWORD dwDefaultTTL; 起始于某个特定计算机的数据包的默认初始生存时间 DWORD dwInReceives; 接收到的数据包数 DWORD dwInHdrErrors; 有头部错误的数据包数 DWORD dwInAddrErrors; 有地址错误的数据包数 DWORD dwForwDatagrams; 转发的数据包数 DWORD dwInUnknownProtos; 未知协议的数据包数 DWORD dwInDiscards; 丢弃的数据包 DWORD dwInDelivers; 已经传递的接收数据包的个数 DWORD dwOutRequests; IP请求传出的传出数据包 DWORD dwRoutingDiscards; 丢弃的传出数据包的数量 DWORD dwOutDiscards; 丢弃的传输数据包的数量 DWORD dwOutNoRoutes;此计算机没有路由到目标 IP 地址的数据报数。 这些数据报被丢弃。 DWORD dwReasmTimeout;允许碎片数据报的所有部分到达的时间量。 如果所有部分在此时间内未到达,则丢弃数据报。 DWORD dwReasmReqds;需要重新程序集的数据报数。 DWORD dwReasmOks;已成功重新汇编的数据报数。 DWORD dwReasmFails;无法重新组合的数据报数。 DWORD dwFragOks;已成功分段的数据报数。 DWORD dwFragFails;未分段的数据报数,因为 IP 标头未指定任何碎片。 这些数据报将被丢弃。 DWORD dwFragCreates;创建的片段数。 DWORD dwNumIf;接口数。 DWORD dwNumAddr;与此计算机关联的 IP 地址数。 DWORD dwNumRoutes;IP 路由表中的路由数。 */ MIB_TCPSTATS TCPStats; GetTcpStatistics(&TCPStats); /* 正在使用的 RTO) 算法重新传输超时 union { DWORD dwRtoAlgorithm; TCP_RTO_ALGORITHM RtoAlgorithm; }; DWORD dwRtoMin;最小 RTO 值(以毫秒为单位)。 DWORD dwRtoMax;最大 RTO 值(以毫秒为单位)。 DWORD dwMaxConn;最大连接数。 如果此成员为 -1,则最大连接数是可变的。 DWORD dwActiveOpens;活动打开的数目。 在活动的打开中,客户端正在启动与服务器的连接。 DWORD dwPassiveOpens;被动打开的数目。 在被动打开中,服务器正在侦听来自客户端的连接请求。 DWORD dwAttemptFails;失败的连接尝试的数目。 DWORD dwEstabResets;重置的已建立连接数。 DWORD dwCurrEstab;当前建立的连接数。 DWORD dwInSegs;收到的段数。 DWORD dwOutSegs;传输的段数。 此数字不包括重新传输的段。 DWORD dwRetransSegs;重新传输的段数。 DWORD dwInErrs;收到的错误数。 DWORD dwOutRsts;使用重置标志集传输的段数。 DWORD dwNumConns;系统中当前存在的连接数。 此总数包括除侦听连接以外的所有状态中的连接。 */ MIB_UDPSTATS UDPStats; GetUdpStatistics(&UDPStats); /* DWORD dwInDatagrams;收到的数据报数。 DWORD dwNoPorts;由于指定的端口无效而丢弃的数据报数。 DWORD dwInErrors;收到的错误数据报数。 此数字不包括 dwNoPorts 成员包含的值。 DWORD dwOutDatagrams;传输的数据报数。 DWORD dwNumAddrs;UDP 侦听器表中的条目数. */