获得拨号网络传输速度

ZDNet软件频道 时间: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)
//参数:每秒发送,每秒接收,总发送,总接收
...
}


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

 


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134