C++获取网速

主要知识点: PMIB_IFTABLE结构体、MIB_IFROW结构体、GetIfTable函数

先上代码

#include <windows.h>
#include <Iphlpapi.h>
#include <cstdio>
#pragma comment(lib, "Iphlpapi.lib")

int main()
{
	PMIB_IFTABLE	m_pTable = NULL;
	DWORD	 m_dwAdapters = 0;
	ULONG	 uRetCode = GetIfTable(m_pTable, &m_dwAdapters, TRUE);
	if (uRetCode == ERROR_NOT_SUPPORTED)
	{
		return (-1);
	}

	if (uRetCode == ERROR_INSUFFICIENT_BUFFER)
	{
		m_pTable = (PMIB_IFTABLE)new BYTE[65535];										//假设端口数不超过65535个
	}

	DWORD	dwLastIn = 0;																					//上一秒钟的接收字节数
	DWORD	dwLastOut = 0;																					//上一秒钟的发送字节数
	DWORD	dwBandIn = 0;																					//下载速度
	DWORD	dwBandOut = 0;																		//上传速度

	while (1)
	{
		system("cls");
		GetIfTable(m_pTable, &m_dwAdapters, TRUE);
		
		DWORD	dwInOctets = 0;
		DWORD	dwOutOctets = 0;

		//将所有端口的流量进行统计
		for (UINT i = 0; i < m_pTable->dwNumEntries; i++)
		{
			MIB_IFROW	Row = m_pTable->table[i];
			dwInOctets += Row.dwInOctets;
			dwOutOctets += Row.dwOutOctets;
			//printf("dwSpeed:%u\n", Row.dwSpeed);
		}

		dwBandIn = dwInOctets - dwLastIn;														//下载速度
		dwBandOut = dwOutOctets - dwLastOut;											//上传速度
		if (dwLastIn <= 0)
		{
			dwBandIn = 0;
		}
		else
		{
			dwBandIn = dwBandIn / 1024.0;															//b转换成kb
		}

		if (dwLastOut <= 0)
		{
			dwBandOut = 0;
		}
		else
		{
			dwBandOut = dwBandOut / 1024.0;													//b转换成kb
		}

		dwLastIn = dwInOctets;
		dwLastOut = dwOutOctets;

		printf("收到字节: %u bytes\n", dwLastIn);
		printf("发送字节: %u bytes\n", dwLastOut);
		printf("下行速度: %u KB\n", dwBandIn);
		printf("上行速度: %u KB\n", dwBandOut);
		printf("--------------------------\n");
		Sleep(1000);																								//休眠一秒钟
	}

	delete[] m_pTable;
	return (0);
}

关键知识点

  1. MIB_IFROW结构体
    语法:
typedef struct _MIB_IFROW {
  WCHAR                   wszName[MAX_INTERFACE_NAME_LEN];
  IF_INDEX                dwIndex;
  IFTYPE                  dwType;
  DWORD                   dwMtu;
  DWORD                   dwSpeed;
  DWORD                   dwPhysAddrLen;
  UCHAR                   bPhysAddr[MAXLEN_PHYSADDR];
  DWORD                   dwAdminStatus;
  INTERNAL_IF_OPER_STATUS dwOperStatus;
  DWORD                   dwLastChange;
  DWORD                   dwInOctets;
  DWORD                   dwInUcastPkts;
  DWORD                   dwInNUcastPkts;
  DWORD                   dwInDiscards;
  DWORD                   dwInErrors;
  DWORD                   dwInUnknownProtos;
  DWORD                   dwOutOctets;
  DWORD                   dwOutUcastPkts;
  DWORD                   dwOutNUcastPkts;
  DWORD                   dwOutDiscards;
  DWORD                   dwOutErrors;
  DWORD                   dwOutQLen;
  DWORD                   dwDescrLen;
  UCHAR                   bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;

成员(只解释相关部分):
dwInOctets
类型:DWORD
通过此接口接收的数据的八进制数。

dwOutOctets
类型:DWORD
通过此接口发送的数据的八位字节数。

  1. PMIB_IFTABLE结构体

语法:

typedef struct _MIB_IFTABLE {
  DWORD     dwNumEntries;
  MIB_IFROW table[ANY_SIZE];
} MIB_IFTABLE, *PMIB_IFTABLE;

成员:
dwNumEntries
数组中的接口条目数。

table[ANY_SIZE]
包含接口条目 的MIB_IFROW 结构的数组。

  1. GetIfTable函数

结构:

IPHLPAPI_DLL_LINKAGE DWORD GetIfTable(
  [out]     PMIB_IFTABLE pIfTable,
  [in, out] PULONG       pdwSize,
  [in]      BOOL         bOrder
);

参数说明:
[out] pIfTable
指向以MIB_IFTABLE结构的形式接收接口表 的缓冲区的 指针。

[in, out] pdwSize
在输入时,指定 pIfTable 参数指向的缓冲区的大小(以字节为单位)。
在输出时,如果缓冲区不够大,无法容纳返回的接口表,则函数会将此参数设置为等于所需的缓冲区大小(以字节为单位)。

[in] bOrder
一个布尔值,指定是否应按接口索引按升序对返回的接口表进行排序。 如果此参数为 TRUE,则对表进行排序。

返回值:
如果函数成功,则返回值NO_ERROR。
如果函数失败,则返回值为以下错误代码之一。
返回代码 说明
ERROR_INSUFFICIENT_BUFFER:pIfTable 参数指向的缓冲区不够大。 所需大小在 pdwSize 参数指向的 DWORD 变量中返回。
ERROR_INVALID_PARAMETER:pdwSize 参数为 NULL,或者 GetIfTable 无法写入 pdwSize 参数指向的内存。
ERROR_NOT_SUPPORTED:本地系统上正在使用的操作系统不支持此函数。

其实就是说传入一个结构体和缓冲区大小值以及一个布尔值,如果你传入的缓冲区大小够大,它就会将所有接口的信息包括流量信息存储到第一个参数的结构体之中,这样你只要调用传回来的结构体就能获取相关信息了

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++获取网速可以通过以下步骤: 1. 使用Winsock库中的函数创建一个socket。 2. 连接到一个服务器,例如Google服务器。 3. 使用gettimeofday函数获取当前时间。 4. 发送一些数据到服务器。 5. 使用gettimeofday函数获取当前时间。 6. 计算发送数据所花费的时间并除以发送数据的大小,即可得到网速。 以下是一个简单的示例代码: ``` #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") int main() { WSADATA wsa; SOCKET s; struct sockaddr_in server; char *message, server_reply[2000]; int recv_size; struct timeval start, end; printf("\nInitializing Winsock..."); if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) { printf("Failed. Error Code : %d",WSAGetLastError()); return 1; } printf("Initialized.\n"); //Create a socket if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET) { printf("Could not create socket : %d" , WSAGetLastError()); } printf("Socket created.\n"); server.sin_addr.s_addr = inet_addr("173.194.222.113"); server.sin_family = AF_INET; server.sin_port = htons( 80 ); //Connect to remote server if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0) { puts("connect error"); return 1; } puts("Connected"); //Send some data message = "GET /index.html HTTP/1.1\r\n\r\n"; gettimeofday(&start, NULL); if( send(s , message , strlen(message) , 0) < 0) { puts("Send failed"); return 1; } puts("Data Sent\n"); //Receive a reply from the server if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR) { puts("recv failed"); } puts("Reply received\n"); //Add a NULL terminating character to make it a proper string before printing server_reply[recv_size] = '\0'; gettimeofday(&end, NULL); //Calculate the network speed double time_diff = (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0; double speed = recv_size / time_diff; printf("Network speed: %f bytes/sec\n", speed); closesocket(s); WSACleanup(); return 0; } ``` 该示例代码连接到Google服务器,并发送一个HTTP GET请求,然后计算发送数据所花费的时间并除以发送数据的大小,即可得到网速。请注意,此示例仅仅是一个简单的示例,实际情况可能更为复杂,需要根据具体需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值