/
Введение
Трафик это основной и единственный ресурс сети Интернет с точки зрения транспорта. Как известно, любая информация в сети Интернет передается в виде отдельных пакетов - блоков данных сравнительно небольшого размера, каждый из которых имеет адрес отправителя и получателя и путешествует по сети самостоятельно. Так вот, трафик это суммарный объем пакетов, прошедших через точку наблюдения. Если бы Интернет был транспортной компанией, то трафик это суммарный вес грузов, перевезенных пакетами-грузовиками вне зависимости от конкретного содержания грузов. Когда выполняется работа с трафиком, абстрагируется содержимого пакетов, поскольку в этом контексте интересно не что именно передано, а сколько и откуда. Если говорить об учете трафика при работе компаний с Интернетом, то возникает понятие трафика входящего и исходящего. Контроль и учет трафика появился вместе с развитием коммерческого сегмента сети интернет. Как только появился платный ресурс, для любого пользователя, подключенного к провайдеру услуг интернет стало интересно учитывать потребление платного ресурса, чтобы контролировать провайдера и понимать на что расходуются деньги за связь. Точно также практически любой провайдер подключен к другому провайдеру для которого он выступает как клиент - т.е. платит за входящий трафик. Поэтому провайдеру необходимо не только учитывать трафик ушедший к клиентам, но и вести подсчет трафика, пришедшего в сеть провайдера снаружи - от других провайдеров. С резким увеличением количества пользователей в сети и появлением трафика разных приложений вопрос о необходимости введения автоматизированной системы контроля трафика локально - вычислительной сети стал чрезвычайно актуальным.
Таким образом, учет трафика необходим для того, чтобы, во-первых, тарифицировать использование Интернет ресурсов, а во-вторых, максимально сократить расходы и оптимизировать использование рабочего времени в организации клиенте. Есть еще один немаловажный аспект, связанный с использованием систем учета трафика - это ограждение пользователей клиента от ненужной или вредной информации из сети Интернет. Автоматизированная система контроля трафика локально-вычислительной сети включает в себя измерение трафика, текущий контроль трафика, измерение структуры трафика.
Данный проект представляет собой автоматизированную систему, помогающую отслеживать передачу данных на компьютере клиента и предавать данные на компьютер сервера. Программный продукт разработан на языке Object Pascal в среде программирования Borland Delphi 7, состоит из 2 приложений: Клиент и Сервер. Пояснительная записка представлена на 78 страницах, состоит из введения, аналитической части, проектной части, техники безопасности, заключения.
1. Аналитическая часть
1.1 Трафик
Трафик это основной и единственный ресурс сети Интернет с точки зрения протоколов транспортного уровня. Как известно, любая информация в сети Интернет передается в виде отдельных пакетов - блоков данных сравнительно небольшого размера, каждый из которых имеет адрес отправителя и получателя и путешествует по сети самостоятельно. Так вот, трафик это суммарный объем пакетов, прошедших через точку наблюдения. Если бы Интернет был транспортной компанией, то трафик это суммарный вес грузов, перевезенных пакетами-грузовиками вне зависимости от конкретного содержания грузов.
Когда выполняется работа с трафиком, системный администратор абстрагируемся от содержимого пакетов, поскольку в этом контексте становится интересным не что именно передано, а сколько и откуда. С другой стороны, для конечного пользователя сети Интернет интерес представляет не только сколько и откуда данных было получено, т.е. количество, но и качество, а именно - что содержалось в этих полученных данных. В общем случае задача учета трафика для операторов и для конечных потребителей отличается именно тем, что последним необходимо контролировать не только количество, но и качество трафика, т.е. в определенных пределах его содержимое.
Если говорить об учете трафика при работе компаний с Интернетом, то возникает понятие трафика входящего и исходящего. Входящий трафик это все пакеты, которые пересекли границу сети между вашей организацией и любой другой сетью в направлении «к вам». Это объем импортированных вами из Интернета данных. Исходящий - соответственно, объем экспортированных вами данных[23]. Наиболее важно понятие входящего трафика, потому что это тот трафик за который, как правило, приходится платить. Бывают, конечно, и исключения, когда платить приходится и за исходящий трафик, но это случается редко. Большинство поставщиков услуг связи берут с клиентов деньги именно за входящий к ним трафик, т.е. за объем данных, которые получил, а не отправил клиент. Это происходит потому, что именно за входящий к нему трафик платит вышестоящему провайдеру ваш провайдер, а при огромных размерах сети Интернет вероятность того, что нужные вам ресурсы находятся непосредственно в сети вашего оператора, стремится к нулю.
1.2 Внутренний учет трафика в организации
Внутри компании, подключенной к сети Интернет, имеется серьезнейшая мотивация для использования систем учета трафика. Интернет уже стал неотъемлемой частью бизнес процессов, тесно переплетаясь с информационными системами бизнеса. То, насколько компания контролирует информацию своего бизнеса, теперь зависит от того, насколько она контролирует Интернет подключение.
Каждый год Интернет удивляет нас скоростью своего роста. Растет не только количество пользователей, но и скорость подключений. Широкополосные подключения, уже повсеместно заменили собой низкоскоростные подключения на корпоративном рынке. Благодаря этому Интернет становится мощным инструментом, который, однако, требует существенно большего контроля. Миллионы новых пользователей появляются в сети, постоянно снижая средний уровень квалификации его пользователей. Бурное развитие технологии направлено в основном на получение большей скорости, в то время как разработка и внедрение механизмов, которые должны обеспечивать учет трафика, контроль и безопасность серьезно отстает от технологии, ответственной за скорость.
Уже очевидно, что средний уровень обычного пользователя совершенно недостаточен для обеспечения хотя бы собственной безопасности при высоких современных скоростях.
Вероятно, нельзя, да и несправедливо требовать от обычного пользователя Интернет высокой квалификации и способности самостоятельно решать все проблемы и избегать соблазнов, которые возникают при работе с сетью Интернет. Для того, что пользователь мог успешно решать свои задачи как сотрудник компании, имеющей интернет-подключение, сама компания должна принять ряд мер, направленных на учет и контроль Интернет трафика и тем самым избежать ряда возможных проблем, таких как нецелевое использование рабочего времени и перерасход трафика[24].
1.3 Нецелевое использование средств
Прямые затраты на Интернет зависят от объема потребленной информации. Создать потребление может как передача данных о новом продукте вашим поставщиком, так и увлечение сотрудников играми в сети. Таким образом, информация может быть как целевой, так и нецелевой. К сожалению, провайдеру все равно, какую информацию вы получили - платить придется за все виды трафика.
Во время потребления средств для Интернет прогулок (или прогулов) сотрудники также потребляют и рабочее время. Шутники от компьютерного мира нередко называют Интернет Всемирной Помойкой, и в чем-то они недалеки от истины. Помимо ресурсов, полезность которых очевидна и неоспорима, в Сети размещено фантастическое количество материалов сомнительного свойства, начиная 'бородатыми' анекдотами и заканчивая порнографией, сайтами экстремистского толка и др. Причем 'мусора' в процентном отношении к полезным данным значительно больше. Абстрагируясь от морально-этической стороны рассматриваемых материалов, следует отметить, что так или иначе они отвлекают внимание ваших сотрудников, а на их просмотре теряется значительное количество рабочего времени.
В материалах сайта http://www.iemag.ru приводятся данные ряда зарубежных исследователей относительно типа потребляемого трафика сотрудниками компаний на своих рабочих местах:
В опросе, проведенном SurfControl, 100% сотрудников, использующих веб-доступ на работе, сообщили, что они пользовались им в личных целях. А 18% сотрудников ежедневно используют Интернет в личных целях 10 и более раз.
Исследование, проведенное Yankelovich Partners, показало, что более 62% сотрудников ежедневно используют доступ в Интернет в личных целях хотя бы раз.
Исследование SANS Institute показало, что от 50 до 70% сайтов, которые посещают сотрудники во время работы, не связаны с бизнесом.
Исследование, проведенное в Великобритании показало, что 44% сотрудников, имеющих доступ в Интернет на работе, тратят в среднем по 3 часа в неделю на использование рабочего Интернета в личных целях.
Исследование Aberdeen Group показало, что сотрудники компаний тратят от 30 мин. до 3 часов ежедневно на нецелевой броузинг.
Исследование Dataquest показало, что 20% сотрудников используют рабочий Интернет в личных целях более 3 часов ежедневно.
Исследование SANS Institute показало, что потери времени на броузинг у 100 наиболее активных интернет-пользователей в компании составляют около 14% полного рабочего времени.
По результатам исследования, проведенного в США, сотрудники с интернет-доступом тратят около 15% своего рабочего времени на просмотр веб-сайтов, не связанных с их бизнесом.
По данным Websense 70% трафика на веб-сайтах для взрослых приходится на рабочее время (с 9 до 17 часов) и 30%-40% всей активности в онлайне в эти часы совершенно не связано с бизнесом. Кроме того, более 60% онлайновых покупок также совершается в рабочие часы.
Исследование Nielsen/NetRatings показало, что 60% сотрудников, имеющих Интернет на рабочем месте, посещают электронные магазины, а 54% - развлекательные сайты.
Кроме прямых потерь на оплату потребленного трафика есть потери скрытые, например, использование сотрудниками пропускной способности и сетевых функций для доступа к сайтам, несвязанным с их работой, снижает скорость доступа к критической бизнес-информации. Кроме этого, увеличивается время простоя систем в результате скачивания большого объема файлов и сбоев, связанных с недостатком системных ресурсов. Более того, простой систем и деятельность, не связанная с бизнесом, приводят к снижению производительности сотрудников[25].
Проблема нецелевого использования трафика существует в любой компании, предоставляющей сотрудникам доступ в Интернет в связи с выполнением ими их служебных обязанностей, например, продаж, поиска новых клиентов, поставщиков, осуществления Интернет рекламы и т.д. Проблема состоит не столько в самом факте нецелевого расходования, сколько в масштабе этого явления, поскольку полностью искоренить его вряд ли возможно. Основной риск, состоит в потерянном рабочем времени. Безусловно, существуют и прямые финансовые потери, связанные с расходами на доступ в Интернет, но этими потерями легко управлять, так как они имеют очевидное и измеряемое проявление. Другие риски нравственного или юридического характера, хотя и могут иметь место, но как правило не являются столь существенными. Обычно для контроля всех этих рисков доступ в Интернет в компании должен быть персонифицирован и должны предприниматься меры по мониторингу трафика. Этих мер вполне достаточно, как для контроля целесообразности использования Интернета, так и для управления затратами.
Второй важнейшей причиной являются вредоносные сетевые программы: вирусы, черви, так называемые троянские кони и т.д. Попавшие в сеть вирусы или черви будут стараться заразить другие компьютеры в Интернет, создавая огромное количество нецелевого паразитного трафика.
1.4 Предназначение контроля и учета трафика
Для того чтобы не растратить деньги попусту необходимо, во-первых, иметь точную и оперативную информацию о том, кто, сколько и каких ресурсов из Интернет потребляет, а во-вторых, иметь возможность запретить доступ неблагонадежным пользователям или доступ к явно бесполезным ресурсам. Эволюция сетей электроснабжения привела к появлению различных стандартизированных устройств, которые защищают пользователя от сети, и наоборот - сеть от пользователя. Это автоматы защиты - рубильники, электросчетчики, трансформаторы. В случае Интернета таких стандартных устройств пока нет, хотя они не менее необходимы. Представьте себе электрическую сеть без любого из этих устройств.
В чистом виде учет трафика - это только счетчик. Программные продукты, которые реализуют учет трафика в корпоративных сетях, должны также уметь управлять доступом пользователей, фильтровать содержимое данных, получаемых компанией из сети Интернет, обеспечивать защиту корпоративной сети, а также иметь различные дополнительные функции, облегчающие взаимодействие корпоративной сети с Интернетом. Такие серверы контроля корпоративного Интернет подключения в идеале должны полностью автоматизировать и управлять взаимоотношениями между корпоративной сетью и Интернетом. Эти требования позволяют четко разграничить требования к продуктам для учета трафика в сетях операторов связи и в корпоративных сетях, породив по сути две различные ветви эволюции в развитии таких систем[30].
компьютер трафик сервер архитектура
1.5 Две ветви систем контроля и учета трафика
Таким образом, и автоматизированные системы расчетов, используемые провайдерами, и серверы для контроля Интернет подключения в организациях клиентах строятся вокруг функции учета трафика, и это то главное, что их объединяет, но остальной функционал их сильно отличается.
Для автоматизированных систем расчетов характерен уклон в сторону бухгалтерии и автоматизации бизнес процессов оператора связи. Кроме того, провайдерские системы учета трафика не должны иметь большого числа функций, поскольку это замедляет их быстродействие, и для определения пользователя, достаточно знать IP адрес его сети.
С другой стороны, серверы для контроля Интернет подключения для компаний пользователей Интернет помимо учета трафика должны гибко управлять доступом пользователей к Интернету, обеспечивать защиту сети, и что особенно важно, обладать набором развитых механизмов авторизации пользователя. Ведь для провайдера с маршрутизируемой сетью даже авторизация на основе IP адреса будет вполне достаточной, а вот для организации, использующей Интернет, авторизация по IP адресу ненадежна и неудобна.
Именно поэтому пути развития программных продуктов для провайдеров и для корпоративных пользователей расходятся все дальше. Каждый из этих программных продуктов постоянно оптимизируется под задачи, характерные для своей области использования. Так что, если вы - Интернет провайдер - выбирайте автоматизированную систему расчетов, имеющую сертификат соответствия по системе сертификации в области связи, что дает вам право использовать данные автоматизированной системы расчетов для выставления счетов клиентам[26].
Если вы корпоративный пользователь, то вам нужен сервер контроля Интернет подключения. Кстати, для внутрикорпоративного использования сервер контроля Интернет подключения не обязан обладать сертификатом, напротив, наличие сертификата удорожает продукт и говорит о его приспособленности под совершенно другие задачи. Зато с другой стороны, ваш сервер контроля Интернет подключения должен обладать всеми необходимыми функциями для решения именно выше перечисленных задач.
1.6 Эволюция решений по контролю и учету трафика для корпоративных сетей
Существенная доля решений реализуется на базе компьютера или сервера, который либо маршрутизирует трафик, либо на нем имеется прокси сервер. В наиболее продвинутых решениях обе модели реализованы одновременно. Операционные системы решений - это Microsoft Windows Server, FreeBSD либо Linux. Решения, естественно, различаются как наборами основных, так и дополнительных функций. Лидеры отрасли имеют в своем арсенале максимальное количество взаимоувязанных сервисов, которые управляются из единого интерфейса.
Наиболее удобны для пользователя такие решения, дистрибутив которых устанавливает на компьютер все, включая операционную систему и все необходимые программы и утилиты. Это значительно удобнее, чем устанавливать все по отдельности. Естественно, что такие решения базируются на ОС Linux или FreeBSD. Кстати, решения на базе UNLX-подобных систем зачастую не требуют абсолютно никаких знаний этих операционных систем от пользователя, поскольку все функции управляются через веб или иные интерфейсы.
Все решения на базе Microsoft требуют не только установки, но и, подразумеваем, приобретения пользователем других компонентов решения -операционной системы, СУБД и т.д. Также Windows решения предъявляют высокие требования по знанию операционной системы к администратору такого решения. Чем более качественным является сервер контроля Интернет подключения, тем большее количество механизмов авторизации пользователей будет в нем присутствовать, позволяя гибко интегрировать систему в корпоративную сеть заказчика.
Если говорить о дальнейшем развитии серверов контроля корпоративного Интернет подключения, то можно выделить такие направления:
– Решения будут обзаводиться дополнительными сервисами, стремясь к обеспечению всех потребностей клиента по работе с Интернетом.
– Довольно много работы будет выполнено по интеграции корпоративного почтового сервера и решению задач контроля СПАМ рассылок и иных угроз, связанных с электронной почтой.
– Вообще компонент информационной безопасности в серверах контроля корпоративного Интернет доступа будет существенно усиливаться. Развитие пользовательских интерфейсов пойдет по пути упрощения и автоматизации, чтобы корпоративный Интернет доступ сравнялся по простоте настройки, скажем, с мобильным телефоном [27].
1.7 Методы контроля и учета трафика
В зависимости от архитектуры сервера контроля корпоративного Интернет доступа могут быть задействованы различные методы получения данных о потреблении трафика.
Для того чтобы полностью учитывать входящий в корпоративную сеть компании трафик, необходимо либо пропускать его через устройство учета, либо получать достоверные данные от системы, которая является маршрутизатором между корпоративной сетью клиента и сетью оператора связи. Причем, поскольку нас интересует распределение входящего трафика по конкретным пользователям, то такой учет должен вестись внутри сети по отношению к тому устройству, которое осуществляет функцию сетевой трансляции адресов (NAT), которая часто используется в сегменте Интернет. Это связано с тем, что система, ведущая учет трафика, должна точно знать внутренний адрес конечного потребителя, и следствием этого требования является тот факт, что оператор связи чаще всего не в состоянии предложить клиенту даже услугу детального анализа его трафика.
Второй вариант построения системы учета - это получение информации о транзитном трафике от маршрутизатора, через который этот трафик проходит. Опять же этот маршрутизатор должен либо сам осуществлять преобразование сетевых адресов клиента (NAT) и включать эту информацию в отчеты, либо находиться в топологии внутренней сети до того устройства, которое осуществляет функцию NAT. При использовании такой схемы необходимо, чтобы выполнялись несколько условий:
Данные, получаемые с маршрутизатора, должны иметь большую степень детализации, а именно, как минимум содержать в себе IP адреса узла отправителя и узла получателя, номера портов протоколов с обеих сторон, тип транспортного протокола, объем переданных данных. Причем речь может идти как об отдельных пакетах, так и об объединенных группах пакетов под определением «сессии» или «потока». Естественно, что во втором случае объем информации о транзитном трафике, который приходится обрабатывать и передавать как непосредственному маршрутизатору, так и серверу контроля Интернет доступа, будет существенно меньше.
Периодичность отправки этих данных на сервер контроля Интернет доступа должна позволять серверу ограничить перерасход трафика, связанный с превышением лимитов. Например, если маршрутизатор объединит в «поток», по которому отчитается только один раз - по окончании этого потока, скажем закачку фильма объемом 1 Гбайт, то перерасход трафика в самом неудачном сценарии составит 1 Гбайт. Поэтому отчитывающийся маршрутизатор должен дробить потоки на единицы сравнительно малого объема и передавать информацию о них серверу контроля Интернет доступа с соответствующей частотой.
Сервер контроля Интернет доступа в такой конфигурации не будет иметь возможности непосредственно влиять на проходящий трафик, например, вводя ограничения по исчерпанию квоты, поскольку он сам не оказывается на маршруте прохождения трафика. В этой связи необходимо наличие такой возможности опосредованно через управление сервером контроля Интернет доступа собственно устройством, осуществляющим маршрутизацию трафика.
Третьим способом получения данных о трафике, поступающем в корпоративную сеть компании, является мониторинг и анализ лог файлов различных программных шлюзов, обслуживающих корпоративную сеть компании. Наиболее явными представителями таких шлюзов являются прокси - сервер для обслуживания обращений пользователей к внешним серверам веб, а также корпоративный почтовый сервер, отправляющий и принимающий корпоративную электронную почту [28].
1.8 Общая архитектура серверов контроля корпоративного Интернет доступа
Для того чтобы лучше представить себе принципы работы систем, контролирующих Интернет доступ в корпоративной сети, в качестве примера рассмотрим сервер под управлением ОС LINUX.
Ядро системы на базе ОС LINUX осуществляет маршрутизацию IP пакетов между интерфейсами системы (в общем случае между внешним и внутренним интерфейсом) на основании статической настройки маршрутов с указанием маршрутизатора оператора связи в качестве маршрута по умолчанию.
В более сложных конфигурациях может применяться динамическая маршрутизация на основании протоколов RIPv2, OSPF. Кроме того, внутренние интерфейсы могут быть настроены в режиме поддержки VLAN (802.1Q). В этом случае для системы будет существовать несколько логических интерфейсов по одному на каждый VLAN.
При прохождении пакетов через интерфейсы система перехватывает копию каждого пакета для осуществления учета трафика.
В процессе обработки трафика необходимо связать данные каждого пакета с конкретным пользователем корпоративной сети и начислить на этого пользователя потребленный трафик. Причем нужно также избежать двойного начисления трафика, когда мы учитываем данные одновременно от перехвата пакетов и по запросам прокси - сервера. Статистика снимается как на внешнем, так и на внутреннем интерфейсах системы. Это сделано для того, чтобы учитывать трафик, чьим адресом назначения является сам сервер контроля корпоративного Интернет доступа.
Источниками данных для учетной системы являются также прокси - сервер и сервер электронной почты SMTP. Данные из журналов этих систем поступают процессу - обработчику статистики, который соотносит потребление трафика с конкретными пользователями сети компании. Этот же процесс обрабатывает «сырую» базу данных по трафику, которая содержит пары IP адресов и количество прошедших пакетов вместе с временной отметкой.
На входе в систему трафик поступает также в межсетевой экран операционной системы, правила фильтрации которому задает программное обеспечение сервера на основании целого ряда условий, указываемых для пользователя.
Межсетевой экран используется не только для предотвращения несанкционированного доступа извне, но и для управления правами самих пользователей корпоративной сети.
Для управления межсетевым экраном сервер контроля корпоративного Интернет доступа используют готовые блоки правил, которые подключаются и отключаются из пользовательского интерфейса. Для удобства продвинутых пользователей может существовать возможность работать с правилами межсетевого экрана на уровне системных команд и индивидуальных правил.
Сервер электронной почты настраивается автоматически на заносимых в интерфейсе управления пользователей. После этого сервер становится способным принять на себя функции корпоративного сервера электронной почты.
Поскольку сервер контроля корпоративного Интернет доступа работает с IP трафиком, то для того, чтобы соотнести IP адрес получателя с пользователем ему необходимо проделать ряд дополнительных действий, если не используется самая простая авторизация пользователя по IP адресам. Во всех остальных случаях информация о текущем IP адресе пользователя получается от встроенных механизмов авторизации: серверов VPN (PPPoE и PPTP), контроллера домена под управлением Microsoft Windows Server, например, посредством механизма Samba [28].
Сервер контроля корпоративного Интернет доступа может также содержать в себе классический HTTP proxy сервер, что позволяет ему отслеживать обращения пользователей к конкретным веб ресурсам (т.е. не ограничиваться ведением статистики только по IP адресам), а также управлять доступом к ресурсам Интернет помимо IP адресов также и по URL объектов. Кроме того, такой сервер сможет осуществлять кэширование содержимого веб - страниц и тем самым поспособствует снижению потребления веб трафика клиентом.
Для управления правами доступа пользователей к внешним ресурсам сервер использует данные по учет потребления трафика пользователями, которые обновляются практически в реальном времени, информацию по настроенным для пользователя лимитам на потребление услуг (в объемном или денежном выражении), а также данные по наличию средств на лицевом счете пользователя. Вся эта информация используется управляющим процессом сервера для динамического внесения изменений в настройки межсетевого экрана в ядре операционной системы, Squid прокси - сервера и SMTP сервера.
1.9 Пример простой системы контроля и учета трафика
У многих начинающих системных администраторов часто стоит вопрос организации системы контроля и учета трафика. Простая система контроля и учета трафика, должна отвечать следующими требованиям:
– Учет всего трафика проходящего через маршрутизатор работающий под ОС Linux;
– Возможностью быстрого изменения конфигурации без внесения изменений в код;
– Данные о трафике должны храниться в базе данных, в нашем случае мы в качестве сервера баз данных будем использовать MySQL.
Начнем с создания конфигурационного файла, назовем его billing.conf. Пусть он имеет следующий вид:
<******* billing.conf **************>
# Формируем список IP адресов машин или сетей, для которых мы будем считать
# трафик
# Рабочее место
WS1='192.168.0.1'
# Ceть нашего клиента
NET='192.168.1.0/24'
# Объединим все сети и адреса в один список.
ALLNETS='$WS1 $NET'
<**********************************>
В принципе формировать списки для каждого адреса или сети нет необходимости, т.к. рассматриваемая система использует только список ALLNETS, однако они могут понадобиться, в случае если нужно будет обрабатывать статистику о каждом пользователе.
Данный конфигурационный файл является единой для всей системы, состоящей как минимум из трех программ:
– Программы формирования правил учета для firewall, с использованием iptables;
– Программы снятия статистики;
– Программы отображения статистики;
Программа формирования правил учета для firewall, названная rc.firewall, которую нужно будет добавлять в один из файлов, который будет выполняться при загрузке системы. В ядрах Linux серии 2.4.X используется firewall NetFilter интерфейсом к которому является программа iptables. В NetFilter существуют несколько цепочек: INPUT - все входящие пакеты, адресованные маршрутизатору, OUTPUT - все исходящие из маршрутизатора пакеты, FORWARD - все пересланные маршрутизатором пакеты во внешнюю сеть.
<******* rc.firewall **************>
#!/bin/bash
# Подключаем конфигурационный файл
. /etc/lbiling.conf
IPTABLES='/sbin/iptables' # Задаем путь к программе iptables
###################################
# Учет трафика
###################################
# Функция для создания правила учета
addrule(){
$IPTABLES -N ACCT_IN_$1 # Создаем правило для учета входящего трафика
$IPTABLES -N ACCT_OUT_$1 # Создаем правило для учета исходящего трафика
$IPTABLES -F ACCT_IN_$1 # Обнулим полученные цепочки
$IPTABLES -F ACCT_OUT_$1
$IPTABLES -A INPUT -j ACCT_IN_$1 # Включим учет по цепочкам
$IPTABLES -A FORWARD -j ACCT_IN_$1
$IPTABLES -A FORWARD -j ACCT_OUT_$1
$IPTABLES -A OUTPUT -j ACCT_OUT_$1
$IPTABLES -A ACCT_IN_$1 -s $2 # Считать входящим трафик у которого источник
# адрес $2
$IPTABLES -A ACCT_OUT_$1 -d $2 # Считать исходящим трафик у которого получатель
# адрес $2
}
# Создаем правила для учета трафика
for NET in $ALLNETS; do
# Для всех сетей в списке $ALLNET создать правила учета трафика
addrule $NET $NET
done
<**********************************>
После программы rc.firewall, набрав в консоле:
# iptables -L
Отобразится нечто подобное:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCT_IN_192.168.0.1 all -- anywhere anywhere
ACCT_IN_192.168.1.0/24 all -- anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCT_IN_192.168.0.1 all -- anywhere anywhere
ACCT_OUT_192.168.0.1 all -- anywhere anywhere
ACCT_IN_192.168.1.0/24 all -- anywhere anywhere
ACCT_OUT_192.168.1.0/24 all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCT_OUT_192.168.0.1 all -- anywhere anywhere
ACCT_OUT_192.168.1.0/24 all -- anywhere anywhere
Chain ACCT_IN_192.168.0.1 (2 references)
target prot opt source destination
all -- 192.168.0.1 anywhere
Chain ACCT_IN_192.168.1.0/24 (2 references)
target prot opt source destination
all -- 192.168.1.0/24 anywhere
Chain ACCT_OUT_192.168.0.1 (2 references)
target prot opt source destination
all -- anywhere 192.168.0.1
Chain ACCT_OUT_192.168.1.0/24 (2 references)
target prot opt source destination
all -- anywhere 192.168.1.0/24
Создадим базу данных в MySQL с названием trafficbd, для этого необходимо будет выполнить следующий SQL запрос:
<********* База данных trafficbd.sql *****>
CREATE DATABASE IF NOT EXISTS trafficbd;
use trafficbd;
#
# Структура таблицы `traffic`
#
CREATE TABLE traffic (
id int(11) NOT NULL auto_increment,
date datetime NOT NULL default '0000-00-00 00:00:00',
ip varchar(20) NOT NULL default '',
inb int(11) NOT NULL default '0',
outb int(11) NOT NULL default '0',
KEY id (id)
) TYPE=MyISAM;
<**********************************>
Теперь используем код программы, которая снимает полученную статистику, заносит её в базу данных и после этого обнуляет счетчики.
<**********************************>
#!/usr/bin/perl
# Функция занимающаяся сбором и внесением данных в БД.
sub account{
$name=$_[0]; # Имя правила
$IP_IN=0; # Инициализация счетчиков
$IP_OUT=0;
# Командная строка MySQL для внесения данных в таблицу.
$mysqlcommand='/usr/bin/mysql -hlocalhost trafficbd -e';
# Снимем данные со счетчика входящего трафика и обнулим
$ipstuff=`/sbin/iptables -L -Z ACCT_IN_$name -v -x`;
# Выделим из вывода предыдущей команды значение счетчика
@IPTBMASS=split(/n/,$ipstuff);
chomp $IPTBMASS[2];
$string=$IPTBMASS[2];
$string=~ s/s{1,}/ /g;
@INFOMASS=split(/ /,$string);
$IP_IN=$INFOMASS[2];
# Снимем данные со счетчика исходящего трафика и обнулим
$ipstuff=`/sbin/iptables -L -Z ACCT_OUT_$name -v -x`;
# Выделим из вывода предыдущей команды значение счетчика
@IPTBMASS=split(/n/,$ipstuff);
$string=$IPTBMASS[2];
$string=~ s/s{1,}/ /g;
@INFOMASS2=split(/ /,$string);
$IP_OUT=$INFOMASS2[2];
# Получим текущее время
($min, $hours, $day, $mounth,$year) = (localtime)[1,2,3,4,5];
$time=$hours.':'.$min.':00';
$mounth=$mounth+1;
$year=$year+1900;
$date=$year.'-'.$mounth.'-'.$day;
# Формируем SQL запрос
$sql='insert into traffic values('',''.$date.' '.$time.'',''.$name.'',''.$IP_IN.'',''.$IP_OUT.'');';
# Выполняем его
`$mysqlcommand '$sql'`;
} # На этом функция account заканчивается:)
# Основая программа
$config=`./lconfreader.sh`; # Прочитаем конфигурационный файл.
# Ниже приводится текст скрипта lconfreader.sh:
# #!/bin/bash
# . ./lbiling.conf # Включить конфигурационный файл
# echo $ALLNETS # Вывести в stdout список всех сетей, по которым ведется учет
chomp $config;
@NETMASS=split(/ /,$config);
foreach $nets(@NETMASS)
# Для каждого элемента списка, выполнить функцию account
account $nets [29];
2. Проектная часть
2.1 Среда программирования «Delphi 7»
Среда программирования «Delphi 7» была выбрана потому что, она имеет специфику создания приложений абсолютно любого направления и сложности на доступном языке Object Pascal
«Delphi 7» - это введение новых технологий, облегчающих и упрощающих создание программ для баз данных и Интернета.
Речь идёт, прежде всего, об инструменте CASE (Computing Assisted Software Engineering - средство автоматизированного программирования) под названием ModalMaker. Задача ModalMaker традиционна для средств подобного рода. Он позволяет программисту сосредоточиться на решении смысловых задач, возложив на ModalMaker всю черновую работу. Существенно изменены технологии создания приложений для Интернета.
С помощью нового набора компонентов IntraWeb можно готовить приложения, которые не будут требовать обязательного посредничества Web-сервера между созданным вами приложением и браузером пользователя (только для режима Stand Alone Application; для остальных типов приложений наличие промышленных серверов обязательно). Введена поддержка промышленного сервера «Apache 2». Устранены любые отличия в версиях языка «Delphi» для собственно «Delphi 7» и «Kylix 3», что в ещё большей степени упрощает процесс создания кроссплатформенных приложений. Однако попытка унификации VCL и CLX привела к тому, что из VCL исчезли компоненты Quick Report и Fast Net, которые следует заменять компонентами вкладок Rave и Indy.Если не считать небольших изменений среды разработчика, библиотеки компонентов и т.п., то следует признать, что основная нацеленность версии - улучшенная поддержка кроссплатформенных приложений (в режиме разработки кроссплатформенных приложений на 21 вкладке помещаются 274 компонента против 211 предыдущей версии), а также введение CASE-средств.
Программист использует специальное окно, которое называется окном формы, как прототип будущего окна программы и наполняет его компонентами, реализующими нужные интерфейсные свойства (списки, кнопки, полосы прокрутки и так далее). Библиотека визуальных компонентов представляет программисту огромное разнообразие созданных разработчиками «Delphi» программных заготовок, которые немедленно или после несложной настройки готовы к работе в рамках вашей программы.
Использование компонентов не только во много раз уменьшает сроки разработки программ, но и существенно снижает вероятность случайных программных ошибок, от которых, увы, не защищён ни один крупный программный проект. В результате даже не сложные программы, созданные в «Delphi», редко имеют объём меньше сотен килобайт [8].
2.2 Структура программ Delphi
Любая программа в Delphi состоит из файла проекта (файл с расширением dpr) и одного или нескольких модулей (файлы с расширениями pas). Каждый из таких файлов описывает программную единицу Object Pascal.
Структура проекта
Файл проекта представляет собой программу, написанную на языке Object Pascal и предназначенную для обработки компилятором. Эта программа автоматически создается Delphi и содержит лишь несколько строк. Чтобы увидеть их, запустите Delphi и щелкнуть по опции Project | View Source главного меню.
Delphi покажет окно кода с закладкой Project1, содержащее такой текст:
program Projecti;
uses
Forms, Unit1 in 'Unit1.pas' {fmExample};
{$R *.RES}
Begin
Application.Initialize;
Application.CreateForm(TfmExample, fmExample);
Application.Run;
end.
В окне кода жирным шрифтом выделяются так называемые зарезервированные слова, а курсивом - комментарии. Текст программы начинается зарезервированным словом program и заканчивается словом end с точкой за ним. Сочетание end со следующей за ней точкой называется терминатором программной единицы: как только в тексте программы встретится такой терминатор, компилятор прекращает анализ программы и игнорирует оставшуюся часть текста.
Зарезервированные слова играют важную роль в Object Pascal, придавая программе в целом свойство текста, написанного на почти естественном английском языке. Каждое зарезервированное слово (а их в Object Pascal несколько десятков) несет в себе условное сообщение для компилятора, который анализирует текст программы слева направо и сверху вниз.
Комментарии, наоборот, ничего не значат для компилятора, и он их игнорирует. Комментарии важны для программиста, который с их помощью поясняет те или иные места программы. Наличие комментариев в тексте программы делает ее понятнее и позволяет легко вспомнить особенности реализации программы, которую вы написали несколько лет назад. В Object Pascal комментарием считается любая последовательность символов, заключенная в фигурные скобки. В приведенном выше тексте таких комментариев два, но строка
{$R *.RES}
на самом деле не является комментарием. Этот специальным образом написанный фрагмент кода называется директивой компилятора (в нашем случае - указание компилятору на необходимость подключения к программе так называемого файла ресурсов). Директивы начинаются символом $, который стоит сразу за открывающей фигурной скобкой.
В Object Pascal в качестве ограничителей комментария могут также использоваться пары символов (*, *) и //. Скобки (*...*) используются подобно фигурным скобкам т. е. комментарием считается находящийся в них фрагмент текста, а символы // указывают компилятору, что комментарий располагается за ними и продолжается до конца текущей строки:
{Это комментарий}
(*Это тоже комментарий*)
//Все символы до конца этой строки составляют комментарий
Слово Program со следующим за ним именем программы и точкой с запятой образуют заголовок программы. За заголовком следует раздел описаний, в котором программист (или Delphi) описывает используемые в программе идентификаторы. Идентификаторы обозначают элементы программы, такие как типы, переменные, процедуры, функции. Здесь же с помощью предложения, которое начинается зарезервированным словом uses (использовать) программист сообщает компилятору о тех фрагментах программы (модулях), которые необходимо рассматривать как неотъемлемые составные части программы и которые располагаются в других файлах. Строки
Uses
Forms, Unit1 in 'Unitl.pas' {fmExample};
указывают, что помимо файла проекта в программе должны использоваться модули Forms И Unit1. модуль Forms является стандартным (т. е. уже известным Delphi), а модуль Unit1 - новым, ранее неизвестным, и Delphi в этом случае указывает также имя файла с текстом модуля (in 'uniti.pas') и имя связанного с модулем файла описания формы {fmExample}.
Собственно тело программы начинается со слова begin (начать) и ограничивается терминатором end с точкой. Тело состоит из нескольких операторов языка Object Pascal. В каждом операторе реализуется некоторое действие - изменение значения переменной, анализ результата вычисления, обращение к подпрограмме и т. п. В теле нашей программы - три исполняемых оператора:
Application.Initialize;
Application.CreateForm(TfmExample, fmExample);
Application.Run;
Каждый из них реализует обращение к одному из методов объекта Application. Объектом называется специальным образом оформленный фрагмент программы, заключающий в себе данные и подпрограммы для их обработки. Данные называются полями объекта, а подпрограммы - его методами. Объект в целом предназначен для решения какой-либо конкретной задачи и воспринимается в программе как неделимое целое (иными словами, нельзя из объекта “выдернуть” отдельное поле или метод). Объекты играют чрезвычайно важную роль в современных языках программирования. Они придуманы для того, чтобы увеличить производительность труда программиста и одновременно повысить качество разрабатываемых им программ.
Два главных свойства объекта - функциональность и неделимость - делают его самостоятельной или даже самодостаточной частью программы и позволяют легко переносить объект из одной программы в другую. Разработчики Delphi придумали сотни объектов, которые можно рассматривать как кирпичики, из которых программист строит многоэтажное здание программы. Такой принцип построения программ называется объектно-ориентированным программированием (ООП). В объекте Application собраны данные и подпрограммы, необходимые для нормального функционирования Windows-программы в целом. Delphi автоматически создает объект-программу Application для каждого нового проекта.
Строка
Application.Initialize;
означает обращение к методу Initialize объекта Application. Прочитав эту строку, компилятор создаст код, который заставит процессор перейти к выполнению некоторого фрагмента программы, написанного для нас разработчиками Delphi.
После выполнения этого фрагмента (программисты говорят: после выхода из подпрограммы) управление процессором перейдет к следующей строке программы, в которой вызывается метод CreateForm и т. д.[21].
2.3 Структура модуля
Модули - это программные единицы, предназначенные для размещений фрагментов программ. С помощью содержащегося в них программного кода реализуется вся поведенческая сторона программы. Любой модуль имеет следующую структуру: заголовок секция интерфейсных объявлений секция реализации терминатор Заголовок открывается зарезервированным словом Unit за которым следует имя модуля и точка с запятой. Секция интерфейсных объявлений открывается зарезервированным словом Interface, a секция реализации - словом implementation. Терминатором модуля, как и терминатором программы, является end с точкой. Следующий фрагмент программы является синтаксически правильным вариантом модуля:
unit Unit1;
interface
// Секция интерфейсных объявлений
Implementation
// Секция реализации
end.
В секции интерфейсных объявлений описываются программные элементы (типы, классы, процедуры и функции), которые будут “видны” другим программным модулям, а в секции реализации раскрывается механизм работы этих элементов. Разделение модуля на две секции обеспечивает удобный механизм обмена алгоритмами между отдельными частями одной программы. Он также реализует средство обмена программными разработками между отдельными программистами. Получив откомпилированный “посторонний” модуль, программист получает доступ только к его интерфейсной части, в которой, как уже говорилось, содержатся объявления элементов. Детали реализации объявленных процедур, функций, классов скрыты в секции реализации и недоступны другим модулям.
Щелкнув по закладке Unit1 окна кода, можно увидеть такой текст:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Buttons, ExtCtrls;
Type
TfmExample = class(TForm)
Panel1: TPanel;
bbRun: TBitBtn;
bbClose: TBitBtn;
edinput: TEdit;
IbOutput: TLabel;
mmOutput: TMemo;
private
{ Private declarations } public
{ Public declarations } end;
Var
fmExample: TfmExample;
implementation
$R *.DFM}
end.
Весь этот текст сформирован Delphi, но в отличие от файла проекта программист может его изменять, придавая программе нужную функциональность. В интерфейсной секции описан один тип (класс - fmExample) и один объект (переменная fmExample).
Вот описание класса:
Type
TfmExample = class(TForm)
Panell: TPanel;
bbRun: TBitBtn;
bbClose: TBitBtn;
edinput: TEdit;
IbOutput: TLabel;
mmOutput: TMemo;
private
{ Private declarations } public
{ Public declarations } end;
Классы служат основным инструментом реализации мощных возможностей Delphi. Класс является образцом, по которому создаются объекты, и наоборот, объект - это экземпляр реализации класса. Образцы для создания элементов программы в Object Pascal называются типами, таким образом, класс TfmExamplel -это тип. Перед его объявлением стоит зарезервированное слово type (тип), извещающее компилятор о начале раздела описания типов.
Стандартный класс TForm реализует все нужное для создания и функционирования пустого Windows-окна. Класс TfmExamplel порожден от этого класса, о чем свидетельствует строка
TfmExample = class(TForm)
в которой за зарезервированным словом class в скобках указывается имя родительского класса. Термин “порожден” означает, что класс TfmExample унаследовал все возможности родительского класса TForm и добавил к ним собственные в виде дополнительных компонентов, которые, вставлены в форму fmExample. Перечень вставленных компонентов и составляет значительную часть описания класса.
Свойство наследования классами-потомками всех свойств родительского класса и обогащения их новыми возможностями является одним из фундаментальных принципов объектно-ориентированного программирования. От наследника может быть порожден новый наследник, который внесет свою лепту в виде дополнительных программных заготовок и т. д.
В результате создается ветвящаяся иерархия классов, на вершине которой располагается самый простой класс TObject (все остальные классы в Delphi порождены от этого единственного прародителя), а на самой нижней ступени иерархии - мощные классы-потомки, которым по плечу решение любых проблем.
Объект fmExampie формально относится к элементам программы, которые называются переменными. Вот почему перед объявлением объекта стоит зарезервированное слово var (от англ. variables - переменные).
Текст модуля доступен как Delphi ,так и программисту. Delphi автоматически вставляет в текст модуля описание любого добавленного к форме компонента, а также создает заготовки для обработчиков событии; программист может добавлять свои методы в ранее объявлённые классыйнаполвять обработчики событий конкретным .содержа,нием, вставлять собственные переменные, типы, константы и т. д. Совместное с Delphi владение текстом модуля будет вполне успешным, если программист будет соблюдать простое правило , он не должен удалять или изменять строки которые вставлены не им, а Delphi. [21].
2.4 Элементы программы
Элементы программы - это минимальные неделимые ее части, еще несущие в себе определенную значимость для компилятора. К элементам относятся:
- зарезервированные слова;
- идентификаторы;
- типы;
- константы;
- переменные;
- метки;
- подпрограммы;
- комментарии.
Зарезервированные слова это английские слова, указывающие компилятору на необходимость выполнения определенных действий. Зарезервированные слова не могут использоваться в программе ни для каких иных целей кроме тех, для которых они предназначены. Например, зарезервированное слово begin означает для компилятора начало составного оператора. Программист не может создать в программе переменную с именем begin, константу begin, метку begin или вообще какой бы то ни было другой элемент программы с именем begin.
Идентификаторы - это слова, которыми программист обозначает любой другой элемент программы, кроме зарезервированного слова, идентификатора или комментария. Идентификаторы в Object Pascal могут состоять из латинских букв, арабских цифр и знака подчеркивания. Никакие другие символы или специальные знаки не могут входить в идентификатор. Из этого простого правила следует, что идентификаторы не могут состоять из нескольких слов (нельзя использовать пробел) или включать в себя символы кириллицы (русского алфавита).
Типы - это специальные конструкции языка, которые рассматриваются компилятором как образцы для создания других элементов программы, таких как переменные, константы и функции. Любой тип определяет две важные для компилятора вещи: объем памяти, выделяемый для размещения элемента (константы, переменной или результата, возвращаемого функцией), и набор допустимых действий, которые программист может совершать над элементами данного типа. Замечу, что любой определяемый программистом идентификатор должен быть описан в разделе описаний (перед началом исполняемых операторов). Это означает, что компилятор должен знать тот тип (образец), по которому создается определяемый идентификатором элемент.
Константы определяют области памяти, которые не могут изменять своего значения в ходе работы программы. Как и любые другие элементы программы, константы могут иметь свои собственные имена. Объявлению имен констант должно предшествовать зарезервированное слово const (от англ. constants - константы). Например, мы можем определить константы
Const
Kbyte = 1024;
Mbyte = Kbyte*Kbyte;
Gbyte = 1024*Mbyte;
чтобы вместо длинных чисел
1048576 (1024*1024) и 1073741824
(1024*1024*1024) писать, соответственно, Mbyte и Gbyte. Тип константы определяется способом ее записи и легко распознается компилятором в тексте программы, поэтому программист может не использовать именованные константы (т. е. не объявлять их в программе явно).
Переменные связаны с изменяемыми областями памяти, т. е. с такими ее участками, содержимое которых будет меняться в ходе работы программы. В отличие от констант переменные всегда объявляются в программе. Для этого после идентификатора переменной ставится двоеточие и имя типа, по образу которого должна строиться переменная. Разделу объявления переменной (переменных) должно предшествовать слово var. Например:
Var
inValue: Integer;
byValue: Byte;
Здесь идентификатор inValue объявляется как переменная типа integer, а идентификатор byValue - как переменная типа Byte. Стандартный (т. е. заранее определенный в Object Pascal) тип integer определяет четырехбайтный участок памяти, содержимое которого рассматривается как целое число в диапазоне от -2 147 483 648 до+2 147 483 647, а стандартный тип Byte - участок памяти длиной 1 байт, в котором размещается беззнаковое целое число в диапазоне от 0 до 2554.Все сведения относительно диапазона возможных значений и объема памяти стандартных типов относятся к Delphi 32. Для 16-разрядной версии 1 эти величины имеют другие значения, например, тип Integer в версии 1 занимает 2 байта и имеет диапазон значении от -32 768 до+32 767.
Метки - это имена операторов программы. Метки используются очень редко и только для того, чтобы программист смог указать компилятору, какой оператор программы должен выполнятся следующим. Метки, как и переменные, всегда объявляются в программе. Разделу объявлений меток предшествует зарезервированное слово label (метка). Например:
Label
Loop;
Begin
Goto Loop;
// Программист требует передать управление
// оператору, помеченному меткой Loop. .....
// Эти операторы будут пропущены
Loор:
// Оператору, идущему за этой меткой,
.....
// будет передано управление
end;
Подпрограммы - это специальным образом оформленные фрагменты программы. Замечательной особенностью подпрограмм является их значительная независимость от остального текста программы. Говорят, что свойства подпрограммы локализуются в ее теле. Это означает, что, если программист что-либо изменит в подпрограмме, ему, как правило, не понадобится в связи с этим изменять что-либо вне подпрограммы. Таким образом, подпрограммы являются средством структурирования программ, т. е. расчленения программ на ряд во многом независимых фрагментов. Структурирование неизбежно для крупных программных проектов, поэтому подпрограммы используются в Delphi-программах очень часто.
В Object Pascal есть два вида подпрограмм: процедуры и функции. Функция отличается от процедуры только тем, что ее идентификатор можно наряду с константами и переменными использовать в выражениях, т. к. функция имеет выходной результат определенного типа. Если, например, определена функция
Function MyFunction: Integer;
и переменная var
X: Integer;
то возможен такой оператор присваивания:
Х := 2*MyFunction-l;
Имя процедуры нельзя использовать в выражении, т. к. процедура не имеет связанного с нею результата:
Procedure MyProcedure;
…
X := 2*MyProcedure-l; // Ошибка!
2.5 Типы данных
Типы в Object Pascal играют огромную роль. Связано это с тем, что лежащий в его основе язык Pascal был специально придуман как средство обучения студентов программированию. Поскольку начинающий программист легко может допустить ошибку или неточно описать свои действия, компилятор Pascal должен был иметь средства контроля за действиями программиста, чтобы вовремя предостеречь его от последствий неверных действий. Первоначально типы как раз и предназначались для того, чтобы программист явно указывал компилятору, какого размера память нужна ему в программе и что он собирается делать с этой памятью. Практика применения типов показала их высокую эффективность для защиты программы от случайных ошибок, так что практически все современные языки программирования в той или иной степени реализуют механизм типов. В Object Pascal значение типов возросло в еще большей степени, т. к. с их помощью определяются классы - основной инструмент программиста.
Свое знакомство с типами можно начать со строкового типа String. Этот тип определяет участок памяти переменной длины, каждый байт которого содержит один символ. Для символов в Object Pascal используется тип Char, таким образом, String - это цепочка следующих друг за другом символов Char. Каждый символ в String пронумерован, причем первый символ имеет номер 1. Программист может обращаться к любому символу строки, указывая его порядковый номер в квадратных скобках сразу за именем переменной:
var // Начало раздела описания переменных
S: String;
// Объявление переменной строкового типа
Begin
// Начало раздела исполняемых операторов
S := 'Строка символов';
// Переменная S содержит
// значение ”Строка символов”
S[6] := 'и'; // Теперь переменная содержит значение
// ”Строки символов”
end;
// Конец раздела исполняемых операторов
Программист обязан объявить любой вводимый им идентификатор. Идентификатор s неизвестен Delphi - он введен нами для переменной строкового типа. После его объявления в разделе переменных Delphi выделит для него начальную область памяти минимальной длины и будет контролировать использование этого идентификатора в разделе исполняемых операторов. Например, если в этом разделе встретится выражение
2*S-1
компилятор сразу забьет тревогу, так как строка не может быть участником математических вычислений: она предназначена для хранения символов, а не чисел.
В первом операторе присваивания в переменную s будет помещено значение строковой константы строка символов'. Строковые константы содержат произвольные символы, заключенные в обрамляющие апострофы, причем сами апострофы не входят в значение константы, поэтому после присваивания переменная примет значение Строка символов без апострофов (если понадобится включить в текстовую константу апостроф, он удваивается: ' символ ' ' - апостроф'). После первого присваивания s будет занимать участок памяти длиной 15 байт - по одному байту на каждый символ значения. На самом деле переменная строкового типа всегда имеет длину 4 байта, которые используются для указания на область памяти, в которой помещается сама строка символов. Переменность размера области памяти, выделяемой для размещения строки символов, - характерная особенность типа string. Если бы, например, во втором операторе мы обратились не к 6-му по счету символу, а ко всей строке в целом:
S := 'и';
эта переменная стала бы занимать 1 байт, а следующие за ним 14 байтов оказались бы свободными. Длина строковой переменной в программе меняется автоматически при каждом присваивании переменной нового значения и может составлять от 0 до 2 Гбайт[Для версии Delphi 1 тип String соответствует “короткой” строке, длина которой не может превышать 255 байт.] (1 Гигабайт (Гбайт) соответствует константе Gbyte). Над строковым типом определена операция сцепления (+):
S := 'Object'+' Pascal';// S содержит “Object Pascal” .[21].
2.6 Описание пользовательского интерфейса
От множества программ по контролю трафика, «Автоматизированную систему контроля трафика ЛВС» отличает бесплатный статус. Кроме этого, программа имеет еще одно достоинство - русскоязычный интерфейс, который способствует ее быстрому освоению. «Автоматизированная система контроля трафика ЛВС» имеет простой, интересный и понятный пользователю любого уровня интерфейс.
Программа «Автоматизированная система контроля трафика ЛВС» имеет очень быструю загрузку, совместима со всеми версиями Windows. Также программа отображает:
- Адаптер с помощью которого устройство подключено к сети.
- MAC - Адрес устройства.
- Скорость передачи данных.
- Фиксирует дату, время и продолжительность работы программы.
- Программа посчитывает входящий и исходящий трафик, определяя пик загруженности сети, среднее количество преданной/принятой информации, и её общее количество.
- Программа имеет удобные вкладки, на которых отображаются IP - Адреса.
- Программный продукт имеет функцию отображения поверх всех окон.
Функциональные возможности программы реализованы с помощью следующих режимов:
- «Заморозить» - для заморозки подключения программы.
- «Разморозить» - Для разморозки подключения.
- «Отчистить» - для обнуления всех полей программы.
- «Выход» - для выхода из программы.
Одно из основных достоинств программного продукта «Автоматизированная система контроля трафика ЛВС», это минимальные системные требования:
- Операционная система Windows 98
- Оперативная память 64 MB
- Видеокарта 32 MB
- Требуемое свободное место на жестком диске 5 MB
- Оптические устройства Клавиатура, мышь.
В данное время программа «Автоматизированная система контроля трафика ЛВС» имеет большую актуальность, в связи с распространением локальных и интернет сетей.
Данный программный продукт имеет универсальный характер применения для предприятий с Интернет - подключением или использованием локальной сети. Так же программа имеет уровень защищённости, т.е. сбои при учёте трафика невозможны или сведены к минимуму. Программа может получить большое распространение в связи с бесплатным статусом, а также имеет открытый исходный код, поэтому любой квалифицированный пользователь в состоянии адаптировать программу к ряду функций. которые имеют для него более высокий приоритет. При создании программного продукта «Автоматизированная система контроля трафика ЛВС» была использована операционная система Linux, поскольку она использует открытый исходный код позволяющий адаптировать ряд функций операционной системы под индивидуальность пользователя, в отличии от операционной системой Windows. Данный программный продукт сочетает в себе все выше перечисленные функции, воплощая в себе вариант открытой и доступной программы, рассчитанной на квалифицированного пользователя.
Приложение «Автоматизированная система контроля трафика ЛВС Client version» предназначено для контроля и учёта входящего и исходящего трафиков локальной вычислительной сети. При двойном щелчке по ярлыку программы открывается приветственное окно представленное на рисунке 1.
Рисунок 1. Приветственное окно программы
Далее открывается основная форма приложения, которая имеет 3 вкладки:
– Мониторинг трафика представленный на рисунке 2.
– Соединение представленный на рисунке 3.
– О программе представленный на рисунке 4.
Рисунок 2. Мониторинг трафика
Рисунок 3. Соединение
Рисунок 4. О программе
Приложение «Автоматизированная система контроля трафика ЛВС Server version» предназначено для приёма и сбора информации о клиентах, контроля и учёта входящего и исходящего трафика локальной вычислительной сети. При двойном щелчке по ярлыку программы открывается приветственное окно представленное на рисунке 5.
Рис 5. Приветственное окно программы
Далее открывается основная форма приложения, которая имеет 3 вкладки:
– Мониторинг, представлена на рисунке 6.
– График, представлена на рисунке 7.
– О программе, представлена на рисунке 8.
Рисунок 6. Мониторинг сети
Рисунок 7. Графическое представление трафиков
Рис 8. О программе
2.7 Описание программных модулей
2.7.1 Описание модуля Unit1
Модуль Unit1 служит для отображения приветственного окна (Листинг 1).
Листинг 1.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls;
type
Tlogo = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
logo: Tlogo;
implementation
{$R *.dfm}
procedure Tlogo.FormCreate(Sender: TObject);
begin
Position:=poScreenCenter;
FormStyle:=fsStayOnTop;
BorderStyle:=bsNone;
BorderIcons:=[];
end;
end.
2.7.2 Описание модуля TrafficUnit
Модуль TrafficUnit предназначен для учёта входящего и исходящего трафиков ( Листинг 2).
Листинг 2.
unit TrafficUnit;
interface
uses SysUtils, Windows, IPHelper, IPHLPAPI;
type
TTraffic = Class;
TNewInstanceEvent = procedure(Sender :TTraffic) of object;
TFreezeEvent = procedure(Sender :TTraffic) of object;
TTraffic = Class
private
FIP: string;
FMac: string;
FInPerSec: Dword;
FInTotal: Dword;
FPeakInPerSec: Dword;
FInterfaceIndex: DWord;
FActiveCountIn: Dword;
FSecondsActive: Cardinal;
FPrevCountIn: DWord;
FDescription: string;
FOutTotal: Dword;
FPeakOutPerSec: Dword;
FOutPerSec: Dword;
FPrevCountOut: DWord;
FActiveCountOut: Dword;
FAverageInPerSec: Dword;
FAverageOutPerSec: Dword;
FStartedAt: TDateTime;
FRunning: boolean;
FOnFreeze: TFreezeEvent;
FOnUnFreeze: TFreezeEvent;
FConnected: boolean;
FFound: boolean;
FSpeed: DWord;
function GetIPFromIFIndex(InterfaceIndex: Cardinal): string;
public
property Found : boolean read FFound write FFound;
property Connected : boolean read FConnected;
property Running : boolean read FRunning;
property InterfaceIndex : DWord read FInterfaceIndex;
property IP : string read FIP;
property Mac : string read FMac;
property Description : string read FDescription;
property StartedAt : TDateTime read FStartedAt;
property SecondsActive : Cardinal read FSecondsActive;
property Speed : DWord read FSpeed;
property ActiveCountIn : Dword read FActiveCountIn; { count of samples where something was received }
property PrevCountIn : DWord read FPrevCountIn; { previous byte count in }
property InPerSec : Dword read FInPerSec; { byte count in of last sample period }
property AverageInPerSec : Dword read FAverageInPerSec; { Average in }
property InTotal : Dword read FInTotal; { total byte count in }
property PeakInPerSec : Dword read FPeakInPerSec; { peak byte count in }
property ActiveCountOut : Dword read FActiveCountOut; { count of samples where something was sent }
property PrevCountOut : DWord read FPrevCountOut; { previous byte count out }
property OutPerSec : Dword read FOutPerSec; { byte count out of last sample period }
property AverageOutPerSec : Dword read FAverageOutPerSec; { Average Out }
property OutTotal : Dword read FOutTotal; { total byte count out }
property PeakOutPerSec : Dword read FPeakOutPerSec; { peak byte count out }
procedure NewCycle(const InOctets, OutOctets, TrafficSpeed : Dword);
procedure Reset;
procedure Freeze;
procedure UnFreeze;
procedure MarkDisconnected;
function GetStatus : string;
function FriendlyRunningTime:string;
constructor Create(const AMibIfRow : TMibIfRow; OnNewInstance : TNewInstanceEvent);
published
property OnFreeze :TFreezeEvent read FOnFreeze write FOnFreeze;
property OnUnFreeze :TFreezeEvent read FOnUnFreeze write FOnUnFreeze;
end;
function BytesToFriendlyString(Value : DWord) : string;
function BitsToFriendlyString(Value : DWord) : string;
implementation
function BytesToFriendlyString(Value : DWord) : string;
const
OneKB=1024;
OneMB=OneKB*1024;
OneGB=OneMB*1024;
begin
if Value<OneKB
then Result:=FormatFloat('#,##0.00 B',Value)
else
if Value<OneMB
then Result:=FormatFloat('#,##0.00 KB', Value/OneKB)
else
if Value<OneGB
then Result:=FormatFloat('#,##0.00 MB', Value/OneMB)
end;
function BitsToFriendlyString(Value : DWord) : string;
const
OneKB=1000;
OneMB=OneKB*1000;
OneGB=OneMB*1000;
begin
if Value<OneKB
then Result:=FormatFloat('#,##0.00 bps',Value)
else
if Value<OneMB
then Result:=FormatFloat('#,##0.00 Kbps', Value/OneKB)
else
if Value<OneGB
then Result:=FormatFloat('#,##0.00 Mbps', Value/OneMB)
end;
constructor TTraffic.Create(const AMibIfRow: TMibIfRow; OnNewInstance : TNewInstanceEvent);
var
Descr: string;
begin
inherited Create;
FRunning:=true;
FConnected:=true;
self.FInterfaceIndex:=AMibIfRow.dwIndex;
self.FIP:=GetIPFromIFIndex(self.InterfaceIndex);
self.FMac:=MacAddr2Str(TMacAddress(AMibIfRow.bPhysAddr), AMibIfRow.dwPhysAddrLen);
SetLength(Descr, Pred(AMibIfRow.dwDescrLen));
Move(AMibIfRow.bDescr, Descr[1], pred(AMibIfRow.dwDescrLen));
self.FDescription:=Trim(Descr);
self.FPrevCountIn:=AMibIfRow.dwInOctets;
self.FPrevCountOut:=AMibIfRow.dwOutOctets;
self.FStartedAt:=Now;
self.FSpeed:=AMibIfRow.dwSpeed;
FActiveCountIn:=0;
FActiveCountOut:=0;
FInTotal:=0;
FOutTotal:=0;
FInPerSec:=0;
FOutPerSec:=0;
FPeakInPerSec:=0;
FPeakOutPerSec:=0;
if Assigned(OnNewInstance)
then OnNewInstance(self);
end;
procedure TTraffic.NewCycle(const InOctets, OutOctets, TrafficSpeed: Dword);
begin
inc(self.FSecondsActive);
if not Running
then Exit;
FSpeed:=TrafficSpeed;
self.FInPerSec:=InOctets-self.PrevCountIn;
Inc(self.FInTotal, self.InPerSec);
if InPerSec>0
then Inc(FActiveCountIn);
if InPerSec>PeakInPerSec
then FPeakInPerSec:=InPerSec;
try
if ActiveCountIn<>0
then self.FAverageInPerSec:=InTotal div ActiveCountIn
except
self.FAverageInPerSec:=0;
end;
FPrevCountIn:=InOctets;
self.FOutPerSec:=OutOctets-self.PrevCountOut;
Inc(self.FOutTotal,self.OutPerSec);
if OutPerSec>0
then Inc(FActiveCountOut);
if OutPerSec>PeakOutPerSec
then FPeakOutPerSec:=OutPerSec;
try
if ActiveCountIn<>0
then self.FAverageOutPerSec:=OutTotal div ActiveCountOut
except
self.FAverageOutPerSec:=0;
end;
FPrevCountOut:=OutOctets;
end;
function TTraffic.GetIPFromIFIndex(InterfaceIndex: Cardinal): string;
var
i: integer;
IPArr: TMIBIPAddrArray;
begin
Result:='Not found!';
Get_IPAddrTableMIB(IpArr);
if Length(IPArr)>0
then
for i:=low(IPArr) to High(IPArr) do
if IPArr[i].dwIndex=InterfaceIndex
then
begin
Result:=IPAddr2Str(IParr[i].dwAddr);
Break;
end;
end;
procedure TTraffic.Reset;
begin
self.FPrevCountIn:=InPerSec;
self.FPrevCountOut:=OutPerSec;
self.FStartedAt:=Now;
FSecondsActive:=0;
FActiveCountIn:=0;
FActiveCountOut:=0;
FInTotal:=0;
FOutTotal:=0;
FInPerSec:=0;
FOutPerSec:=0;
FPeakInPerSec:=0;
FPeakOutPerSec:=0;
end;
procedure TTraffic.Freeze;
begin
FRunning:=false;
if Assigned(FOnFreeze)
then OnFreeze(Self);
end;
procedure TTraffic.UnFreeze;
begin
FRunning:=true;
if Assigned(FOnUnFreeze)
then OnUnFreeze(Self);
end;
procedure TTraffic.MarkDisconnected;
begin
self.FConnected:=false;
self.FRunning:=false;
end;
function TTraffic.GetStatus: string;
begin
if self.Connected
then Result:='Connected'
else Result:='Not connected';
if self.Running
then Result:=Result+', Running'
else Result:=Result+', Not running';
end;
function TTraffic.FriendlyRunningTime: string;
var
H,M,S: string;
ZH,ZM,ZS: integer;
begin
ZH:=SecondsActive div 3600;
ZM:=Integer(SecondsActive) div (60-ZH*60);
ZS:=Integer(SecondsActive)-(ZH*3600+ZM*60);
H:=Format('%.2d',[ZH]);
M:=Format('%.2d',[ZM]);
S:=Format('%.2d',[ZS]);
Result:=H+':'+M+':'+S;
end;
end.
2.7.3 Описание модуля MainFormUnit
Модуль MainFormUnit является главной формой клиентского приложения на которой производится контроль и учёт трафика (Листинг 3).
Листинг 3.
unit MainFormUnit;
interface
uses
Windows, Graphics, ExtCtrls, Controls, StdCtrls, Buttons, Tabs,
ComCtrls, Classes, SysUtils, Forms, Dialogs, Messages, Variants, ToolWin,
TrafficUnit, IPHelper, IPHLPAPI, ShellAPI, sSkinProvider, sSkinManager,
jpeg, Menus, TrayIcon, ScktComp;
type
TMainForm = class(TForm)
pnlMain: TPanel; - компонент панель
pnlBottom: TPanel; - компонент панель
pc: TPageControl; - компонент для создания вкладок
tsTraffic: TTabSheet; - вкладка
ExitButton: TButton; - кнопка выхода
TrafficTabs: TTabSet; - компонент отображения данных
GroupBox: TGroupBox; - компонент для создания группы элементов
ledAdapterDescription: TLabeledEdit; - компонент отображения данных
UnFreezeButton: TBitBtn; - кнопка
FreezeButton: TBitBtn; - кнопка
ClearCountersButton: TBitBtn; - кнопка
ledMACAddress: TLabeledEdit; - компонент отображения данных
gbIN: TGroupBox; - компонент для создания группы элементов
ledOctInSec: TLabeledEdit; - компонент отображения данных
ledAvgINSec: TLabeledEdit; - компонент отображения данных
ledPeakINSec: TLabeledEdit; - компонент отображения данных
ledTotalIN: TLabeledEdit; - компонент отображения данных
gbOUT: TGroupBox; - компонент для создания группы элементов
ledOctOUTSec: TLabeledEdit; - компонент отображения данных
ledAvgOUTSec: TLabeledEdit; - компонент отображения данных
ledPeakOUTSec: TLabeledEdit; - компонент отображения данных
ledTotalOUT: TLabeledEdit; - компонент отображения данных
Timer: TTimer; - компонент таймер
gbTime: TGroupBox; - компонент для создания группы элементов
ledStartedAt: TLabeledEdit; - компонент отображения данных
ledActiveFor: TLabeledEdit; - компонент отображения данных
RemoveInactiveButton: TBitBtn; - кнопка
StatusText: TStaticText; - компонент отображения данных
cbOnTop: TCheckBox; - компонент включения/отключения виде флажка
ledSpeed: TLabeledEdit; - компонент отображения данных
sSkinManager1: TsSkinManager; - компонент установки скинов
sSkinProvider1: TsSkinProvider; - компонент установки скинов
TabSheet1: TTabSheet; - вкладка
Panel1: TPanel; - компонент панель
Image1: TImage; - компонент для отображения изображения
Image2: TImage; - компонент для отображения изображения
Label1: TLabel; - метка
Label2: TLabel; - метка
Panel2: TPanel; - компонент панель
TrayIcon1: TTrayIcon; - компонент сворачивания в трей
PopupMenu1: TPopupMenu; - компонент меню
N1: TMenuItem; - вкладка меню
N2: TMenuItem; - вкладка меню
ClientSocket1: TClientSocket; - компонент обмена данными
TabSheet2: TTabSheet; - вкладка
Edit4: TEdit; - компонент отображения данных
Edit3: TEdit; - компонент отображения данных
Label3: TLabel; - метка
Label4: TLabel; - метка
Timer1: TTimer; - компонент таймер
ReConnect: TTimer; - компонент таймер
Label5: TLabel; - метка
Label6: TLabel; - метка
ListBox1: TListBox; - компонент отображения данных
ListBox2: TListBox; - компонент отображения данных
Label7: TLabel; - метка
Send: TTimer; - компонент таймер
Label8: TLabel; - метка
Image3: TImage; - компонент для отображения изображения
Label9: TLabel; - метка
procedure TrayIcon1Click(Sender: TObject); - процедура сворачивания в трей
procedure TimerTimer(Sender: TObject); - процедура передачи данных в заданное время
procedure ClearCountersButtonClick(Sender: TObject); - процедура отчистки данных
procedure cbOnTopClick(Sender: TObject); - процедура определяющая стиль формы
procedure FormDestroy(Sender: TObject); - процедура обнуления счётчиков
procedure TrafficTabsChange(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean); - прцедура добавления вкладки IP - адреса
procedure ExitButtonClick(Sender: TObject); - процедура выхода из программы
procedure FormCreate(Sender: TObject); - процедура обработки событий
procedure FreezeButtonClick(Sender: TObject); - процедура «заморозки» данных
procedure UnFreezeButtonClick(Sender: TObject); - процедура «разморозки» данных
procedure RemoveInactiveButtonClick(Sender: TObject); - процедура удаления данных
procedure ledAdapterDescriptionChange(Sender: TObject); -процедура получения адаптера
procedure N2Click(Sender: TObject); - процедура выхода из программы
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket); - процедура подключения к серверу
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); - процедура формирования пакета данных для отправки на сервер
procedure FormActivate(Sender: TObject); - процедура авторизации пользователя
procedure Timer1Timer(Sender: TObject); - процедура отправки данных по таймеру
procedure ReConnectTimer(Sender: TObject); - процедура переподключения к серверу
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer); - процедура ошибки подключения к серверу
procedure ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket); - процедура разъединения с сервером
procedure SendTimer(Sender: TObject); - процедура отправки данных по таймеру
private
procedure HandleNewAdapter(ATraffic : TTraffic); - процедура подключения нового адаптера
procedure HandleFreeze(ATraffic : TTraffic); - процедура «заморозки»
procedure HandleUnFreeze(ATraffic : TTraffic); - процедура «разморозки»
function LocateTraffic(AdapterIndex : DWord) : TTraffic; - процедура учета трафика
procedure ProcessMIBData; - процедура добавления данных о трафике
procedure ClearDisplay; - процедура отчистки данных
procedure RefreshDisplay; - процедура обнуления данных
public
{ Public declarations }
end;
var
MainForm: TMainForm;
ActiveTraffic : TTraffic;
CanCloseForm:boolean;
NewTab: Integer;
nick:string;
implementation
{$R *.dfm}
function GetCompName:string;
var Len:Cardinal; pStr:PChar;
begin pStr:=nil; Len:=256;
try pStr:=StrAlloc(Len);
if GetComputerName(pStr,Len) then
Result:=pStr; finally
if pStr<>nil then StrDispose(pStr); end;
end;
procedure TMainForm.ClearDisplay;
var
j:integer;
begin
TrafficTabs.Tabs.Clear;
StatusText.Caption:='';
for j:=0 to GroupBox.ControlCount-1 do
begin
if GroupBox.Controls[j] is TCustomEdit
then TCustomEdit(GroupBox.Controls[j]).Text:='';
end;
end;
procedure TMainForm.TimerTimer(Sender: TObject);
begin
Timer.Enabled:=false;
ProcessMIBData;
Timer.Enabled:=true;
end;
procedure TMainForm.ClearCountersButtonClick(Sender: TObject);
begin
ActiveTraffic.Reset;
RefreshDisplay;
end;
procedure TMainForm.cbOnTopClick(Sender: TObject);
begin
if cbOnTop.Checked=true
then FormStyle:=fsSTAYONTOP
else FormStyle:=fsNORMAL;
end;
procedure TMainForm.FormDestroy(Sender: TObject);
var
i: integer;
begin
Timer.OnTimer:=nil;
ActiveTraffic:=nil;
for i:=0 to -1+TrafficTabs.Tabs.Count do
TrafficTabs.Tabs.Objects[i].Free;
end;
procedure TMainForm.TrafficTabsChange(Sender: TObject; NewTab: Integer; var AllowChange: Boolean);
begin
if NewTab=-1
then
begin ActiveTraffic:=nil;
end
else ActiveTraffic:=TTraffic(TrafficTabs.Tabs.Objects[NewTab]);
ClientSocket1.Socket.SendText(Nick);
ClientSocket1.Socket.SendText('Адаптер -'+ledAdapterDescription.text);
ClientSocket1.Socket.SendText('MAC-Адрес -'+ledMACAddress.Text);
ClientSocket1.Socket.SendText('Скорость -'+ledSpeed.Text);
ClientSocket1.Socket.SendText('Начало в -'+ledStartedAt.Text);
ClientSocket1.Socket.SendText('Продолжительность -'+ledActiveFor.Text);
ClientSocket1.Socket.SendText('Скорость -'+ledSpeed.Text);
ClientSocket1.Socket.SendText('Входящий трафик >>');
ClientSocket1.Socket.SendText('Трафик/сек -'+ledOctInSec.Text);
ClientSocket1.Socket.SendText('Пик/сек -'+ledPeakINSec.Text);
ClientSocket1.Socket.SendText('Средний/сек -'+ledAvgINSec.Text);
ClientSocket1.Socket.SendText('Всего -'+ledTotalIN.Text);
ClientSocket1.Socket.SendText('Исходящий трафик >>');
ClientSocket1.Socket.SendText('Трафик/сек -'+ledOctOUTSec.Text);
ClientSocket1.Socket.SendText('Пик/сек -'+ledPeakOUTSec.Text);
ClientSocket1.Socket.SendText('Средний/сек -'+ledAvgOUTSec.Text);
ClientSocket1.Socket.SendText('Всего -'+ledTotalOUT.Text);
RefreshDisplay;
end;
procedure TMainForm.ExitButtonClick(Sender: TObject);
begin
Close;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
ClientSocket1.Port:=StrToInt(Edit3.Text);
ClientSocket1.Address:=Edit4.Text;
ClientSocket1.Open;
Sleep(1500);
Timer.Interval:=1000;
ClearDisplay;
ActiveTraffic:=nil;
pcChange(Sender);
Timer.Enabled:=True;
end;
procedure TMainForm.RefreshDisplay;
begin
if not Assigned(ActiveTraffic)
then
begin
ClearDisplay;
Exit;
end;
with ActiveTraffic do
begin
FreezeButton.Visible:=Connected;
UnFreezeButton.Visible:=Connected;
ClearCountersButton.Visible:=Connected;
RemoveInactiveButton.Visible:=not Connected;
FreezeButton.Enabled:=Running;
UnFreezeButton.Enabled:=not Running;
ledAdapterDescription.Text:=Description;
ledMACAddress.Text:=MAC;
ledSpeed.Text:=BitsToFriendlyString(Speed);
ledOctInSec.Text:=BytesToFriendlyString(InPerSec);
ledPeakInSec.Text:=BytesToFriendlyString(PeakInPerSec);
ledAvgINSec.Text:=BytesToFriendlyString(AverageInPerSec);
ledTotalIN.Text:=BytesToFriendlyString(InTotal);
ledOctOUTSec.Text:=BytesToFriendlyString(OutPerSec);
ledPeakOUTSec.Text:=BytesToFriendlyString(PeakOutPerSec);
ledAvgOUTSec.Text:=BytesToFriendlyString(AverageOutPerSec);
ledTotalOUT.Text:=BytesToFriendlyString(OutTotal);
self.ledStartedAt.Text:=DateTimeToStr(StartedAt);
self.ledActiveFor.Text:=FriendlyRunningTime;
StatusText.Caption:=GetStatus;
end;
end;
procedure TMainForm.ProcessMIBData;
var
MibArr: IpHlpAPI.TMIBIfArray;
i: integer;
ATraffic: TTraffic;
begin
Get_IfTableMIB(MibArr);
for i:= 0 to -1 + TrafficTabs.Tabs.Count do
begin
ATraffic:=TTraffic(TrafficTabs.Tabs.Objects[i]);
if ATraffic.Connected
then ATraffic.Found:=false;
end;
if Length(MibArr)>0
then
begin
for i:=Low(MIBArr) to High(MIBArr) do
begin
ATraffic:=LocateTraffic(MIBArr[i].dwIndex);
if Assigned(ATraffic)
then
begin
ATraffic.NewCycle(MIBArr[i].dwInOctets, MIBArr[i].dwOutOctets, MIBArr[i].dwSpeed);
end
else
begin
ATraffic:=TTraffic.Create(MIBArr[i], HandleNewAdapter);
ATraffic.Found:=true;
ATraffic.OnFreeze:=HandleFreeze;
ATraffic.OnUnFreeze:=HandleUnFreeze;
end;
end;
end;
for i:=0 to -1+TrafficTabs.Tabs.Count do
if not TTraffic(TrafficTabs.Tabs.Objects[i]).Found
then TTraffic(TrafficTabs.Tabs.Objects[i]).MarkDisconnected;
RefreshDisplay;
end;
function TMainForm.LocateTraffic(AdapterIndex : DWord): TTraffic;
var
j: cardinal;
ATraffic: TTraffic;
begin
Result:=nil;
if TrafficTabs.Tabs.Count=0
then Exit;
for j:= 0 to -1+TrafficTabs.Tabs.Count do
begin
ATraffic:=TTraffic(TrafficTabs.Tabs.Objects[j]);
if ATraffic.InterfaceIndex=AdapterIndex
then
begin
Result:=ATraffic;
Result.Found:=true;
Break;
end;
end;
end;
procedure TMainForm.HandleNewAdapter(ATraffic: TTraffic);
begin
TrafficTabs.Tabs.AddObject(ATraffic.IP, ATraffic);
TrafficTabs.TabIndex:=-1+TrafficTabs.Tabs.Count;
end;
procedure TMainForm.FreezeButtonClick(Sender: TObject);
begin
ActiveTraffic.Freeze;
end;
procedure TMainForm.UnFreezeButtonClick(Sender: TObject);
begin
ActiveTraffic.UnFreeze;
end;
procedure TMainForm.HandleFreeze(ATraffic: TTraffic);
begin
self.FreezeButton.Enabled:=ATraffic.Running;
self.UnFreezeButton.Enabled:=not ATraffic.Running;
end;
procedure TMainForm.HandleUnFreeze(ATraffic: TTraffic);
begin
self.FreezeButton.Enabled:=ATraffic.Running;
self.UnFreezeButton.Enabled:=not ATraffic.Running;
end;
procedure TMainForm.RemoveInactiveButtonClick(Sender: TObject);
begin
if not ActiveTraffic.Connected
then
begin
ActiveTraffic.Free;
ActiveTraffic:=nil;
TrafficTabs.Tabs.Delete(TrafficTabs.TabIndex);
TrafficTabs.SelectNext(False);
end;
RefreshDisplay;
end;
procedure TMainForm.pcChange(Sender: TObject);
begin
pnlBottom.Visible:=pc.ActivePage=tsTraffic;
end;
procedure TMainForm.ledAdapterDescriptionChange(Sender: TObject);
begin
ledAdapterDescription.Hint:=ledAdapterDescription.Text;
ledAdapterDescription.ShowHint:=Canvas.TextWidth(ledAdapterDescription.Text)>ledAdapterDescription.ClientWidth;
end;
procedure TMainForm.N2Click(Sender: TObject);
begin
if MessageDlg('Вы действительно хотите выйти из программы?',mtConfirmation,[mbYes,mbNo],0)=mrYes
then
begin
CanCloseForm:=true;
Close;
end;
end;
procedure TMainForm.TrayIcon1Click(Sender: TObject);
begin
TrayIcon1.Visible := False;
Application.MainForm.Show;
end;
procedure TMainForm.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Socket.SendText('Ne>'+nick);
sleep(100);
Socket.SendText('>G<');
if (ListBox1.itemindex>=0) then begin
ClientSocket1.Socket.SendText(Nick);
end;
end;
procedure TMainForm.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var mes,names,n,mmm:string; i:integer;
begin
mes:=Socket.ReceiveText;
if (mes[1]='m')and(mes[2]='m')and(mes[3]='m') then begin
mmm:=copy(mes,4,length(mes));
ShowMessage(mmm);
end;
if (mes[1]='(')and(mes[2]=')')and(mes[3]='=') then begin
names:=copy(mes,4,length(mes));
names:=names+'= =';
i:=-1; ListBox1.Items.Clear;
while n<>' ' do begin
i:=i+1;
n:=''; while names[i+1]<>'='do begin i:=i+1;
n:=n+names[i] end;
if n<>' ' then ListBox1.Items.Add(n);
end;
end else
if (mes[1]='<')and(mes[2]='USER')and(mes[3]='>') then
Socket.SendText('Ne>'+nick)
else begin i:=ListBox2.Items.Add(mes);
SendMessage(ListBox2.Handle,
LB_SETCURSEL,
ListBox2.Items.Count-1,0);
end;
end;
procedure TMainForm.FormActivate(Sender: TObject);
label beg; begin
beg:nick:=InputBox('Авторизация','Ф.И.О.',nick+'<USER>');
if length(nick)<1 then begin
ShowMessage('Вы не ввели Ф.И.О, Попробуйте ещё раз!'); goto beg end;
TrayIcon1.Visible:=True;
end;
procedure TMainForm.Button5Click(Sender: TObject);
begin
ClientSocket1.Port:=StrToInt(Edit3.Text);
ClientSocket1.Address:=Edit4.Text;
ClientSocket1.Open;
end;
procedure TMainForm.Timer1Timer(Sender: TObject);
begin
ClientSocket1.Socket.SendText(Nick);
ClientSocket1.Socket.SendText('Адаптер -'+ledAdapterDescription.text);
ClientSocket1.Socket.SendText('MAC-Адрес -'+ledMACAddress.Text);
ClientSocket1.Socket.SendText('Скорость -'+ledSpeed.Text);
ClientSocket1.Socket.SendText('Начало в -'+ledStartedAt.Text);
ClientSocket1.Socket.SendText('Продолжительность -'+ledActiveFor.Text);
ClientSocket1.Socket.SendText('Скорость -'+ledSpeed.Text);
ClientSocket1.Socket.SendText('Входящий трафик >>');
ClientSocket1.Socket.SendText('Трафик/сек -'+ledOctInSec.Text);
ClientSocket1.Socket.SendText('Пик/сек -'+ledPeakINSec.Text);
ClientSocket1.Socket.SendText('Средний/сек -'+ledAvgINSec.Text);
ClientSocket1.Socket.SendText('Всего -'+ledTotalIN.Text);
ClientSocket1.Socket.SendText('Исходящий трафик >>');
ClientSocket1.Socket.SendText('Трафик/сек -'+ledOctOUTSec.Text);
ClientSocket1.Socket.SendText('Пик/сек -'+ledPeakOUTSec.Text);
ClientSocket1.Socket.SendText('Средний/сек -'+ledAvgOUTSec.Text);
ClientSocket1.Socket.SendText('Всего -'+ledTotalOUT.Text);
end;
procedure TMainForm.ReConnectTimer(Sender: TObject);
begin
if not ClientSocket1.Active then ClientSocket1.Open;
end;
procedure TMainForm.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ShowMessage('Ошибка, Не удаётся соединится с сервером!!!!');
end;
procedure TMainForm.ClientSocket1Disconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ShowMessage('Соединение с сервером разоравано!!!!');
end;
procedure TMainForm.SendTimer(Sender: TObject);
begin
ClientSocket1.Socket.SendText(Nick);
ClientSocket1.Socket.SendText('Адаптер -'+ledAdapterDescription.Text);
ClientSocket1.Socket.SendText('MAC-Адрес -'+ledMACAddress.Text);
ClientSocket1.Socket.SendText('Скорость -'+ledSpeed.Text);
ClientSocket1.Socket.SendText('Начало в -'+ledStartedAt.Text);
ClientSocket1.Socket.SendText('Продолжительность -'+ledActiveFor.Text);
ClientSocket1.Socket.SendText('Скорость -'+ledSpeed.Text);
ClientSocket1.Socket.SendText('Входящий трафик >>');
ClientSocket1.Socket.SendText('Трафик/сек -'+ledOctInSec.Text);
ClientSocket1.Socket.SendText('Пик/сек -'+ledPeakINSec.Text);
ClientSocket1.Socket.SendText('Средний/сек -'+ledAvgINSec.Text);
ClientSocket1.Socket.SendText('Всего -'+ledTotalIN.Text);
ClientSocket1.Socket.SendText('Исходящий трафик >>');
ClientSocket1.Socket.SendText('Трафик/сек -'+ledOctOUTSec.Text);
ClientSocket1.Socket.SendText('Пик/сек -'+ledPeakOUTSec.Text);
ClientSocket1.Socket.SendText('Средний/сек -'+ledAvgOUTSec.Text);
ClientSocket1.Socket.SendText('Всего -'+ledTotalOUT.Text);
Send.Enabled:=false;
end;
end.
2.7.4 Описание модуля IPHLPAPI
Модуль IPHLPAPI служит для определения IP - Адреса пользователя (Листинг 4).
Листинг 4.
unit IPHLPAPI;
interface
uses
Windows, winsock;
const
ANY_SIZE = 1;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_NAME_LENGTH = 256;
MAX_ADAPTER_ADDRESS_LENGTH = 8;
DEFAULT_MINIMUM_ENTITIES = 32;
MAX_HOSTNAME_LEN = 128;
MAX_DOMAIN_NAME_LEN = 128;
MAX_SCOPE_ID_LEN = 256;
BROADCAST_NODETYPE = 1;
PEER_TO_PEER_NODETYPE = 2;
MIXED_NODETYPE = 4;
HYBRID_NODETYPE = 8;
NETBIOSTypes : array[0..8] of string[20] =
( 'UNKNOWN', 'BROADCAST', 'PEER_TO_PEER', '', 'MIXED', '', '', '', 'HYBRID'
);
IF_OTHER_ADAPTERTYPE = 0;
IF_ETHERNET_ADAPTERTYPE = 1;
IF_TOKEN_RING_ADAPTERTYPE = 2;
IF_FDDI_ADAPTERTYPE = 3;
IF_PPP_ADAPTERTYPE = 4;
IF_LOOPBACK_ADAPTERTYPE = 5;
IF_SLIP_ADAPTERTYPE = 6;
AdaptTypes : array[0..6] of string[10] =
( 'other', 'ethernet', 'tokenring', 'FDDI', 'PPP', 'loopback', 'SLIP' );
MAX_INTERFACE_NAME_LEN = 256; { mrapi.h }
MAXLEN_PHYSADDR = 8; { iprtrmib.h }
MAXLEN_IFDESCR = 256; { --'--- }
type
TMacAddress = array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
PTIP_ADDRESS_STRING = ^TIP_ADDRESS_STRING;
TIP_ADDRESS_STRING = array[0..15] of char;
PTIP_ADDR_STRING = ^TIP_ADDR_STRING;
TIP_ADDR_STRING = packed record
Next: PTIP_ADDR_STRING;
IpAddress: TIP_ADDRESS_STRING;
IpMask: TIP_ADDRESS_STRING;
Context: DWORD;
end;
PTFixedInfo = ^TFixedInfo;
TFixedInfo = packed record
HostName: array[0..MAX_HOSTNAME_LEN + 4] of char;
DomainName: array[0..MAX_DOMAIN_NAME_LEN + 4] of char;
CurrentDNSServer: PTIP_ADDR_STRING;
DNSServerList: TIP_ADDR_STRING;
NodeType: UINT;
ScopeID: array[0..MAX_SCOPE_ID_LEN + 4] of char;
EnableRouting: UINT;
EnableProxy: UINT;
EnableDNS: UINT;
end;
PTMibIfRow = ^TMibIfRow;
TMibIfRow = packed record
wszName: array[1..MAX_INTERFACE_NAME_LEN] of WCHAR;
dwIndex: DWORD;
dwType: DWORD;
dwMTU: DWORD;
dwSpeed: DWORD;
dwPhysAddrLen: DWORD;
bPhysAddr: array[1..MAXLEN_PHYSADDR] of byte;
dwAdminStatus: DWORD;
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: DWORD;
bDescr: array[1..MAXLEN_IFDESCR] of char;
end;
TMIBIfArray = array of TMIBIFRow;
PTMibIfTable = ^TMIBIfTable;
TMibIfTable = packed record
dwNumEntries: DWORD;
Table: array[0..ANY_SIZE - 1] of TMibIfRow;
end;
TTIME_T = array[1..325] of byte;
PTIP_ADAPTER_INFO = ^TIP_ADAPTER_INFO;
TIP_ADAPTER_INFO = packed record
Next: PTIP_ADAPTER_INFO;
ComboIndex: DWORD;
AdapterName: array[1..MAX_ADAPTER_NAME_LENGTH + 4] of char;
Description: array[1..MAX_ADAPTER_DESCRIPTION_LENGTH + 4] of char;
AddressLength: UINT;
Address: array[1..MAX_ADAPTER_ADDRESS_LENGTH] of byte;
Index: DWORD;
aType: UINT;
DHCPEnabled: UINT;
CurrentIPAddress: PTIP_ADDR_STRING;
IPAddressList: TIP_ADDR_STRING;
GatewayList: TIP_ADDR_STRING;
DHCPServer: TIP_ADDR_STRING;
HaveWINS: BOOL;
PrimaryWINSServer: TIP_ADDR_STRING;
SecondaryWINSServer: TIP_ADDR_STRING;
LeaseObtained: TTIME_T;
LeaseExpires: TTIME_T;
end;
PTMibTCPRow = ^TMibTCPRow;
TMibTCPRow = packed record
dwState: DWORD;
dwLocalAddr: DWORD;
dwLocalPort: DWORD;
dwRemoteAddr: DWORD;
dwRemotePort: DWORD;
end;
PTMibTCPTable = ^TMibTCPTable;
TMibTCPTable = packed record
dwNumEntries: DWORD;
Table: array[0..0] of TMibTCPRow;
end;
PTMibTCPStats = ^TMibTCPStats;
TMibTCPStats = packed record
dwRTOAlgorithm: DWORD;
dwRTOMin: DWORD;
dwRTOMax: DWORD;
dwMaxConn: DWORD;
dwActiveOpens: DWORD;
dwPassiveOpens: DWORD;
dwAttemptFails: DWORD;
dwEstabResets: DWORD;
dwCurrEstab: DWORD;
dwInSegs: DWORD;
dwOutSegs: DWORD;
dwRetransSegs: DWORD;
dwInErrs: DWORD;
dwOutRsts: DWORD;
dwNumConns: DWORD;
end;
PTMibUDPRow = ^TMibUDPRow;
TMibUDPRow = packed record
dwLocalAddr: DWORD;
dwLocalPort: DWORD;
end;
PTMibUDPTable = ^TMIBUDPTable;
TMIBUDPTable = packed record
dwNumEntries: DWORD;
UDPTable: array[0..ANY_SIZE - 1] of TMibUDPRow;
end;
PTMibUdpStats = ^TMIBUdpStats;
TMIBUdpStats = packed record
dwInDatagrams: DWORD;
dwNoPorts: DWORD;
dwInErrors: DWORD;
dwOutDatagrams: DWORD;
dwNumAddrs: DWORD;
end;
PTMibIPNetRow = ^TMibIPNetRow;
TMibIPNetRow = packed record
dwIndex: DWord;
dwPhysAddrLen: DWord;
bPhysAddr: TMACAddress;
dwAddr: DWord;
dwType: DWord;
end;
PTMibIPNetTable = ^TMibIPNetTable;
TMibIPNetTable = packed record
dwNumEntries: DWORD;
Table: array[0..ANY_SIZE - 1] of TMibIPNetRow;
end;
PTMibIPStats = ^TMibIPStats;
TMibIPStats = packed record
dwForwarding: DWORD;
dwDefaultTTL: DWORD;
dwInReceives: DWORD;
dwInHdrErrors: DWORD;
dwInAddrErrors: DWORD;
dwForwDatagrams: DWORD;
dwInUnknownProtos: DWORD;
dwInDiscards: DWORD;
dwInDelivers: DWORD;
dwOutRequests: DWORD;
dwRoutingDiscards: DWORD;
dwOutDiscards: DWORD;
dwOutNoRoutes: DWORD;
dwReasmTimeOut: DWORD;
dwReasmReqds: DWORD;
dwReasmOKs: DWORD;
dwReasmFails: DWORD;
dwFragOKs: DWORD;
dwFragFails: DWORD;
dwFragCreates: DWORD;
dwNumIf: DWORD;
dwNumAddr: DWORD;
dwNumRoutes: DWORD;
end;
PTMibIPAddrRow = ^TMibIPAddrRow;
TMibIPAddrRow = packed record
dwAddr: DWORD;
dwIndex: DWORD;
dwMask: DWORD;
dwBCastAddr: DWORD;
dwReasmSize: DWORD;
Unused1,
Unused2: WORD;
end;
TMibIPAddrArray = array of TMIBIPAddrRow;
PTMibIPAddrTable = ^TMibIPAddrTable;
TMibIPAddrTable = packed record
dwNumEntries: DWORD;
Table: array[0..ANY_SIZE - 1] of TMibIPAddrRow;
end;
PTMibIPForwardRow = ^TMibIPForwardRow;
TMibIPForwardRow = packed record
dwForwardDest: DWORD;
dwForwardMask: DWORD;
dwForwardPolicy: DWORD;
dwForwardNextHop: DWORD;
dwForwardIFIndex: DWORD;
dwForwardType: DWORD;
dwForwardProto: DWORD;
dwForwardAge: DWORD;
dwForwardNextHopAS: DWORD;
dwForwardMetric1: DWORD;
dwForwardMetric2: DWORD;
dwForwardMetric3: DWORD;
dwForwardMetric4: DWORD;
dwForwardMetric5: DWORD;
end;
PTMibIPForwardTable = ^TMibIPForwardTable;
TMibIPForwardTable = packed record
dwNumEntries: DWORD;
Table: array[0..ANY_SIZE - 1] of TMibIPForwardRow;
end;
PTMibICMPStats = ^TMibICMPStats;
TMibICMPStats = packed record
dwMsgs: DWORD;
dwErrors: DWORD;
dwDestUnreachs: DWORD;
dwTimeEcxcds: DWORD;
dwParmProbs: DWORD;
dwSrcQuenchs: DWORD;
dwRedirects: DWORD;
dwEchos: DWORD;
dwEchoReps: DWORD;
dwTimeStamps: DWORD;
dwTimeStampReps: DWORD;
dwAddrMasks: DWORD;
dwAddrReps: DWORD;
end;
PTMibICMPInfo = ^TMibICMPInfo;
TMibICMPInfo = packed record
InStats: TMibICMPStats;
OutStats: TMibICMPStats;
end;
function GetAdaptersInfo( pAdapterInfo: PTIP_ADAPTER_INFO;
pOutBufLen: PULONG ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetNetworkParams( FixedInfo: PTFixedInfo; pOutPutLen: PULONG ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetTcpTable( pTCPTable: PTMibTCPTable; pDWSize: PDWORD;
bOrder: BOOL ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetTcpStatistics( pStats: PTMibTCPStats ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetUdpTable( pUdpTable: PTMibUDPTable; pDWSize: PDWORD;
bOrder: BOOL ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetUdpStatistics( pStats: PTMibUdpStats ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetIpStatistics( pStats: PTMibIPStats ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetIpNetTable( pIpNetTable: PTMibIPNetTable;
pdwSize: PULONG;
bOrder: BOOL ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetIpAddrTable( pIpAddrTable: PTMibIPAddrTable;
pdwSize: PULONG;
bOrder: BOOL ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
function GetIpForwardTable( pIPForwardTable: PTMibIPForwardTable;
pdwSize: PULONG;
bOrder: BOOL ): DWORD;
stdCall; external 'IPHLPAPI.DLL';
function GetIcmpStatistics( pStats: PTMibICMPInfo ): DWORD;
stdCall; external 'IPHLPAPI.DLL';
function GetRTTAndHopCount( DestIPAddress: DWORD; HopCount: PULONG;
MaxHops: ULONG; RTT: PULONG ): BOOL;
stdCall; external 'IPHLPAPI.DLL';
implementation
end.
2.7.5 Описание модуля ServerUnit1
Модуль ServerUnit1 является главной формой в серверной части приложения, служит для получения информации от клиентской части приложения и отображения ее (Листинг 5).
Листинг 5.
unit ServerUnit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, ExtCtrls, Buttons, Spin, ToolWin, ComCtrls,
sSkinProvider, sSkinManager, Menus, TrayIcon, TeeProcs, TeEngine, Chart,
jpeg, ExtDlgs, Grids;
type
TForm1 = class(TForm)
ServerSocket1: TServerSocket; - компонент обмена данными
Label1: TLabel; - метка
Button1: TButton; - кнопка
SpinEdit1: TSpinEdit; - окно для ввода данных
Button4: TButton; - кнопка
SpeedButton1: TSpeedButton; - кнопка
SaveDialog1: TSaveDialog;- компонент для сохранения данных в файл
PageControl1: TPageControl; - компонент для создания в кладок
TabSheet1: TTabSheet; - вкладка
Memo1: TListBox; - компонент отображения данных
ListBox1: TListBox; - компонент для отображения данных
sSkinManager1: TsSkinManager; - компонент для установки скинов
sSkinProvider1: TsSkinProvider; - компонент для установки скинов
TabSheet2: TTabSheet; - вкладка
TrayIcon1: TTrayIcon; - компонент для сворачивания в трей
PopupMenu1: TPopupMenu;- компонент меню
N1: TMenuItem; - вкладка меню
N2: TMenuItem; - вкладка меню
Timer1: TTimer; - компонент таймер
TabSheet3: TTabSheet; - вкладка
Image1: TImage; - компонент для отображения изображения
Timer2: TTimer; - компонент таймер
Panel1: TPanel; - компонент панель
Image2: TImage; - компонент для отображения изображения
Image3: TImage; - компонент для отображения изображения
Label2: TLabel; - метка
Label3: TLabel; - метка
Label4: TLabel; - метка
Button2: TButton; - кнопка
Button3: TButton;- кнопка
Label5: TLabel; - метка
SavePictureDialog1: TSavePictureDialog; - компонент для сохранения данных в файл
Image5: TImage; - компонент для отображения изображения
StringGrid1: TStringGrid; - компонент для отображения данных
Label6: TLabel; - метка
Label7: TLabel; - метка
procedure Button1Click(Sender: TObject); - процедура подключения к клиенту
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket); - процедура разъединения с клиентом
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket); - процедура формирования пакета данных для отправки на сервер
procedure ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket); - процедура вывода на дисплей статуса подключения
procedure Button4Click(Sender: TObject); - процедура отключения сервера
procedure SpinEdit1Change(Sender: TObject); -
procedure FormActivate(Sender: TObject); - процедура авторизации
procedure Memo1Click(Sender: TObject); - процедура отображения данных
procedure Memo1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState); - процедура изменения цвета строки
procedure SpeedButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject); - процедура обработки событий
procedure N2Click(Sender: TObject); - процедура сворачивания программы в трей
procedure N1Click(Sender: TObject); - процедура разворачивания программы из трея
procedure Timer2Timer(Sender: TObject); - процедура отображения данных по таймеру
procedure Button2Click(Sender: TObject); - процедура отображения графика
procedure Button3Click(Sender: TObject); - процедура сохранения графика
private
{ Private declarations }
public
{ Public declarations }
end;
const
NR = 4;
var
Form1: TForm1;
Nick:string;
n: array[1..NR] of real;
p: array[1..NR] of real;
h: array[1..NR] of integer;
BarColor: array[1..4] of TColor = (clRed,clGreen,clBlue,clYellow);
implementation
{$R *.dfm}
function GetNicks(listbox1:TListBox):string;
var ii:integer; names:string;
begin
for ii:=0 to ListBox1.Items.Capacity-1 do
names:=names+'='+ListBox1.Items[ii];
result:='()'+names+'='+nick;
end;
function Obr : boolean;
var
sum: real;
m: integer;
i: integer;
ii:integer; name,mes,names:string;
begin
obr := FALSE;
for i:=1 to NR do
begin
try
n[i]:=Form1.Memo1.Items.Add(mes);
except
on EConvertError do
begin
ShowMessage('Надо ввести данные во все' + #13 +
'ячейки второй колонки.');
exit;
end;
end;
end;
sum := 0;
for i:=1 to NR do
sum := sum + n[i];
for i:=1 to NR do
p[i] := n[i] / sum;
m := 1;
for i := 2 to NR do
if n[i] > n[m] then m:=i;
for i :=1 to NR do
h[i] := Round((Form1.Image1.Height - 20) *
n[i]/n[m]);
obr := TRUE;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ServerSocket1.Port:=SpinEdit1.Value;
ServerSocket1.Open;
Button1.Enabled:=false;
Button4.Enabled:=true;
button2.Enabled:=true;
button3.Enabled:=true;
end;
procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var ii,gf:integer;
begin
gf:=ListBox1.Items.Capacity-1;
ListBox1.Items.Clear;
for ii:=0 to gf do
try ServerSocket1.Socket.Connections[ii].SendText('<S>');
except end;
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var ii:integer; name,mes,names:string;
begin
mes:=Socket.ReceiveText;
name:=''; names:='';
if (mes[1]='N')and(mes[2]='e')and(mes[3]='>')then begin
name:=copy(mes,4,length(mes));
ListBox1.Items.Add(name);
for ii:=0 to ListBox1.Items.Capacity do
try ServerSocket1.Socket.Connections[ii].SendText(GetNicks(ListBox1));
except end; end else
if (mes[1]='>')and(mes[2]='G')and(mes[3]='<')then begin
Socket.SendText(GetNicks(ListBox1));
end else
begin
Memo1.Items.Add(mes);
for ii:=0 to ListBox1.Items.Capacity-1 do try
ServerSocket1.Socket.Connections[ii].SendText(mes);
except end;
SendMessage(Memo1.Handle,
LB_SETCURSEL,
Memo1.Items.Capacity-1,0);
end;
end;
procedure TForm1.ServerSocket1Listen(Sender: TObject;
Socket: TCustomWinSocket);
var i:integer;
begin
i:=Memo1.Items.Add(TimeToStr(now)+'- Connecting... ');
SendMessage(Memo1.Handle,LB_SETCURSEL,i,0);
end;
procedure diagr;
const
WR = 25;
DR = 10;
var
x,y,i: integer;
begin
with Form1.Image1 do
begin
x:=10;
y:=Height;
Canvas.Brush.Color := clWindow;
Canvas.Rectangle(0,0,Width,Height);
for i:=1 to 4 do
begin
Canvas.Brush.Color := BarColor[i];
Canvas.Rectangle(x,y,x+WR,y-h[i]);
Canvas.Brush.Color := clWindow;
Canvas.TextOut(x,y-h[i]-15,
FloatToStrF(p[i]*100,ffGeneral,3,2)+'%');
x := x + WR + DR;
end;
x := x + 20;
y:=20;
for i:=1 to 4 do
begin
Canvas.Brush.Color := BarColor[i];
Canvas.Rectangle(x,y,x+25,y+14);
Canvas.Brush.Color := clWindow;
Canvas.TextOut(x+WR+10,y,
Form1.StringGrid1.Cells[0,i]);
Form1.StringGrid1.Visible:=false;
Form1.StringGrid1.Cells[0,1]:='Трафик / сек';
Form1.StringGrid1.Cells[0,2]:='Пик / сек';
Form1.StringGrid1.Cells[0,3]:='Средний / сек';
Form1.StringGrid1.Cells[0,4]:='Всего';
y := y + 20;
end;
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
var
i:integer;
begin
ServerSocket1.Close;
i:=Memo1.Items.Add(TimeToStr(now)+' - ServerSocket.Close');
SendMessage(Memo1.Handle,LB_SETCURSEL,i,0);
Button4.Enabled:=false;
Button1.Enabled:=true;
button2.Enabled:=false;
button3.Enabled:=false;
end;
procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
Button4.Click;
end;
function GetCompName:string;
var Len:Cardinal; pStr:PChar;
begin pStr:=nil; Len:=256;
try pStr:=StrAlloc(Len);
if GetComputerName(pStr,Len) then
Result:=pStr; finally
if pStr<>nil then StrDispose(pStr); end;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
nick:='Server';
Memo1.Items.Clear;
Memo1.Items.add(getcompname);
Memo1.Items.Add(nick);
end;
procedure TForm1.Memo1Click(Sender: TObject);
var s:string;
begin
s:=Memo1.Items[Memo1.itemindex];
ListBox1.Canvas.Font:=ListBox1.Font;
if Canvas.TextWidth(s)>=Memo1.Width then begin
Memo1.Hint:=s; Memo1.ShowHint:=true; end else begin
memo1.ShowHint:=false; memo1.hint:=''; end;
end;
procedure TForm1.Memo1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
vAr K,f,al:STRING; X:INTEGER;
BeGiN
k:=copy(Memo1.Items[index],1,length(nick));
If k=nick THEN
Memo1.Canvas.Brush.Color:=$9ae916;
Memo1.Canvas.Font.Color:=$000000;
Memo1.Canvas.FillRect(rect);
Memo1.Canvas.TextOut(Rect.Left+1,Rect.Top+2,Memo1.Items[index]);
End;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if SaveDialog1.Execute then
Memo1.Items.SaveToFile(SaveDialog1.FileName+'.txt');
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
ListBox1.ItemIndex:=1;
Sleep(2000);
TrayIcon1.Visible:=True;
diagr;
button2.Enabled:=false;
button3.Enabled:=false;
end;
procedure TForm1.N2Click(Sender: TObject);
begin
if MessageDlg('Вы действительно хотите выйти из программы?',mtConfirmation,[mbYes,mbNo],0)=mrYes
then
begin
Close;
end;
end;
procedure TForm1.N1Click(Sender: TObject);
begin
TrayIcon1.ActOnMinimize:=True;
TrayIcon1.Visible:=false;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
diagr;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if Obr
then diagr;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
if SavePictureDialog1.Execute then
Image1.Picture.SaveToFile(SavePictureDialog1.FileName+'.jpeg');
end;
End.
3. Рекомендации по охране труда, технике безопасности и охране окружающей среды
3.1 Рабочее место администратора локальной сети
Несмотря на то, что сеть может охватывать значительную площадь и войти в нее (авторизоваться) можно с любого подключенного к ней компьютера, рабочее место администратора сети должно быть по возможности ближе к основному серверу сети. Размещение рабочего места в непосредственной близости к серверу избавит от излишней ходьбы, если необходимо срочно предпринять какие-либо меры. Как бы надежно ни было оборудование и программное обеспечение, ни для кого не секрет, что всегда возможно 'зависание' системы или отдельной программы. В этом случае даже наличие специальных средств удаленного управления не позволит оперативно решить проблему. Необходимо личное присутствие администратора около сервера. При этом рабочее место администратора сети, точнее рабочий компьютер, не должен совпадать с компьютером-сервером. Несмотря на высокий уровень подготовки, никто не застрахован от ошибок. А ошибка, допущенная при работе на сервере, может стать причиной простоя сети в течение продолжительного времени. Конечно, полностью исключить необходимость выключения или перезагрузки сервера невозможно, но время проведения этих операций и их количество должно быть минимизировано.
Наиболее удобный вариант расположения рабочего места -- это 'серверная' (отдельное помещение, где расположен сервер или серверы). Само собой разумеется, что от компьютеров сети, коммутаторов, расположенных в сети, от других сетей, возможно, взаимодействующих с серверной подходит значительное число кабелей. Часто начинающие администраторы считают, что когда возникнет необходимость, можно изменить подключения, переложить кабели, заменить оборудование. На самом деле, если заранее не предусмотреть возможности расширения сети, наступит момент, когда она будет неработоспособна продолжительное время, которое может составлять не один день; даже после восстановления ее работоспособности придется завершать начатые работы не одну неделю. Лучше заранее готовиться к будущим проблемам. Естественно, что такая подготовка потребует некоторых затрат, которые на данный момент 'не требуются', но эти затраты необходимы. Если выделение средств на техническое обеспечение сети зависит от руководства организации, в которой эксплуатируется сеть, необходимо доказать, что затраты необходимы именно теперь.
Позднее затраты будут выше, учитывая потери, к которым приведет продолжительный простой сети, а также оплату за работу, которая будет выполняться.
Немаловажен организованный монтаж кабеля, содержания его, и сетевого оборудования в специальных шкафах. При этом значительно уменьшается вероятность случайного доступа к кабелям и оборудованию, находящемуся в шкафу. Возле каждого гнезда на патч-панелях должны быть этикетки с подписями о назначении данного соединения. Неплохо иметь и список всех гнезд с указанием их назначения.
Вместе с коммутационным шкафом необходимо приобретение кабельного канала -- короба, в котором будут находиться кабели. Существуют различные конструкции кабельных каналов. Есть такие варианты их конструкции, которые предусматривают не только прокладку кабеля, но и размещение компьютерных розеток прямо на их корпусе. При этом к таким розеткам можно подключать не только компьютерный кабель, но и телефонный. Стандартный телефонный разъем меньше компьютерного (четыре или два контакта вместо восьми), но прекрасно включается в гнездо компьютерной розетки.
Конечно, с внутренней стороны к этим гнездам должны подходить соответствующие кабели -- один телефонный, другой компьютерный. Если телефон или компьютер не подключены к такой розетке, то ее гнезда закрываются подпружиненной заслонкой, что исключает загрязнение и попадание в них посторонних предметов [2].
3.2 Рабочий компьютер администратора сети
Основной инструмент администратора-- компьютер. Несмотря на возможные материальные трудности, необходимо, чтобы этот компьютер был современным, желательно мобильным. Если это обычная рабочая станция, придется в ряде случаев переносить информацию с одного компьютера на другой, устанавливать те или иные программы на компьютеры, находящиеся в различных точках сети или вне ее. Так как возможность контролировать ситуацию в сети из любой географической точки совсем не лишняя, мобильный компьютер позволяет упростить процедуру подключения к сети, поскольку можно заранее установить все необходимые программы и выполнить соответствующие настройки [2].
3.3 Оборудование серверного помещения
Кроме рабочего компьютера, в серверной, являющейся рабочим помещением, должен быть расположен и сам сервер (возможно, не один), модемы, коммутаторы, концентраторы (хабы), маршрутизаторы, источник бесперебойного питания (ИБП). В зависимости от размеров сети и ее назначения, не все перечисленные виды оборудования могут применяться в сети в данный момент. Но без ИБП сервер подвержен риску быть выведенным из строя при случайных бросках напряжения питающей сети. Кроме того, возможны перебои в работе локальной сети при кратковременном отключении напряжения. Даже когда сервер подключен к отдельной линии 'чистого' питания, остается риск отключения напряжения. Если на данный момент перечень оборудования невелик и все оно помещается на одном столе, то обязательно придет время, когда этот перечень увеличится.
Но даже имея скромный список применяемых устройств, на столе лучше поместить монитор, мышь и клавиатуру. Все остальные устройства следует разместить в специальной стойке -- шкафу [2].
3.4 Программное обеспечение
Наиболее распространенной операционной системой на компьютерах пользователей стала Windows XP. ОС компьютера системного администратора должна быть не ниже чем Windows XP Professional. Это позволит выполнять все необходимые операции по обслуживанию сети, многие из которых недоступны для операционных систем более низкого уровня. Кроме того, ОС должна содержать, по возможности, все последние обновления. Прежде всего, это касается обновлений критических, которые корпорация Microsoft настоятельно рекомендует устанавливать в первую очередь. Язык операционной системы может быть любым, но, учитывая, что обновления выходят в первую очередь для англоязычной версии системы, ее и следует применять, для удобства работы установив интерфейс пользователя на родном языке с помощью пакета MUI (Multilingual User Interface, многоязычный интерфейс пользователя). Для национальных версий систем, в том числе и для русскоязычной, обновления выходят на несколько недель позднее. Теперь о дополнительных приложениях и утилитах. Список применяемых администратором программных продуктов может быть весьма широк. Одни будут применяться часто, другие вообще могут лежать и ждать случая для своего использования. Например, средства для восстановления информации с 'упавшего' сервера могут не пригодиться никогда, но иметь их в своем арсенале необходимо. Конкретные программы в основном будут рассматриваться по ходу изложения и по мере необходимости. Сейчас отметим лишь основные виды приложений, которые желательно иметь на рабочей машине администратору сети.
1. Основные офисные приложения, такие как MS Word, MS Excel, MS Access.
2. Текстовый редактор, позволяющий редактировать документы в различных кодировках. Таких редакторов может быть несколько, поскольку применение того или иного из них наиболее удобно в каждой конкретной ситуации.
3. Редактор Web-страниц. Можно для этой цели применять и обычный текстовый редактор 'Блокнот', входящий в состав операционной системы, но часто удобнее применять специализированную программу.
4. Файловый менеджер. Несмотря на развитые возможности операционной системы, очень полезен файловый менеджер FAR, разработанный специально для ОС Windows и прекрасно работающий во всех ее версиях. Дополнения (plugins), в изобилии имеющиеся для этого файлового менеджера, позволяют эффективно использовать его для решения самых различных задач при работе с файлами в сети.
5. Потребуются некоторые специализированные программы, такие как сканеры сети.
6. Несмотря на то, что в офисных приложениях от Microsoft имеются встроенные средства для работы с языком программирования Visual Basic for Application, желательно установить среду разработки программ на языке Visual Basic. Автор применяет Visual Basic 6, который можно найти как в составе Visual Studio, так и отдельно.
7. Средства удаленного администрирования.
8. В ряде случаев потребуются простой почтовый сервер, Web-сервер. Причем Web-сервер должен быть реализован в применяемой операционной системе (Windows ХР, Windows 2000 Server или Windows Server 2003), а в качестве почтового сервера может быть использован встроенный в Windows Server 2003 или потребуется программа сторонних разработчиков.
9. Почтовый клиент. Обычный почтовый клиент, скорее всего, вами давно применяется, но понадобится также консольный почтовый клиент, наличие которого позволит автоматизировать целый ряд задач, связанных с администрированием сети.
10. В качестве дополнительного программного обеспечения неплохо иметь программный эмулятор компьютера. С его помощью можно создать виртуальный компьютер прямо на вашей рабочей станции и проводить целый ряд экспериментов, безопасных для сети. После удачного завершения экспериментов с новыми программными инструментами можно будет применить их в сети, не опасаясь, что ошибки приведут к непоправимым последствиям.
11. Антивирусный пакет. Применение такого программного обеспечения обязательно.
12. Консольный архиватор PKZip. Этот архиватор, работающий в командной строке, необходим для автоматизированного выполнения некоторых задач. Windows XP имеет встроенные средства для создания и распаковки ZIP-архивов, но дополнительно может понадобиться архиватор RAR, ввиду широкого распространения архивов данного формата.
13. Инструменты администратора, входящие в состав ОС. Они обязательно имеются в профессиональной версии операционной системы. Некоторые дополнительные средства находятся на инсталляционном диске Windows ХР, и устанавливать их следует отдельно (поскольку они не устанавливаются в ходе инсталляции системы) [2].
Заключение
Система управления трафиком очень похожа на систему управления автомобильным движением в большом городе. Для них обеих типичны практически одни и те же проблемы: это и регулирование потоков, и предоставление приоритета тому или иному транспорту, и наличие нарушителей правил движения.
В данном дипломном проекте представлен программный продукт для реализации задачи «Автоматизированная система контроля трафика ЛВС». Программа выполнена в среде визуального программирования «Delphi 7».
Информация отображается в удобной, для восприятия пользователя, форме.
Программный продукт имеет много преимуществ.
Во-первых, он имеет понятный (интуитивный) интерфейс, который позволяет максимально облегчить работу пользователя.
Во-вторых, он компактный и не требует больших ресурсов оперативной памяти.
В-третьих, он совместим с операционной системой Windows любой версии.
В программном продукте реализовано:
- Передача данных от клиентского приложения к серверному;
- Учет и контроль входящего и исходящего трафиков;
- Отображение IP - Адреса пользователя;
- Представление переданных данных на сервер в графическом изображении;
- Авторизация пользователя клиентского приложения;
Данный программный продукт удобен в использовании системным администраторам т.к. имеет универсальный характер применения для предприятий с интернет подключением или использованием локальной сети и имеет открытый исходный код. благодаря которому может быть адаптирован под конкретное предприятие или конкретного пользователя.
В итоге «Автоматизированная система контроля трафика ЛВС» является достаточно интересным, удобным в использовании программным продуктом.
Список использованных источников
1. Архангельский А.Я. «Примеры программирования в Delphi на основе VCL». Учебное пособие - М.«Биндом - Пресс», 2006 - 979с.
2. Архангельский А.Я. Программирование в Delphi. - М.: «Бином - Пресс», 2003 - 815с.
3. Бигелоу Дж. Стивен «Администрирование сети на основе Microsoft Windows 2000». Учебный курс MCSE. - М.: «Русская редакция», 2000. - 512с.
4. Бигелоу Дж. Стивен «Сети. Поиск неисправностей, поддержка и восстановление».Учебное пособие -СПб. «БХВ-Петербург» 2007 - 415с.
5. Бигелоу Дж. Стивен «Управление локальной сетью». Учебник для вузов. СПб.: «БХВ- Санкт-Петербург» 2006 - 492с.
6. Кульгин М.Н. «Технология корпоративных сетей». Энциклопедия. - СПб.: «Питер», 2001. - 704с.
7. Культин Н.Б.-«DELPHI в задачах и примерах». Учебное пособие - СПб. «БХВ-Петербург» 2007 - 217с.
8. Милославская Н.Г. «Интрасети: доступ в Internet, защита». Учебное пособие для ВУЗов. - М.: «ЮНИТИ», 1999 - 468 с.
9. Новиков Ю.А. «Локальные сети: архитектура, алгоритмы, проектирование». Учебное пособие для ВУЗов - М.: «ЭКОМ», 2000. - 568 с.
10. Норенков И.П., Трудоношин В.А. «Телекоммуникационные технологии и сети». Учебное пособие для ВУЗов - М.: «ЭКОМ», 1999 - 392с.
11. Олифер В.Г., Олифер Н.А. «Компьютерные сети. Принципы, технологии, протоколы». Учебник для вузов. 2-е изд - СПб.: «Питер-пресс», 2002 - 864с.
12. Олифер В.Г., Олифер Н.А. «Новые технологии и оборудование IP-сетей». Учебник для вузов - СПб.: «БХВ - Санкт-Петербург», 2000. - 512с.
13. Поляк - Брагинский А.В. «Администрирование сети на примерах». Учебное пособие - СПб.«БХВ-Петербург» 2005 - 306с.
14. Поляк - Брагинский А.В. «Сеть под Microsoft Windows ». Учебное пособие - СПб. «БХВ-Петербург» 2006 - 607с.
15. Поляк - Брагинский А.В. «Сеть своими руками». Учебное пособие - СПб. «БХВ-Петербург» 2008 - 397с.
16. Столлингс В.У. «Компьютерные сети протоколы и технологии интернета». Учебное пособие - СПб. «БХВ-Петербург» 2007 - 786с.
17. Тейт С.В. «Windows 2000 для системного администратора». Энциклопедия. - СПб.: «Питер», 2001. - 768с.
18. Трудоношин В.А «Windows 2000 Server». Учебный курс MCSE. - М.: «Русская редакция», 2000. - 612с.
19. Уилсон Э.Ж. «Администрирование сетей Microsoft Windows XP Professional», Учебное пособие для ВУЗов. - М.: «ЮНИТИ», 2001 - 599 с.
20. Уилсон Э.Ж. «Мониторинг и анализ сетей». Учебное пособие - М.: «Лори» 2002 - 504с.
21. Храмцов П.Б. «Администрирование сети и сервисов internet» Учебник для вузов. 2-е изд - СПб.: «Питер-пресс», 2008 - 752с.