Консультация № 183980
07.09.2011, 10:20
54.66 руб.
0 35 1
Здравствуйте, уважаемые!

Подскажите функцию (или несколько функций, если одной обойтись нельзя) WinAPI, которая бы отображала количество сетевых подключений к серверу на данный момент.

Обсуждение

Неизвестный
07.09.2011, 11:21
общий
Адресаты:
Я сам NetWatch пользуюсь для работы с shares а так же в целях мониторинга подключаемых к компьютеру пользователей. Могу выложить уже собранную версию.
давно
Мастер-Эксперт
425
4118
07.09.2011, 11:29
общий
Цитата: 181465
Могу выложить уже собранную версию.

Выложите, если не трудно. Посмотрю... Дело в том, что мне нужны не только подключения, которые заходят на сервер за файлами, а ещё и подключающиеся к нескольким сервера БД, которые на этом же сервере.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 11:41
общий
Адресаты:
Хмм.. про базы данных не уверен. У меня на машине нету баз данных. Но можно посмотреть исходники, которые я уже выложил, если программа заработает и в случае соединения с базой данных (если это TCP/IP, то, думаю, заработает)
Выкладываю сам exe-файл.
Прикрепленные файлы:
aa743f92137a6a811b7249d00ace0efa.zip
давно
Мастер-Эксперт
425
4118
07.09.2011, 12:20
общий
Похоже это не то, что нужно. Утилита показывает коннекты к расшареным ресурсам. И если к ресурсам никто не коннектится, то, получается, и нет никаких коннектов, а это неправда.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 12:23
общий
Ну, жаль. Наверно, тут надо смотреть, какими протоколами какие СУБД пользуются.

Товарищи администраторы, удалите мой ответ!
давно
Мастер-Эксперт
425
4118
07.09.2011, 12:32
общий
У операционки должны быть какие-то функции для учёта коннектов, иначе в XP не стояло бы ограничение на 10 подключений.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 12:44
общий
Адресаты:
Это ограничение стоит где? Если у терминала, то это рулится терминалом. Если у шары - то как раз через API, который используется в NetWatch. Если у базы данных, то это функционал СУБД и, опять же, протоколов/API, через которые эти СУБД работают. Если TCP/IP - то это дело менеджмента сокетов. Есть ещё NetBIOS, про него не скажу...
давно
Мастер-Эксперт
425
4118
07.09.2011, 12:53
общий
Цитата: 181465
Это ограничение стоит где?

Оно стоит у самой ОС. Вне зависимости от того, какие ресурсы я беру с компьютера - это может быть как файл, так и работа с серверной БД - больше 10 подключений из сети одновременно XP не даст сделать.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 12:58
общий
Адресаты:
Стоит у самой ОС где?
Просто вроде так быть не должно, потому что не бывает просто соединений. Они обязательно конкретные соединения, через конкретные протоколы. Можно ограничить те же TCP/IP до 10 штук, но NetBIOS разрешит хоть 100 человек за раз. При этом та же MSSQL уже нет.
давно
Мастер-Эксперт
425
4118
07.09.2011, 13:09
общий
07.09.2011, 13:12
Цитата: 181465
Стоит у самой ОС где?

Если говорить про XP - в драйвере tcpip.sys. А вот где это дело прописывается у серваков - увы, не знаю.

NetBIOS стоит у винды поверх транспортного протокола, а вовсе не параллельно ему. Таким образом достаточно ограничить соединения по TCP и всё что лежит выше его будет ограничено автоматически.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 13:15
общий
Ага, т.е. судя по имени драйвера, это TCP/IP. И так как это драйвер, то (ногами не пинать!) у него должны быть или конфирурационные файлы, либо ветки реестра. Или - клинический вариант - 10-ка прошита в коде железно
Тогда надо смотреть документацию по этому драйверу и читать cfg-файлы/реестр на тему нужных ключей. (такой способ может сработать, в отличие от обратного, т.е. установки/настройки драйвера)
Ну, или, да, м.б. есть API, которое читает-пишет конфигурацию самостоятельно.
давно
Посетитель
7438
7205
07.09.2011, 14:04
общий
Адресаты:
А если посмотреть в сторону функции NetSessionEnum?
Например, вот программка, показывающая локальных пользователей, пользователей, подключенных по сети (интересующий Вас случай), а также открытые по сети файлы(пайпы):
[code h=207]#include <windows.h>
#include <lm.h>
#include <stdio.h>

#pragma hdrstop

#pragma comment( lib, "netapi32.lib" )

#define MAXLEN 256

SESSION_INFO_502 *buf, *cur;
WKSTA_USER_INFO_1 *bufw, *curw;
FILE_INFO_3 *buff,*curf;

DWORD read, total, resumeh, rc, i;

//-----------------------------------------------------------
void PrintError( DWORD err )
{
char msgbuf[4096];

FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
msgbuf, sizeof( msgbuf ), NULL );

printf( "Error %d: %s\n", err, msgbuf );
}

//-------------------------------------------------------
void PrintLocalUsers(LPWSTR server)
{
resumeh = 0;
do
{
bufw = NULL;
rc = NetWkstaUserEnum( (LPTSTR)server, 1, (LPBYTE*) &bufw,
2048, &read, &total, &resumeh );
if ( rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS )
break;
{
for ( i = 0, curw = bufw; i < read; ++ i, ++ curw )
{
printf( "%-12S %-15S %-12S \n", curw->wkui1_username,
curw->wkui1_logon_domain, curw->wkui1_logon_server );
}
}
if ( bufw != NULL )
NetApiBufferFree( bufw );
} while ( rc == ERROR_MORE_DATA );

if ( rc != ERROR_SUCCESS )
PrintError( rc );
}

//-------------------------------------------------------
void PrintNetUsers(LPWSTR server)
{
resumeh = 0;

do
{
buf = NULL;
rc = NetSessionEnum( (LPTSTR) server, NULL, NULL, 502, (LPBYTE*)&buf,
2048, &read, &total, &resumeh );
if ( rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS )
break;
{
for ( i = 0, cur = buf; i < read; ++ i, ++ cur )
{
printf( "%-12S %-12S %-27S %-22S\n", cur->sesi502_username,
cur->sesi502_cname, cur->sesi502_transport, cur->sesi502_cltype_name );
}

}
if ( buf != NULL )
NetApiBufferFree( buf );
} while ( rc == ERROR_MORE_DATA );

if ( rc != ERROR_SUCCESS )
PrintError( rc );
}

//-------------------------------------------------------
void PrintNetFiles(LPWSTR server)
{
resumeh = 0;
do
{
buff = NULL;
rc=NetFileEnum( (char *) server, NULL, NULL, 3, (BYTE**)&buff,
2048, &read, &total, &resumeh );
if ( rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS )
break;
for ( i = 0, curf = buff; i < read; ++ i, ++ curf )
{
printf( "%-12S %-15S \n", curf->fi3_username, curf->fi3_pathname );
}
if ( buff != NULL )
NetApiBufferFree( buff );
} while ( rc == ERROR_MORE_DATA );

if ( rc != ERROR_SUCCESS )
PrintError( rc );
}

//-------------------------------------------------------
int main( int argc, char *argv[] )
{
WCHAR server[MAXLEN];

if ( argc == 1 )
wcscpy(server,L"");
else if ( argc == 2 )
mbstowcs( server, argv[1], MAXLEN);
else
{
printf("Usage - who [server]");
exit(1);
}

printf("\nLocal users:\n");
PrintLocalUsers(server);

printf("\nNet users:\n");
PrintNetUsers(server);

printf("\nFiles(Pipes)\n");
PrintNetFiles(server);

return 0;
}[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
425
4118
07.09.2011, 14:10
общий
Цитата: 181465
Или - клинический вариант - 10-ка прошита в коде железно

Не могу утверждать точно, но как то раз в интернете я повстречал статью, что заменой файла tcpip.sys в XP можно убрать ограничение на сетевые подключения. Из чего делаю логический вывод - ограничение железно прописано в коде. У серверных же ОС это не так, потому что при установке ОС можно прописать количество подключений на сервер.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 14:31
общий
Адресаты:
Ухты! Интересно

Тогда могу предложить ещё один, дурацкий способ решения: поставить два сервера с разным количеством соединений и сверить драйвера потом у обоих. Он, скорее всего не сработает, а если и сработает, то не практичен, ввиду изменения смещений для данных внутри файла (хотя инсталлятор как-то же его генерирует?)


И, да, как NetSessionEnum работает/определяет подключения к базе данных?
давно
Мастер-Эксперт
425
4118
07.09.2011, 14:40
общий
Адресаты:
И всё было бы ничего, но у меня в gcc нет netapi32.lib.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Мастер-Эксперт
425
4118
07.09.2011, 14:45
общий
Цитата: 181465
Тогда могу предложить ещё один, дурацкий способ решения: поставить два сервера с разным количеством соединений и сверить драйвера потом у обоих.

Это несерьёзно. Мне кажется, что количество возможных подключений у серваков должно записываться где-то в реестре. Только никто не знает где...
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Мастер-Эксперт
425
4118
07.09.2011, 14:59
общий
Вот, что мне удалось добиться:

gcc -lnetapi32 netuser.c
Прикрепленные файлы:
b7f250147da1dc2dfb37a9262705746e.png
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 15:28
общий
Цитата: Вадим Исаев ака sir Henry
А по поводу netstat есть кое-какие непонятки. Например, моя рабочая станция позволяет существовать только 10 подключениям, а netstat их показывает ажно целых 16. Кому верить?


А эти установленные 16 соединений все внешние адреса?
Неизвестный
07.09.2011, 15:35
общий
07.09.2011, 15:51
Цитата: Вадим Исаев ака sir Henry
У операционки должны быть какие-то функции для учёта коннектов, иначе в XP не стояло бы ограничение на 10 подключений.


Дело в том что не все можно использовать.Многие функции предназначены только для использования самой ОС.

Узнать какая функция используется можно дизассемблировать NETSTAT.Думаю прокатит.К сожалению под рукой нет дизассемблера.

Я так понимаю разговор о базе подключениях к базе данных?Почему вам netstat не подходит?Можно ведь фильтроать по портам.Например

netstat -an|find "ESTABLISHED"|find "80"

Программа работающая в сети будет использовать какой нибудь порт.
давно
Мастер-Эксперт
425
4118
07.09.2011, 15:54
общий
Цитата: 243211
А эти установленные 16 соединений все внешние адреса?

Ага.
Цитата: 243211
Я так понимаю разговор о базе подключениях к базе данных?

Не только. Мне нужны вообще все подключения, в том числе и к расшареным ресурсам.
Цитата: 243211
Можно ведь фильтроать по портам.Например
netstat -an|find "ESTABLISHED"|find "80"

Можно. Только надо разобраться, почему такое количество подключений показывает netstat.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.09.2011, 16:21
общий
Мои комментарии выходят за рамки этой темы но я считаю что практичней использовать HTTP.
C помощью php можно знать о подключении все и по условию переадресовывать куда надо.Людей к файлам, роботов в мусорку.В качестве примера я приведу перечень глобальных переменных.Вы увидите что так проще.Но это мое мнение, я его никому не навязываю.

PHP_SELF

Имя файла в настоящее время выполняющегося сценария, относительно корня документа. Например, $_SERVER ['PHP_SELF'] в сценарии при адресе http://example.com/test.php/foo.bar возвращает /test.php/foo.bar. Предопределенная константа __FILE__ содержит полный путь и имя файла.
Если PHP выполняется из командной строки, эта переменная содержит имя сценария (доступно, начиная с PHP 4.3.0).

argv

Массив параметров, переданных сценарию. При использовании метода GET, он будет содержать строку запроса.

argc

Содержит номер параметров командной строки, переданных сценарию (если они переданы из командной строки).
GATEWAY_INTERFACE

Содержит версию CGI, которую использует веб-сервер (Например, CGI/1.1).

SERVER_NAME

Имя веб-сервера, под которым текущий скрипт выполняется. Если скрипт исполняется на виртуальном веб-сервере, переменная будет содержать имя веб-сервера, которое было определено для виртуального веб-сервера.

SERVER_SOFTWARE

Идентификационная строка веб-сервера, которая передается через заголовки при ответах на запросы сервера.

SERVER_PROTOCOL

Имя и версия используемого протокола HTTP (Например, HTTP/1.1).

REQUEST_METHOD

Используемый метод запроса веб-страницы ( 'GET', 'HEAD', 'POST', 'PUT' ).

REQUEST_TIME

Время начала запроса веб-страницы. Доступна, начиная с PHP 5.1.0

QUERY_STRING

Строка запроса веб-страницы, если она существует, через которую был получен доступ к странице.

DOCUMENT_ROOT

Корневая директория, под которой выполняется текущий скрипт. Определяется конфигурацией веб-сервера.

HTTP_ACCEPT

Содержание заголовка Accept, если он есть.

HTTP_ACCEPT_CHARSET

Содержание заголовка Accept-Charset, если он есть. Пример: 'iso-8859-1,*,utf-8'.

HTTP_ACCEPT_ENCODING

Содержание заголовка Accept-Encoding, если он есть. Пример: 'gzip'.

HTTP_ACCEPT_LANGUAGE

Содержание заголовка Accept-Language, если он есть. Пример: 'en'.

HTTP_CONNECTION

Содержание заголовка Connection, если он есть. Пример: 'Keep-Alive'.

HTTP_HOST

Содержание заголовка Host, если он есть.

HTTP_REFERER

Адрес страницы, которая ссылается на текущий документ посредством пользовательского клиента (программное обеспечение клиента). Не все пользовательские клиенты предоставляют данную информацию, а некоторые из них способны изменять HTTP_REFERER, следовательно, такой информации полностью доверять нельзя.

HTTP_USER_AGENT

Содержание заголовка 'User-Agent'. Эта строка содержит информацию о пользовательском клиенте (программное обеспечение клиента), который обращается к странице. Типичный пример: Mozilla/4.5 [en] (X11; U; Linux 2.2.9 i586). Для получения подобной информации вы также можете использовать функцию get_browser()

REMOTE_ADDR

IP-адрес удаленного пользователя, который обращается к текущей странице.

REMOTE_HOST

Имя хоста удаленного пользователя, который обращается к текущей странице. Реверсивный поиск DNS базируется на REMOTE_ADDR удаленного пользователя. Примечание: веб-сервер должен поддерживать создание данной переменной. Например, в Apache опция HostnameLookups должна быть включена в конфигурационном файле httpd.conf (On). Смотрите также: gethostbyaddr()

REMOTE_PORT

Порт, используемый для соединения с веб-сервером

SCRIPT_FILENAME

Абсолютный путь для текущего скрипта.

SERVER_ADMIN

Значение, задаваемое SERVER_ADMIN (для Apache). Определяется директивой конфигурации веб-сервера. Если скрипт исполняется на виртуальном хосте, то значение определяется текущими настройками виртуального хоста веб-сервера.

SERVER_PORT

Текущий порт веб-сервера, используемы для предечи данных по протоколу HTTP. По-умолчанию '80'.

SERVER_SINGATURE

Строка, содержащая версию веб-сервера или имя виртуального хоста.

PATH_TRANSLATED

Базовый путь к текущему сценарию.

SCRIPT_NAME

Содержит путь и имя файла текущего исполняемого скрипта.

REQUEST_URI

URI для текущей страницы, например, '/index.html'.

PHP_AUTH_DIGEST

Если PHP работает как модуль Apache, переменная используется в аутентификации по протоколу HTTP, для проверки подлинности.

PHP_AUTH_USER

Если PHP работает как модуль Apache, либо как ISAPI IIS, данная переменная содержит имя авторизируемого пользователя при аутентификации по протоколу HTTP.

PHP_AUTH_PW

Если PHP работает как модуль Apache, либо как ISAPI IIS, данная переменная содержит пароль авторизируемого пользователя при аутентификации по протоколу HTTP.

AUTH_TYPE

Если PHP работает как модуль Apache, либо как ISAPI IIS, данная переменная содержит тип используемой аутентификации по протоколу HTTP.
давно
Посетитель
7438
7205
07.09.2011, 17:41
общий
07.09.2011, 18:05
Адресаты:
Хочу предложить программку на Delphi. Это Ваше родное, разберетесь.
В ней использованы два способа для получения статистики:
1) При помощи GetTcpTable, GetUdpTable
2) При помощи недокументрированных методов AllocateAndGetTcpExTableFromStack, AllocateAndGetUdpExTableFromStack. Работает только на ХР или Win 2003.
Кстати, именно последние и используются в netstat
Прикрепленные файлы:
db40ee487fb6ef09371ad6d43659d7c3.zip
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
07.09.2011, 17:42
общий
Возможно, количество сетевых подключений к серверу на данный момент можно определить с помощью Windows Management Instrumentation (WMI). У кого какие мысли по этому поводу?
Неизвестный
07.09.2011, 19:42
общий
Про HTTP - я бы не стал использовать, потому что http может быть закрыть админами.

WMI тоже может быть отключено.

Про недокументированные функции - надо только следить, что они до сих пор поддерживаются операционкой в том же виде. А ещё бы я поискал в системе внешние обёртки под эти функции.
давно
Мастер-Эксперт
425
4118
08.09.2011, 06:43
общий
Адресаты:
В общем я переделал Ваш пример с NetSessionEnum на Pascal, однако эта функция требует каких то совершенно особых привилегий (по крайней мере в семёрке). Единственное, что от неё удалось добиться, это ERROR_ACCESS_DENIED.
Сейчас посмотрю второй Ваш пример.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Мастер-Эксперт
425
4118
08.09.2011, 07:08
общий
08.09.2011, 07:17
Адресаты:
По второму примеру: Похоже Билл Гейтс не дремлет.
Error: Точка входа в процедуру AllocateAndGetUdpExTableFromStack не найдена в библиотеке DLL IPHLPAPI.DLL.
Хотя, если судить по MSDN, эта процедура именно в этой DLL'ке и должна находиться.

Добавлено:
Всё прояснилось. Из MSDN:

End of client support: Windows XP
End of server support: Windows Server 2003

т.е. ни в Windows 7, ни в Windows 2008 эти функции уже не работают. А у меня как раз сии операционки...
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
7438
7205
08.09.2011, 09:28
общий
Адресаты:
Да, первая программка немного не то: показывает подключенных пользователей и открытые файлы...
А GetTcpTable есть?
По поводу второй я ж так и указал:
Работает только на ХР или Win 2003

А в Windows 7 есть аналогичная утилита? Если есть, дайте мне, я посмотрю, что там используется.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Мастер-Эксперт
425
4118
08.09.2011, 09:51
общий
08.09.2011, 10:14
Адресаты:

В семёрке GetTcpTable есть. Вот что у меня получилось:
Код:
{$mode objfpc}{$H+}
Uses Windows, jwawinsock2, jwaiprtrmib, jwaiphlpapi;

// Функция преобразует состояние порта в строковый эквивалент
function PortStateToStr(const State: DWORD): String;
begin
case State of
MIB_TCP_STATE_CLOSED: Result := 'CLOSED';
MIB_TCP_STATE_LISTEN: Result := 'LISTEN';
MIB_TCP_STATE_SYN_SENT: Result := 'SYN SENT';
MIB_TCP_STATE_SYN_RCVD: Result := 'SYN RECEIVED';
MIB_TCP_STATE_ESTAB: Result := 'ESTABLISHED';
MIB_TCP_STATE_FIN_WAIT1: Result := 'FIN WAIT 1';
MIB_TCP_STATE_FIN_WAIT2: Result := 'FIN WAIT 2';
MIB_TCP_STATE_CLOSE_WAIT: Result := 'CLOSE WAIT';
MIB_TCP_STATE_CLOSING: Result := 'CLOSING';
MIB_TCP_STATE_LAST_ACK: Result := 'LAST ACK';
MIB_TCP_STATE_TIME_WAIT: Result := 'TIME WAIT';
MIB_TCP_STATE_DELETE_TCB: Result := 'DELETE TCB';
else
Result := 'UNKNOWN';
end;
end;


// Получение TCP/UDP статистики при помощи стандартных методов
procedure Show;
var
Size: DWORD;
TCPTable: PMIB_TCPTABLE;
UDPTable: PMIB_UDPTABLE;
I, Count: DWORD;
begin
// для успешного получения стстаистики первоначально необходимо определиться
// сколько памяти потребует данная операция
// для этого делаем так:
// Вделяем память под TCP таблицу (под один элемент)
GetMem(TCPTable, SizeOf(TMibTCPTable));
try
// Показываем что памяти у нас не выделено
Size := 0;
// Выполняем функцию и после этого переменная Size
// будет содержать кол-во необходимой памяти
if GetTcpTable(TCPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
finally
// освобождаем память занятую под один элемент
FreeMem(TCPTable);
end;
// Теперь выделяем уже требуемое кол-во памяти
GetMem(TCPTable, Size);
Count:=0;
try
// Выполняем функцию
if GetTcpTable(TCPTable, Size, True) = NO_ERROR then
begin
WriteLn('');
WriteLn('Standart TCP Stats');
WriteLn('Host':15, 'RemotePort':10, 'State':15, 'LocalPort':10);

WriteLn('==================================================');
// и насинаем выводить данные по ТСР
for I := 0 to TCPTable^.dwNumEntries - 1 do
If (inet_ntoa(in_addr(TCPTable^.Table[I].dwRemoteAddr))<>'127.0.0.1') and
(inet_ntoa(in_addr(TCPTable^.Table[I].dwRemoteAddr))<>'0.0.0.0') Then
Begin
WriteLn(inet_ntoa(in_addr(TCPTable^.Table[I].dwRemoteAddr)):15,
htons(TCPTable^.Table[I].dwRemotePort):10,
PortStateToStr(TCPTable^.Table[I].dwState):15,
htons(TCPTable^.Table[I].dwLocalPort):10);

Inc(Count);
End;
end;
WriteLn('==================================================');
WriteLn('OutConnections: ', Count);
finally
// Не забываем освободить память
FreeMem(TCPTable);
end;

// По аналогии поступаем и с UDP статистикой
GetMem(UDPTable, SizeOf(TMibUDPTable));
try
Size := 0;
if GetUdpTable(UDPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
finally
FreeMem(UDPTable);
end;
GetMem(UDPTable, Size);
try
if GetUdpTable(UDPTable, Size, True) = NO_ERROR then
begin
WriteLn('');
WriteLn('Standart UDP Stats');
WriteLn('Host':15, 'Port':7);
WriteLn('======================================');
Count:=0;
for I := 0 to UDPTable^.dwNumEntries - 1 do
if (inet_ntoa(in_addr(TCPTable^.Table[I].dwLocalAddr))<>'127.0.0.1') and
(inet_ntoa(in_addr(TCPTable^.Table[I].dwLocalAddr))<>'0.0.0.0') Then
Begin
WriteLn(inet_ntoa(in_addr(UDPTable^.Table[I].dwLocalAddr)):15,
htons(UDPTable^.Table[I].dwLocalPort):7);
Inc(Count);
End;
end;
WriteLn('==================================================');
WriteLn('OutConnections: ', Count);
finally
FreeMem(UDPTable);
end;
end;

Begin
Show;
End.

Извиняюсь, что не на С++ (С++ - отстой, FreePascal - форева! ). Код полностью работающий и на семёрке и на 2008. Можете давать ответ, только код, наверное, надо на С++ перелопатить.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Мастер-Эксперт
425
4118
08.09.2011, 09:52
общий
Адресаты:
Цитата: Лысков Игорь Витальевич
А в Windows 7 есть аналогичная утилита?

Вы про netstate? Есть и называется так же.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
давно
Посетитель
7438
7205
08.09.2011, 13:49
общий
это ответ
Здравствуйте, sir Henry!
Вот Вам программа, показывающая TCP- и UDP-подключения к компьютеру.
Работа основана на двух функциях: GetTcpTable и GetUdpTable

[code h=207]#pragma once

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <iostream>
#include <Iphlpapi.h>
#include <Winsock2.h>
#include <conio.h>
#include <stdio.h>

#pragma comment( lib, "Iphlpapi.lib" )
#pragma comment( lib, "Ws2_32.lib" )

using namespace std;

// Функция преобразует состояние порта в строковый эквивалент
char * PortStateToStr(const DWORD State)
{
switch (State)
{
case MIB_TCP_STATE_CLOSED:
return "CLOSED";
case MIB_TCP_STATE_LISTEN:
return "LISTEN";
case MIB_TCP_STATE_SYN_SENT:
return "SYN SENT";
case MIB_TCP_STATE_SYN_RCVD:
return "SYN RECEIVED";
case MIB_TCP_STATE_ESTAB:
return "ESTABLISHED";
case MIB_TCP_STATE_FIN_WAIT1:
return "FIN WAIT 1";
case MIB_TCP_STATE_FIN_WAIT2:
return "FIN WAIT 2";
case MIB_TCP_STATE_CLOSE_WAIT:
return "CLOSE WAIT";
case MIB_TCP_STATE_CLOSING:
return "CLOSING";
case MIB_TCP_STATE_LAST_ACK:
return "LAST ACK";
case MIB_TCP_STATE_TIME_WAIT:
return "TIME WAIT";
case MIB_TCP_STATE_DELETE_TCB:
return "DELETE TCB";
default:
return "UNKNOWN";
}
}

// Получение TCP/UDP статистики при помощи стандартных методов
void Show(void)
{
// Declare and initialize variables
int Count;
DWORD i, Size;
PMIB_TCPTABLE pTCPTable;
PMIB_UDPTABLE pUDPTable;
in_addr *paddr;

// для успешного получения стстаистики первоначально необходимо определиться
// сколько памяти потребует данная операция
// для этого делаем так:
// Вделяем память под TCP таблицу (под один элемент)
pTCPTable = (MIB_TCPTABLE*) GlobalAlloc(GMEM_FIXED,sizeof(MIB_TCPTABLE));
// Показываем что памяти у нас не выделено
Size = 0;
// Выполняем функцию и после этого переменная Size
// будет содержать кол-во необходимой памяти
if (GetTcpTable(pTCPTable, &Size, TRUE) != ERROR_INSUFFICIENT_BUFFER)
return;
// освобождаем память занятую под один элемент
GlobalFree(pTCPTable);
// Теперь выделяем уже требуемое кол-во памяти
pTCPTable = (MIB_TCPTABLE*) GlobalAlloc(GMEM_FIXED, Size);

Count = 0;
// Выполняем функцию
if (GetTcpTable(pTCPTable, &Size, TRUE) == NO_ERROR)
{
cout << endl;
cout << "\tСтатистика TCP" << endl;
cout.width(19);
cout << "Удаленный IP-адрес";
cout.width(15);
cout << "Удаленный порт";
cout.width(15);
cout << "Состояние";
cout.width(15);
cout << "Локальный порт" << endl;
cout << "================================================================" << endl;
// и начинаем выводить данные по ТСР
for (i=0; i<pTCPTable->dwNumEntries; i++)
{
paddr = (in_addr *)&pTCPTable->table[i].dwRemoteAddr;
if (strcmp(inet_ntoa(*paddr), "0.0.0.0"))
{
cout.width(19);
cout << inet_ntoa(*paddr);
cout.width(15);
cout << htons(pTCPTable->table[i].dwRemotePort);
cout.width(15);
cout << PortStateToStr(pTCPTable->table[i].dwState);
cout.width(15);
cout << htons(pTCPTable->table[i].dwLocalPort) << endl;
Count++;
}
}
cout << "================================================================" << endl;
cout << "Всего соединений: " << Count << endl;

}
// Не забываем освободить память
GlobalFree(pTCPTable);

// По аналогии поступаем и с UDP статистикой
pUDPTable = (MIB_UDPTABLE*) GlobalAlloc(GMEM_FIXED,sizeof(MIB_UDPTABLE));
Size = 0;
if (GetUdpTable(pUDPTable, &Size, TRUE) != ERROR_INSUFFICIENT_BUFFER)
return;
GlobalFree(pUDPTable);
pUDPTable = (MIB_UDPTABLE*) GlobalAlloc(GMEM_FIXED, Size);

Count = 0;
if (GetUdpTable(pUDPTable, &Size, TRUE) == NO_ERROR)
{
cout << endl << endl;
cout << "\tСтатистика UDP" << endl;
cout.width(19);
cout << "Локальный IP-адрес";
cout.width(15);
cout << "Локальный порт" << endl;
cout << "==================================" << endl;
for (i=0; i<pUDPTable->dwNumEntries; i++)
{
paddr = (in_addr *)&pUDPTable->table[i].dwLocalAddr;
if (strcmp(inet_ntoa(*paddr), "0.0.0.0"))
{
cout.width(19);
cout << inet_ntoa(*paddr);
cout.width(15);
cout << htons(pTCPTable->table[i].dwLocalPort) << endl;
Count++;
}
}
cout << "==================================" << endl;
cout << "Всего соединений: " << Count << endl;

}
GlobalFree(pUDPTable);
}

int main()
{
setlocale(LC_ALL,"russian");
Show();
_getch();
return 0;
}[/code]
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа