Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.08.2013, 14:23   #1
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию Как определить текущую скорость Ethernet сети (реальную)

Вот как это делает AIDA64:

Т.е. она в реальном времени показывает,сколько сейчас мегабайт\сек передается данных через сетевую карту.
Я пробовал 2 функции: GET_ADAPTERS_INFO и GET_ADAPTER_ADRESSES, первая выводит туфту в значениях DWORD dwInUcastPkts и DWORD dwInNUcastPkts структуры MIB_IFROW:

Вторая апишка использует структуру IP_ADAPTER_ADRESSES, параметры TransmitLinkSpeed и RecieveLinkSpeed недоступны на ОС ниже Висты.
calypso вне форума Ответить с цитированием
Старый 16.08.2013, 15:01   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,358
По умолчанию

Наверно надо смотреть на dwInOctets и dwOutOctets и замерять время и вычислять насколько изменилось между двумя измерениями.
И кстати, не путайте мегабиты и мегабайты.
waleri вне форума Ответить с цитированием
Старый 22.09.2015, 21:00   #3
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Снова актуально. В инете есть исходник где данная штука реализована с помощью WMI и двух классов: NetworkAdapter и NetworkMonitor.
Получается что если я буду этот огород городить на Embarcadero C++ ,то мне придется делать код на основе CoInitializeEx и вся эта бадяга?
Может что попроще и покороче есть?
Ещё хочу сделать счетчик трафика, сколько принято и сколько отправлено.
Как реализовано в AIDA64 так и не понял, мониторил через API Monitor V2 , но ничего так и не смог найти.
calypso вне форума Ответить с цитированием
Старый 22.09.2015, 22:33   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,783
По умолчанию

Цитата:
Как реализовано в AIDA64 так и не понял
Ну вам же объяснили - замеряет вх и исх несколько раз и делит на время между замерами.
p51x вне форума Ответить с цитированием
Старый 22.09.2015, 23:34   #5
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Вряд ли, отображение скорости в реальном времени идет с дискретом меньше 1 секунды. Если всё это как вы предлагаете замутить в цикл, то будет загрузка CPU 100% и жуткие тормоза.
В Windows есть уже готовый инструментарий WMI Performance Counters.
Просто с использованием WMI получается очень сложный и кривой код
calypso вне форума Ответить с цитированием
Старый 23.09.2015, 07:06   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,358
По умолчанию

Цитата:
Сообщение от calypso Посмотреть сообщение
то будет загрузка CPU 100% и жуткие тормоза.
Ничего подобного.
waleri вне форума Ответить с цитированием
Старый 23.09.2015, 19:18   #7
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Хорошо, попробуем разделить задачу на 2 части. Сначала нужно подсчитать количество переданных\принятых байт в реальном времени.
Можно ли это сделать чистым API без всякой галиматьи вроде WMI и OLE-объектов?

Если использовать WMI, то без этого кода не обойтись походу:
Код:
HRESULT hres;

	// Step 1: --------------------------------------------------
	// Initialize COM. ------------------------------------------

	hres =  CoInitializeEx(0, COINIT_MULTITHREADED);
	if (FAILED(hres))
	{
		ShowMessage ("Failed to initialize COM library. Error code = 0x"+String(hres));
//		return 1;                  // Program has failed.
	}

	// Step 2: --------------------------------------------------
	// Set general COM security levels --------------------------
	// Note: If you are using Windows 2000, you need to specify -
	// the default authentication credentials for a user by using
	// a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
	// parameter of CoInitializeSecurity ------------------------

	hres =  CoInitializeSecurity(
		NULL,
		-1,                          // COM authentication
        NULL,                        // Authentication services
		NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
		RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
		NULL,                        // Authentication info
		EOAC_NONE,                   // Additional capabilities
        NULL                         // Reserved
		);

	if (FAILED(hres))
	{
		ShowMessage ("Failed to initialize security. Error code = 0x"+String(hres));
		CoUninitialize();
   //		return 1;                    // Program has failed.
	}

    // Step 3: ---------------------------------------------------
	// Obtain the initial locator to WMI -------------------------

	IWbemLocator *pLoc = NULL;

	hres = CoCreateInstance(
        CLSID_WbemLocator,
		0,
		CLSCTX_INPROC_SERVER,
		IID_IWbemLocator, (LPVOID *) &pLoc);

	if (FAILED(hres))
    {
		ShowMessage( "Failed to create IWbemLocator object. Err code = 0x"+String(hres));
		CoUninitialize();
 //		return 1;                 // Program has failed.
	}

    // Step 4: -----------------------------------------------------
	// Connect to WMI through the IWbemLocator::ConnectServer method

	IWbemServices *pSvc = NULL;

	// Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
	// to make IWbemServices calls.
	hres = pLoc->ConnectServer(
		 BSTR(L"ROOT\\CIMV2"), // Object path of WMI namespace
		 NULL,                    // User name. NULL = current user
		 NULL,                    // User password. NULL = current
		 0,                       // Locale. NULL indicates current
		 NULL,                    // Security flags.
		 0,                       // Authority (e.g. Kerberos)
		 0,                       // Context object
		 &pSvc                    // pointer to IWbemServices proxy
		 );

	if (FAILED(hres))
	{
		ShowMessage("Could not connect. Error code = 0x"+String(hres));
		pLoc->Release();
		CoUninitialize();
//		return 1;                // Program has failed.
    }

	ShowMessage("Connected to ROOT\\CIMV2 WMI namespace");


	// Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
	   pSvc,                        // Indicates the proxy to set
	   RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
	   RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
       NULL,                        // Server principal name
	   RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
       RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
	   NULL,                        // client identity
	   EOAC_NONE                    // proxy capabilities
	);

	if (FAILED(hres))
    {
		ShowMessage("Could not set proxy blanket. Error code = 0x"+String(hres));
		pSvc->Release();
		pLoc->Release();
		CoUninitialize();
  //      return 1;               // Program has failed.
	}

Последний раз редактировалось Stilet; 31.10.2015 в 07:45.
calypso вне форума Ответить с цитированием
Старый 23.09.2015, 19:26   #8
calypso
Форумчанин
 
Регистрация: 02.12.2012
Сообщений: 250
По умолчанию

Код:
	// Step 6: --------------------------------------------------
	// Use the IWbemServices pointer to make requests of WMI ----

	// For example, get the name of the operating system
	IEnumWbemClassObject* pEnumerator = NULL;
	hres = pSvc->ExecQuery(
		BSTR("WQL"),
		BSTR("SELECT * FROM Win32_OperatingSystem"),
		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
		NULL,
		&pEnumerator);

	if (FAILED(hres))
    {
		ShowMessage("Query for operating system name failed. Error code = 0x"+String(hres));
		pSvc->Release();
		pLoc->Release();
        CoUninitialize();
 //		return 1;               // Program has failed.
    }

	// Step 7: -------------------------------------------------
	// Get the data from the query in step 6 -------------------

	IWbemClassObject *pclsObj;
	ULONG uReturn = 0;

	while (pEnumerator)
	{
		HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
			&pclsObj, &uReturn);

		if(0 == uReturn)
		{
			break;
		}

		VARIANT vtProp;

		// Get the value of the Name property
		hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
		ShowMessage(" OS Name : " +String(vtProp.bstrVal));
		VariantClear(&vtProp);
	}

	// Cleanup
	// ========

	pSvc->Release();
	pLoc->Release();
	pEnumerator->Release();
        pclsObj->Release();       // здесь выдает exception
	CoUninitialize();
CoInitializeEx(0, COINIT_MULTITHREADED); с параметром MULTITHREADED всегда выдает ошибку. Там ещё я так понял нужно будет городить синхронизацию потоков с помощью мьютексов. Это слишком сложный способ
calypso вне форума Ответить с цитированием
Старый 23.09.2015, 19:33   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,358
По умолчанию

Цитата:
Сообщение от calypso Посмотреть сообщение
Можно ли это сделать чистым API без всякой галиматьи вроде WMI и OLE-объектов?
Да, можно. Смотрите dwInOctets и dwOutOctets в MIB_IFROW структуре.
waleri вне форума Ответить с цитированием
Старый 23.09.2015, 19:36   #10
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,358
По умолчанию

Цитата:
Сообщение от calypso Посмотреть сообщение
Там ещё я так понял нужно будет городить синхронизацию потоков с помощью мьютексов.
Нет, не нужно никакой синхронизации.
Кстати, а почему вы решили, что нужен COINIT_MULTITHREADED режим?
waleri вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как узнать скорость передачи данных (при копировании файлов) по сети calypso Работа с сетью в Delphi 0 02.12.2012 19:56
Сканирование документов по сети / Scan over Ethernet mixael Работа с сетью в Delphi 0 08.10.2010 11:03
Как определить текущую строку StringGrid Veiron Общие вопросы Delphi 2 24.09.2009 03:03
Определить текущую ячейку на листе НикНик Microsoft Office Excel 5 18.08.2008 09:40
Как определить IP-адресс компьютера в локальной сети? SalasAndriy C/C++ Сетевое программирование 2 29.11.2007 02:09