网络编程学习笔记(2)--本机网络信息编程

目录

gethostname函数

gethostbyname函数

GetAdaptersInfo

GetIpStatistics 

GetNetworkParams

GetTcpStatistics

GetUdpStatistics

WSAEnumProtocols


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()进行清理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值