【Windows网络编程】一.主机相关网络信息编程

需要包含的头文件:

#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 侦听器表中的条目数.
    	*/
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shad0w-2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值