目录
gethostname函数
gethostbyname函数
GetAdaptersInfo
GetIpStatistics
GetNetworkParams
GetTcpStatistics
GetUdpStatistics
WSAEnumProtocols
作用:获取本地计算机标准名
原型:int gethostname(char *name, int namelen);
参数:
name指向接收本地主机名的缓冲区的指针;
namelen表示name所指缓冲区的长度,以字节为单位。
返回值:
如果没有出现错误,那么函数返回零;否则,将返回SOCKET_ERROR。
调用:
#include
#include
int main()
{char hostName[128];if (gethostname(hostName, 128) == 0)std::cout << "hostName:" << hostName << std::endl;elsestd::cout << GetLastError() << std::endl;system("pause");return 0;
}
以上代码运行报错,
错误:LNK2019 无法解析的外部符号 _gethostname@8,该符号在函数 _main 中被引用
原因:缺少包含库
解决方案:添加下列代码,
#pragma comment(lib,"ws2_32.lib")
运行,获取本地计算机名失败,用GetLastError获取错误码
错误:得到10093,解释如下
WSANOTINITIALISED
10093 (0x276D)
Either the application has not called WSAStartup, or WSAStartup failed.
原因:未进行初始化,或者初始化失败。
解决方案:在获取本地计算机名称之前添加下列代码,
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
函数调用结束之后,需要添加下列代码释放资源
WSACleanup();
作用:从主机数据库中检索与主机名对应的主机信息。
原型:hostent * gethostbyname( const char *name);
参数:name 本地计算机名称
调用:
struct hostent * pHost;
pHost = gethostbyname(hostName);
其中hostent定义如下:
typedef struct hostent {char *h_name;//主机的正式名称char **h_aliases;//主机别名数组short h_addrtype;//返回地址类型short h_length;//ip地址长度char **h_addr_list;//ip地址} HOSTENT, *PHOSTENT, *LPHOSTENT;
获取本机所有IP地址:
for (int i = 0;pHost != NULL && pHost->h_addr_list[i] != NULL;i++)
{char *psz = inet_ntoa(*(in_addr *)pHost->h_addr_list[i]);std::cout << psz << std::endl;
}
作用:检索本地计算机的适配器信息。
原型:ULONG GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
参数:pAdapterInfo指向接收 IP_ADAPTER_INFO 结构链接列表的缓冲区的指针。
IP_ADAPTER_INFO定义如下:
typedef struct _IP_ADAPTER_INFO {struct _IP_ADAPTER_INFO *Next;//适配器列表中的下一个适配器的指针DWORD ComboIndex;char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//适配器名称的 ANSI 字符串char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//包含适配器说明的 ANSI 字符串UINT AddressLength;//适配器的硬件地址的长度(以字节为单位)BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//表示为 BYTE 数组的适配器的硬件地址DWORD Index;//适配器索引。当禁用并启用适配器或在其他情况下,适配器索引可能会更改UINT Type;//适配器类型UINT DhcpEnabled;//一个选项值,该值指定是否为此适配器启用动态主机配置协议 (DHCP) PIP_ADDR_STRING CurrentIpAddress;IP_ADDR_STRING IpAddressList;//与此适配器关联的 IPv4 地址列表IP_ADDR_STRING GatewayList;//此适配器的网关的 IPv4 地址IP_ADDR_STRING DhcpServer;//此适配器的 DHCP 服务器的 IPv4 地址,DhcpEnabled非零有效BOOL HaveWins;//此适配器是否使用 Windows Internet 名称服务 (WINS)IP_ADDR_STRING PrimaryWinsServer;//主 WINS 服务器的 IPv4 地址,HaveWins=true,有效IP_ADDR_STRING SecondaryWinsServer;//辅助 WINS 服务器的 IPv4 地址time_t LeaseObtained;//获取当前 DHCP 租约的时间,DhcpEnabled非零有效time_t LeaseExpires;//当前 DHCP 租约过期的时间,DhcpEnabled非零有效
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
SizePointer指向ULONG变量的指针,指定 pAdapterInfo 参数指向的缓冲区的大小。 如果此大小不足以保存适配器信息, GetAdaptersInfo 会用所需的大小填充此变量,并返回 ERROR_BUFFER_OVERFLOW的错误代码。
返回值:
如果函数成功,则返回值 ERROR_SUCCESS。
调用:
//头文件
#include
#include
#include
#pragma comment(lib, "IPHLPAPI.lib")
PIP_ADAPTER_INFO pAdapterInfo;PIP_ADAPTER_INFO pAdapter = NULL;ULONG pOutSize = 0;pOutSize = sizeof(IP_ADAPTER_INFO);pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));if (pAdapterInfo == NULL){return 1;}//第一次调用的时候pAdapterInfo设为NULL,这样pOutBufLen将指向获得实际所需缓冲区大小if (GetAdaptersInfo(NULL, &pOutSize) == ERROR_BUFFER_OVERFLOW){free(pAdapterInfo);pAdapterInfo = (IP_ADAPTER_INFO *)malloc(pOutSize);if (pAdapterInfo == NULL) {return 1;}}//第二次调用可以为pAdapterInfo分配实际所需大小if (GetAdaptersInfo(pAdapterInfo, &pOutSize) == NO_ERROR){pAdapter = pAdapterInfo;while (pAdapter){std::cout << "Ip:" << pAdapter->IpAddressList.IpAddress.String << std::endl;std::cout << "Mask:" << pAdapter->IpAddressList.IpMask.String << std::endl;std::cout << "Type:" << pAdapter->Type << std::endl;std::cout<Next;}}
pAdapter->Description中包含"PCI"的为物理网卡;pAdapter->Type是71的为无线网卡。
作用:检索当前计算机的 IP 统计信息。
原型:ULONG GetIpStatistics(PMIB_IPSTATS pStats);
参数:pStats指向MIB_IPSTATS结构的指针,该结构接收本地计算机的IP统计信息
MIB_IPSTATS定义如下:
typedef struct _MIB_IPSTATS{// dwForwarding指定IPv4或IPv6的每个协议转发状态,而不是接口的转发状态DWORD dwForwarding;DWORD dwDefaultTTL; //起始于特定计算机上的数据包的默认初始生存时间DWORD dwInReceives; //接收到的数据包数DWORD dwInHdrErrors; //接收到的有头部错误的数据包数DWORD dwInAddrErrors; //收到的具有地址错误的数据包数DWORD dwForwDatagrams; //转发的数据包数DWORD dwInUnknownProtos; //接收到的具有未知协议的数据包数DWORD dwInDiscards; //丢弃的接收数据包的数目DWORD dwInDelivers; //已传递的接收数据包的数目// IP请求传输的传出数据包数。此数目不包括转发的数据包DWORD dwOutRequests;DWORD dwRoutingDiscards; //丢弃的传出数据包的数目DWORD dwOutDiscards; //丢弃的传输数据包数//此计算机没有到目标IP地址的路由的数据包数,这些数据包被丢弃DWORD dwOutNoRoutes;//允许碎片数据包的所有部分到达的时间量。如果在这段时间内所有数据块都没有到达,数据包将被丢弃DWORD dwReasmTimeout;DWORD dwReasmReqds; //需要重新组装的数据包数DWORD dwReasmOks; //成功重新组合的数据包数DWORD dwReasmFails; //无法重新组合的数据包数DWORD dwFragOks; //成功分段的数据包数//由于IP头未指定分段而未分段的数据包数,这些数据包被丢弃DWORD dwFragFails;DWORD dwFragCreates; //创建的片段数DWORD dwNumIf; //接口的数目DWORD dwNumAddr; //与此计算机关联的IP地址数DWORD dwNumRoutes; //IP路由选项卡中的路由数} MIB_IPSTATS, *PMIB_IPSTATS;
返回值:
如果函数成功,则返回值NO_ERROR。
调用:
头文件:
#include
#pragma comment(lib,"IPHlpApi.lib")
MIB_IPSTATS *pStats;
pStats = (MIB_IPSTATS *)malloc(sizeof(MIB_IPSTATS));
if (pStats != NULL)
{if (GetIpStatistics(pStats) == NOERROR){std::cout << "yes" << std::endl;}
}if (pStats)free(pStats);
作用:获得本地计算机网络参数。
原型:DWORD GetNetworkParams(PFIXED_INFO pFixedInfo,PULONG pOutBufLen);
参数:
指向包含FIXED_INFO 结构的缓冲区的指针。
FIXED_INFO定义如下:
typedef struct {char HostName[MAX_HOSTNAME_LEN + 4];//本地计算机主机名char DomainName[MAX_DOMAIN_NAME_LEN + 4];//本地计算机的域PIP_ADDR_STRING CurrentDnsServer;//本地计算机DNS服务器IP_ADDR_STRING DnsServerList;//本地计算机使用的DNS服务器集UINT NodeType;//本地计算机的节点类型char ScopeId[MAX_SCOPE_ID_LEN + 4];//DHCP范围名称UINT EnableRouting;//是否在本地计算机上启用路由UINT EnableProxy;//本地计算机是否充当ARP代理UINT EnableDns;//是否启用DNS
} FIXED_INFO_W2KSP1, *PFIXED_INFO_W2KSP1;
返回值:
函数成功,则返回值 ERROR_SUCCESS
作用:获取本地计算机的TCP统计信息。
原型:ULONG GetTcpStatistics( PMIB_TCPSTATS pStats);
参数:指向接收本地计算机的 TCP 统计信息的MIB_TCPSTATS结构的指针。
MIB_TCPSTATS定义如下:
typedef struct _MIB_TCPSTATS{DWORD dwRtoAlgorithm; //正在使用的重传超时(RTO)算法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_TCPSTATS, *PMIB_TCPSTATS;
返回值:函数成功,则返回值NO_ERROR。
调用:
MIB_TCPSTATS *pStats;pStats = (MIB_TCPSTATS *)malloc(sizeof(MIB_TCPSTATS));if (pStats != NULL){if (GetTcpStatistics(pStats) == NOERROR){std::cout << "yes" << std::endl;}}if (pStats)free(pStats);
作用:获取本地计算机的UDP统计信息。
原型:ULONG GetUdpStatistics( PMIB_UDPSTATS pStats);
参数:指向接收本地计算机的 UDP 统计信息的MIB_UDPSTATS结构的指针。
MIB_UDPSTATS定义如下:
typedef struct _MIB_UDPSTATS{DWORD dwInDatagrams; // 接收的数据包数DWORD dwNoPorts; //由于指定的端口无效而丢弃的接收的数据包数//接收到的错误数据包的数目。此数字不包括dwNoPorts成员包含的值DWORD dwInErrors;DWORD dwOutDatagrams; // 传输的数据包数DWORD dwNumAddrs; // UDP侦听器表中的条目数} MIB_UDPSTATS,*PMIB_UDPSTATS;
返回值:
函数成功,则返回值NO_ERROR。
调用:
MIB_UDPSTATS *pStats;pStats = (MIB_UDPSTATS *)malloc(sizeof(MIB_UDPSTATS));if (pStats != NULL){if (GetUdpStatistics(pStats) == NOERROR){std::cout << "yes" << std::endl;}}if (pStats)free(pStats);
作用:获取可用网络传输协议的信息。
原型:
int WSAAPI WSAEnumProtocols( LPINT lpiProtocols, LPWSAPROTOCOL_INFOA lpProtocolBuffer, LPDWORD lpdwBufferLength);
参数:
lpiProtocols指向协议值数组;
lpProtocolBuffer指向用WSAPROTOCOL_INFOA结构填充的缓冲区的指针;
lpdwBufferLength在输入时,传递给WSAEnumProtocols的lpProtocolBuffer缓冲区中的字节数。
WSAPROTOCOL_INFOA定义如下:
typedef struct _WSAPROTOCOL_INFOA {DWORD dwServiceFlags1;//描述协议提供的服务的位掩码DWORD dwServiceFlags2;//为其他协议属性定义保留DWORD dwServiceFlags3;//为其他协议属性定义保留DWORD dwServiceFlags4;//为其他协议属性定义保留DWORD dwProviderFlags;//一组标志,提供有关 Winsock 目录中此协议的表示方式的信息GUID ProviderId;//由服务提供商供应商分配给提供程序的全局唯一标识符 (GUID)DWORD dwCatalogEntryId;//由每个 WSAPROTOCOL_INFO 结构WS2_32.DLL分配的唯一标识符WSAPROTOCOLCHAIN ProtocolChain;//与协议关联的 WSAPROTOCOLCHAIN 结构int iVersion;//协议版本标识符int iAddressFamily;//int iMaxSockAddr;//最大地址长度(以字节为单位)int iMinSockAddr;//最小地址长度(以字节为单位)int iSocketType;int iProtocol;//协议int iProtocolMaxOffset;int iNetworkByteOrder;int iSecurityScheme;DWORD dwMessageSize;//协议支持的最大消息大小(以字节为单位)DWORD dwProviderReserved;//保留供服务提供商使用CHAR szProtocol[WSAPROTOCOL_LEN + 1];//标识协议
} WSAPROTOCOL_INFOA, *LPWSAPROTOCOL_INFOA;
返回值:
未发生错误, WSAEnumProtocols 将返回要报告的协议数。 否则,返回SOCKET_ERROR值。
调用:
WSADATA wsaData;int nRet = WSAStartup(MAKEWORD(2, 2),&wsaData);if (nRet != 0){return 1;}DWORD buffLen = 0;if (WSAEnumProtocols(NULL, NULL, &buffLen) == SOCKET_ERROR){if (WSAGetLastError() != WSAENOBUFS){WSACleanup();return 1;}}LPWSAPROTOCOL_INFO pWSAInfo = (LPWSAPROTOCOL_INFO)malloc(buffLen);int iCntRet = WSAEnumProtocols(NULL, pWSAInfo, &buffLen);if (iCntRet == SOCKET_ERROR){WSACleanup();return 1;}for (int i = 0;i < iCntRet;i++){std::cout << pWSAInfo[i].szProtocol << std::endl;}if (pWSAInfo)free(pWSAInfo);WSACleanup();
注意:使用 DLL 之前,还需要调用 WSAStartup() 函数进行初始化,以指明 WinSock 规范的版本,调用之后,需要调用WSACleanup()进行清理。