获得拨号网络传输速度

开发者在线 Builder.com.cn 更新时间:2001-08-14作者:闻怡洋 来源:

本文关键词: C C++ 拨号网络


转载自VCHelp

这段时间很多朋友都写邮件问我如何得到拨号上网时的网络速度,下面的代码是在我的软件Dial Monitor中节选出来的相关程序片。

H文件:rasSpdM.h

#ifndef __RASSPDMON_H_
#define __RASSPDMON_H_

void InitSpeedMonitor(void);
void ClearSpeedMonitor(void);
void GetRASSpeed(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT);
////参数:每秒发送,每秒接收,总发送,总接受


#endif



CPP文件rasSpdM.cpp

#include "stdafx.h"
#include "rasSpdM.h"


#include

#define TOTALBYTES 4096
#define BYTEINCREMENT 1024

LPSTR lpNameStrings=NULL;
LPSTR *lpNamesArray=NULL;
BOOL glo_fFromDynReg=TRUE;

/*
在9x下通过dyn_data注册表得到速度
*/
DWORD GetTotalRecv(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStatsStatData", &hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up AdapterTotalBytesRecvd",NULL,&dwType,(BYTE*)&dwValue, &dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
DWORD GetTotalXmit(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStatsStatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up AdapterTotalBytesXmit",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
DWORD GetPerSecondRecv(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStatsStatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up AdapterBytesRecvd",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}
DWORD GetPerSecondXmit(void)
{
HKEY hKey;
DWORD dwValue=(DWORD)-1;
if(0==RegOpenKey(HKEY_DYN_DATA,"PerfStatsStatData",&hKey))
{
DWORD dwType,dwLen=sizeof(DWORD);
RegQueryValueEx(hKey,"Dial-Up AdapterBytesXmit",NULL,&dwType,(BYTE*)&dwValue,&dwLen);
RegCloseKey(hKey);
}
return dwValue;
}

/****************************************************
在NT下通过per Data得到
*****************************************************/

PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData )
{
return( (PPERF_OBJECT_TYPE)((PBYTE)PerfData +
PerfData->HeaderLength) );
}

PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj )
{
return( (PPERF_OBJECT_TYPE)((PBYTE)PerfObj +
PerfObj->TotalByteLength) );
}

PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj )
{
return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfObj +
PerfObj->DefinitionLength) );
}

PPERF_INSTANCE_DEFINITION NextInstance(
PPERF_INSTANCE_DEFINITION PerfInst )
{
PPERF_COUNTER_BLOCK PerfCntrBlk;

PerfCntrBlk = (PPERF_COUNTER_BLOCK)((PBYTE)PerfInst +
PerfInst->ByteLength);

return( (PPERF_INSTANCE_DEFINITION)((PBYTE)PerfCntrBlk +
PerfCntrBlk->ByteLength) );
}

PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj )
{
return( (PPERF_COUNTER_DEFINITION) ((PBYTE)PerfObj +
PerfObj->HeaderLength) );
}

PPERF_COUNTER_DEFINITION NextCounter(
PPERF_COUNTER_DEFINITION PerfCntr )
{
return( (PPERF_COUNTER_DEFINITION)((PBYTE)PerfCntr +
PerfCntr->ByteLength) );
}

/*****************************************************
* *
* Load the counter and object names from the registry to the *
* global variable lpNamesArray. *
* *
*******************************************************/

void GetNameStrings( )
{
HKEY hKeyPerflib; // handle to registry key
HKEY hKeyPerflib009; // handle to registry key
DWORD dwMaxValueLen; // maximum size of key values
DWORD dwBuffer; // bytes to allocate for buffers
DWORD dwBufferSize; // size of dwBuffer
LPSTR lpCurrentString; // pointer for enumerating data strings
DWORD dwCounter; // current counter index

// Get the number of Counter items.

RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SOFTWAREMicrosoftWindows NTCurrentVersionPerflib",
0,
KEY_READ,
&hKeyPerflib);

dwBufferSize = sizeof(dwBuffer);

RegQueryValueEx( hKeyPerflib,
"Last Counter",
NULL,
NULL,
(LPBYTE) &dwBuffer,
&dwBufferSize );

RegCloseKey( hKeyPerflib );

// Allocate memory for the names array.

lpNamesArray = (char**)malloc( (dwBuffer+1) * sizeof(LPSTR) );
// Open key containing counter and object names.

RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SOFTWAREMicrosoftWindows NTCurrentVersionPerflib9",
0,
KEY_READ,
&hKeyPerflib009);

// Get the size of the largest value in the key (Counter or Help).

RegQueryInfoKey( hKeyPerflib009,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
&dwMaxValueLen,
NULL,
NULL);

// Allocate memory for the counter and object names.

dwBuffer = dwMaxValueLen + 1;

lpNameStrings = (char*)malloc( dwBuffer * sizeof(CHAR) );

// Read Counter value.

RegQueryValueEx( hKeyPerflib009,
"Counter",
NULL,
NULL,
(BYTE*)lpNameStrings, &dwBuffer );

// Load names into an array, by index.

int iC=1;
for( lpCurrentString = lpNameStrings; *lpCurrentString;
lpCurrentString += (lstrlen(lpCurrentString)+1) )
{
dwCounter = atol( lpCurrentString );
lpCurrentString += (lstrlen(lpCurrentString)+1);

//printf("%d length=%d data=%s ",iC++,dwCounter,lpCurrentString);
lpNamesArray[dwCounter] = (LPSTR) lpCurrentString;
}
}

/****************************************************
得到下RAS速度
*****************************************************/
void GetRASSpeedOn9X(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
{// under 9x
*pTPS=GetPerSecondXmit();
*pRPS=GetPerSecondRecv();
*pTT=GetTotalXmit();
*pRT=GetTotalRecv();
}

void GetRASSpeedOnNT(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
{// under NT
////参数:每秒发送,每秒接收,总发送,总接受
PPERF_DATA_BLOCK PerfData = NULL;
PPERF_OBJECT_TYPE PerfObj;
PPERF_INSTANCE_DEFINITION PerfInst;
PPERF_COUNTER_DEFINITION PerfCntr, CurCntr;
PPERF_COUNTER_BLOCK PtrToCntr;
DWORD BufferSize = TOTALBYTES;
DWORD i, j, k;

// Get the name strings through the registry.

//return;
// Allocate the buffer for the performance data.

PerfData = (PPERF_DATA_BLOCK) malloc( BufferSize );

while( RegQueryValueEx( HKEY_PERFORMANCE_DATA,
"906",//"Global",
NULL,
NULL,
(LPBYTE) PerfData,
&BufferSize ) == ERROR_MORE_DATA )
{
// Get a buffer that is big enough.

BufferSize += BYTEINCREMENT;
PerfData = (PPERF_DATA_BLOCK) realloc( PerfData, BufferSize );
}

// Get the first object type.

PerfObj = FirstObject( PerfData );

// Process all objects.

//printf("object total=%d ",PerfData->NumObjectTypes);
//getchar();
for( i=0; i < PerfData->NumObjectTypes; i++ )
{
// Display the object by index and name.

// Get the first counter.

PerfCntr = FirstCounter( PerfObj );

if( PerfObj->NumInstances > 0 )
{
//exit(0);
}
else
{
// Get the counter block.
PtrToCntr = (PPERF_COUNTER_BLOCK) ((PBYTE)PerfObj +
PerfObj->DefinitionLength );

// Retrieve all counters.

for( j=0; j < PerfObj->NumCounters; j++ )
{
// Display the counter by index and name.


if(strcmp("Bytes Transmitted/Sec",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pTPS=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
if(strcmp("Bytes Received/Sec",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pRPS=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
if(strcmp("Bytes Transmitted",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pTT=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
if(strcmp("Bytes Received",lpNamesArray[PerfCntr->CounterNameTitleIndex])==0)
{
*pRT=*((DWORD*)((BYTE*)PtrToCntr+PerfCntr->CounterOffset));
}
// Get the next counter.
PerfCntr = NextCounter( PerfCntr );
}
}

// Get the next object type.
PerfObj = NextObject( PerfObj );
}
}

void GetRASSpeed(DWORD* pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
{////参数:每秒发送,每秒接收,总发送,总接受
if(glo_fFromDynReg==FALSE)
{
GetRASSpeedOnNT(pTPS,pRPS, pTT,pRT);
}
else
{
GetRASSpeedOn9X(pTPS,pRPS, pTT,pRT);
}
}

void InitSpeedMonitor(void)
{
DWORD dwVersion = GetVersion();
// Get major and minor version numbers of Windows
DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
// Get build numbers for Windows NT or Win32s
if (dwVersion>>31 ==0) // Windows NT
{
glo_fFromDynReg=FALSE;
GetNameStrings( );
}
else // Windows 95 - 98
glo_fFromDynReg=TRUE;
}
void ClearSpeedMonitor(void)
{
if(lpNameStrings)
free(lpNameStrings);
if(lpNamesArray)
free(lpNamesArray);
}



使用方法:

#include "rasSpdM.h"
BOOL CYourApp::InitInstance()
{
//初始化RAS速度访问
InitSpeedMonitor();

...
}


#include "rasSpdM.h"
void CYourWnd::OnTimer(UINT nIDEvent)
{
DWORD dwR,dwS,dwPSR,dwPSS;//总接收,总发送,每秒接收,每秒发送
GetRASSpeed(&dwPSS,&dwPSR,&dwS,&dwR);//pTPS,DWORD* pRPS,DWORD* pTT,DWORD* pRT)
//参数:每秒发送,每秒接收,总发送,总接收
...
}


但我在使用过程中发现每秒发送,每秒接收这两个结果并不十分正确,所以我是采用总数相减的方式来计算每秒速度的。
 

 

用户评论

  • 用户名
  • 评论内容