目录
gethostname函数
作用:获取本地计算机标准名
原型:int gethostname(char *name, int namelen);
参数:
name指向接收本地主机名的缓冲区的指针;
namelen表示name所指缓冲区的长度,以字节为单位。
返回值:
如果没有出现错误,那么函数返回零;否则,将返回SOCKET_ERROR。
调用:
#include<iostream>
#include<Windows.h>
int main()
{
char hostName[128];
if (gethostname(hostName, 128) == 0)
std::cout << "hostName:" << hostName << std::endl;
else
std::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();
gethostbyname函数
作用:从主机数据库中检索与主机名对应的主机信息。
原型: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;
}
GetAdaptersInfo
作用:检索本地计算机的适配器信息。
原型: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 <winsock2.h>
#include <iphlpapi.h>
#include<iostream>
#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<<std::endl;
pAdapter = pAdapter->Next;
}
}
pAdapter->Description中包含"PCI"的为物理网卡;pAdapter->Type是71的为无线网卡。
GetIpStatistics
作用:检索当前计算机的 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 <Iphlpapi.h>
#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);
GetNetworkParams
作用:获得本地计算机网络参数。
原型: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
GetTcpStatistics
作用:获取本地计算机的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);
GetUdpStatistics
作用:获取本地计算机的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);
WSAEnumProtocols
作用:获取可用网络传输协议的信息。
原型:
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()进行清理。