35366

Система удаленного управления компьютером

Курсовая

Информатика, кибернетика и программирование

Компьютерные сети в настоящее время представляют собой сложные комплексы с множеством поддерживаемых протоколов передачи данных и управления, которые интенсивно совершенствуются. Компьютерные сети предоставляют пользователям сервисы, реализуемые в виде сетевых приложений.

Русский

2014-03-24

764.5 KB

12 чел.

PAGE  26

МОСКОВСКИЙ  ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

им. Н.Э.БАУМАНА

Факультет_______________________________________________________

Кафедра________________________________________________________

 

Курс: «Вычислительные комплексы и сети»

РАСЧЕТНО-ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовой работе на тему:

    

    

 

Студент                           __ (   Дятлов Р.А.   )        Группа             ИУ7-73_

                                                                                 (фамилия, инициалы)                                             (индекс)

Студент                           __ (    Новикова Д.А.   )  Группа             ИУ7-73_     

                                                                                 (фамилия, инициалы)                                             (индекс)

                                                                                                                           

 

Оценка:  РПЗ -

 Демо версия --                                               

 

Преподаватель                                                (       Алешин В. А.       )

фамилия, инициалы

«      » ________ 2010 года

г.Москва

2010 г.


Содержание.

Введение

  1.  Исследовательская часть
    1.  Цель разработки и основные решаемые задачи
    2.  Современные средства решения поставленной задачи

1.2.1. Radmin

1.2.2. Hidden Administrator

1.2.3. Anyplace Control

Выводы

  1.  Конструкторская часть
    1.  Блок схемы алгоритмов

2.1.1. Алгоритм приема команды клиентом

2.1.2. Алгоритм отправки файла с клиента на сервер

2.1.3. Алгоритм получения сервером дерева файлов

2.1.4. Алгоритм проверки существующих соединений

  1.  Диаграмма протокола
    1.  Функциональная структура

Выводы

  1.  Технологическая часть
    1.  Средства программирования и отладки
    2.  Основные структуры данных программного комплекса
    3.  Описание работы приложения
    4.  Тестирование проекта

Выводы

Заключение

Список литературы

Приложения


Введение

Компьютерные сети в настоящее время представляют собой сложные комплексы с множеством поддерживаемых протоколов передачи данных и управления, которые интенсивно совершенствуются. Компьютерные сети предоставляют пользователям сервисы, реализуемые в виде сетевых приложений. Одним из наиболее распространенных классов сетевых приложений являются клиент-серверные приложения [2], которые реализуются в виде серверной части, формирующей запросы к клиентам, и клиентской части, реагирующей на эти запросы (рис. 1.).

Рис. 1. Клиент-серверное приложение.

В данной работе предпринята попытка создания сетевого приложения, обеспечивающего возможность управления удаленной машиной. В качестве протокола обмена данными между клиентом и сервером предложен протокол, основанный на прямых командах серверной части к клиентской. Система поддерживает одновременную работу сервера с несколькими клиентами. Команды серверной части могут быть следующего вида:

  •  Команда на выключение/перезагрузку компьютера клиента.
  •  Команда на выключение монитора (только для стационарного компьютера).
  •  Команда на выполнение в командной строке передаваемой инструкции.
  •  Команда на отключение процесса.
  •  Команда на передачу дерева файлов.
  •  Команда на удаление файла.
  •  Команда на переименование файла.
  •  Команда на копирование файла.
  •  Команда на перемещение файла.
  •  Команда на получение файла.


1. Исследовательская часть

  1.  Цель разработки и основные решаемые задачи

Главной целью данной работы является создание серверной и клиентской частей системы удаленного доступа с возможностью управления удаленной машиной по локальной или глобальной сетям.

Серверная часть должна обеспечивать эффективную работу с клиентами в условиях одновременного подключения нескольких пользователей, а так же обладать дружественным развитым интерфейсом и отвечать следующим основным требованиям:

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

Клиентская часть должна обеспечивать эффективное обслуживание серверных запросов и корректно выполнять посылаемые ей команды. К клиентской части предъявляются следующие требования:

  •  Корректное реагирование на команды сервера.
  •  Фиксированное время ответа и выполнение команд сервера.
  •  Выполнение системных функций для компьютера (выключение/перезагрузка), сервисов (остановка/запуск) и файлов (копирование/вставка/переименование).

Задача не является новой, поэтому при задании функциональности и разработке дизайна данной системы необходимо учитывать большой опыт, наработанный в данной области, и ориентироваться на уже существующие успешные проекты, работающие в глобальной сети.

  1.  
    Современные средства решения поставленной задачи

В настоящее время существует множество приложений, предоставляющих возможность удаленного управления компьютером через локальную или глобальную сети. Рассмотрим самые популярные из них.

1.2.1. Radmin

Radmin – это программа удаленного администрирования для платформы Windows, которая позволяет полноценно работать сразу на нескольких удаленных компьютерах с помощью обычного графического интерфейса [3] (Рис. 1.2.1.1.).

Возможности:

  •  Удаленное управление на аппаратном уровне с поддержкой технологии Intel® AMT.
  •  Текстовый и голосовой чаты.
  •  Безопасный обмен файлами с функцией "докачки".
  •  Поддержка нескольких одновременных соединений.
  •  Возможность отображения экрана удалённого ПК в отдельном окне или в полноэкранном режиме с плавным изменением масштаба и сохранением пропорций.
  •  Поддержка нескольких мониторов.
  •  Совместимость с ОС Linux.
  •  Двусторонняя работа с буфером обмена с поддержкой Unicode.
  •  Режим Telnet.
  •  Удалённое выключение компьютера.
  •  Запись в лог файл имени пользователя и DNS расшифровки его адреса.
  •  И т.д.

Недостатки:

  •  Необходимость установки на компьютер клиента программного обеспечения, видео драйвера.
  •  Необходимость доступа в интернет.
  •  Работа Telnet не корректна:
    •  нет возможности выделить/скопировать/вставить текст;
    •  поддерживается только вывод русской кодировки chcp 1251;
    •  невозможно вводить команды на русском языке.
  •  Непрозрачная работа с буфером обмена.

Рис. 1.2.1.1. Главное окно Radmin.

1.2.2. Hidden Administrator

Программа Hidden Administrator предназначена для удаленного скрытого наблюдения или управления компьютерами локальной сети или рабочей группы [4] (Рис. 1.2.2.1.).

Возможности:

  •  Отображение рабочего стола дистанционного ПК в реальном времени.
  •  Управление удаленным компьютером при помощи мыши и клавиатуры.
  •  Одновременное наблюдение за несколькими компьютерами (до 256 компьютеров одновременно) с возможностью их администрирования.
  •  Обмен файлами, поддержка Drag & Drop (Менеджер файлов).
  •  Удаленный доступ в режиме командной строки (аналог системной утилиты "CMD").
  •  Передача звука по сети в режиме реального времени.
  •  Мониторинг запущенных приложений, посещенных сайтов, распечатанных документов и активности USB накопителей.
  •  Включение компьютеров по сети (Wake on LAN).
  •  Обмен сообщениями с пользователем (Чат).
  •  Поддержка многоязычности.
  •  И т.д.

Недостатки:

  •  Необходимость установки программного обеспечения на компьютер клиента.
  •  Сложная удаленная установка.

Рис. 1.2.2.1. Главное окно Hidden Administrator.

1.2.3. Anyplace Control

Anyplace Control - программа, позволяющая получить удаленный доступ к компьютеру через Интернет или локальную сеть и в полной безопасности управлять удаленным компьютером в режиме реального времени [5] (Рис. 1.2.3.1.).

Возможности:

  •  Отображение рабочего стола удаленного компьютера в реальном времени.
  •  Использование мыши и клавиатуры для управления удаленным компьютером.
  •  Обмен файлами между компьютерами.
  •  Копирование текста, графики или других данных из буфера обмена одного компьютера и перенос их на другой компьютер.
  •  Включение, выключение, перезагрузка удаленного ПК, а также блокирование его мыши и клавиатуры.
  •  Получение удаленного доступа через интернет к ПК за маршрутизатором или брандмауэром без каких-либо настроек.

Недостатки:

  •  Отсутствие поддержки мультиэкранных систем.
  •  Невозможность проведения записи с экрана.
  •  Неудачный алгоритм шифрования данных (128 бит вместо 256).
  •  Режим работы через аккаунт-подключение, когда трафик пропускается через промежуточный веб-сервер, который принадлежит разработчикам Anyplace Control. С одной стороны, они гарантируют сохранность подобной информации, с другой – пользователи становятся в своего рода зависимость от стабильности работы сервера вендора, который может, например, выйти на длительное время из строя.

Рис. 1.2.3.1. Работа Anyplace Control.


Выводы

Для создания полноценной системы удаленного доступа, нужно изучить несколько различных приложений, ориентированных на эту цель, выделить из их функционала самые необходимые возможности и включить их в свой проект. Кроме того в проект необходимо добавить ряд второстепенных возможностей, упрощающих работу с удаленными машинами, а так же позаботиться об удобстве реализации этих возможностей и о простоте интерфейса. Это займет довольно много времени, поэтому был выбран другой путь – создать приложение, включающее только самые необходимые для работы с удаленной машиной возможности.

В рамках данной работы вашему вниманию будет представлено простейшее приложение для удаленной работы с компьютером. Оно обладает незагруженным интерфейсом и ограниченными возможностями:

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

Прием и отправка команд в созданном приложении происходит через специально разработанный протокол.

Представленное в данной работе приложение может быть использовано в небольшой локальной сети для помощи в настройке компьютера.


2.
 Конструкторская часть

  1.  Блок схемы алгоритмов

2.1.1. Алгоритм приема команды клиентом

Алгоритм для клиентской части. Клиент находится в ожидании, производя проверку буфера на пустоту через промежутки времени в 100 млс. Если буфер оказывается заполненным, то клиент должен распознать префикс пришедших данных и найти его в библиотеке префиксов, чтобы выяснить, какое действие ему необходимо выполнить (Рис. 2.1.1.1.).

Рис. 2.1.1.1. Алгоритм приема команды клиентом.
2.1.2. Алгоритм отправки файла с клиента на сервер

Алгоритм для клиентской и серверной частей. Перед передачей файла, клиент должен отправить запрос на сервер. Сервер находится в ожидании и проверяет буфер на пустоту. Как только буфер оказывается не пустым, сервер должен распознать префикс переданных данных. По префиксу сервер поймет, что клиент хочет передать файл, и, если сервер не занят, он примет этот файл (Рис. 2.1.2.1.).

Рис. 2.1.2.1.  Алгоритм отправки файла с клиента на сервер.
2.1.3. Алгоритм получения сервером дерева файлов

Алгоритм для серверной части. После установления соединения сервер ждет, пока клиент не сформирует дерево своих файлов. После чего начинается передача файла со сформированным деревом с клиента на сервер. Если передача прошла неуспешно, то клиент получает сообщение о неудаче и отправляет файл с деревом повторно. Если передача прошла успешно, то сервер отобразит дерево файлов клиента (Рис. 2.1.3.1.).

Рис. 2.1.3.1. Алгоритм получения сервером дерева файлов.
2.1.4. Алгоритм проверки существующих соединений

Алгоритм для серверной части. На сервере выполняется бесконечный цикл проверок каждого сокета на событие Disconnect (разъединение). Если какой-то из сокетов разорвал соединение, то сервер, после очередной проверки, обнаружит это, удалит информацию об отсоединенном клиенте и выведет сообщение о данном разъединении (Рис. 2.1.4.1.).

Рис. 2.1.4.1. Алгоритм проверки существующих соединений.

  1.  
    Диаграмма протокола

Для приема и отправки команд серверной части в создаваемом приложении был разработан специальный протокол вида (Рис. 2.2.1.):

<префикс> <размер передаваемых данных или файла, который последует за данным сообщением> <данные>

Рис. 2.2.1. Диаграмма протокола.

  1.  
    Функциональная структура

Для корректной работы проекта, скорости выполнения команд, а также для упрощения механизма отладки, программный код разбит на небольшие функции. Самыми важными из них, для обеспечения работоспособности всего запланированного функционала, являются:

  1.  Исключительно для сервера: 
  •  CreateServerSocket – создание сокета и настройка его на прослушивание заданного порта: 49200.
  •  AddClien – добавление нового пользователя в случае наличия в очереди клиента, желающего взаимодействовать с сервером.
  •  RemoovClient – очистка информации о клиенте в случае отключения клиента по каким-либо причинам.
  •  isClientRedyToWork – контроль за готовностью клиента к работе. Он необходим, например, при передаче файла клиенту или получения файла от него, чтобы в байты файла не попали лишние байты команд и не исказили структуру файла.
  1.  Исключительно для клиента:
    •  CreateClientSocket – создание сокета клиента и настройка его для связи с сервером.
    •  ConnectToServer – запрос на соединение с сервером.
  2.  Функции важные для обеспечения корректной работоспособности обоих приложений:
    •  ShutDounSocket – функция, предназначенная для корректного завершения сеанса связи.
    •  CheckConection – функция, необходимая для проверки соединения, на случай обрыва связи, инициированного второй стороной.
    •  SendFile – функция, необходимая для передачи файлов.
    •  SendMessage - функция принимает набор данных для передачи и префикс передачи, компонует пакет данных и отправляет второй стороне.
    •  Createcommand – функция для создания команды заданной структуры, используемой в разработанном протоколе связи.
    •  SepaGetedData – функция, необходимая для распаковки полученного пакета данных в структуру W_Data (Листинг 2.3.1.).
    •  GetMessageIfAny – функция, используемая для проверки буфера входных данных на пустоту и, в случае наличия данных, считывания их.
    •  GetError – функция, используемая для получения интуитивно-понятного объяснения возникшей ошибки, если таковая возникла.

Листинг 2.3.1.


Вывод

После рассмотрения различных вариантов реализации проекта, нами были выбраны рассмотренные в конструкторской части алгоритмы работы приложения.

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

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


3. Технологическая часть

  1.  Средства программирования и отладки

Для разработки клиент-серверного приложения был выбран язык C++. Данный выбор обусловлен наличием библиотек, предоставляющих необходимый для нашего проекта функционал, реализованный в достаточном объеме, а также удобством и лаконичностью синтаксиса языка.

Средой разработки был выбран C++ Builder компании Borland из-за обширности и разнообразия компонентных моделей, проработанных за долгие годы существования среды. Кроме того, данная среда не добавляет в код, не требуемых в задаче функций, тем самым уменьшая размер программы и увеличивая скорость работы приложения.

  1.  
    Основные структуры данных программного комплекса

Протокол

Создаваемое приложение имеет ряд команд, которые сервер пересылает клиенту. Структура этих команд:

  •  Запрос на получение, удаление и установку защиты от изменения файла:

-xxx < Len(File Path)> <File Path>

  •  Запрос на копирование и перемещение файла:

-xxx < Len(<OldPath>\t<NewPath>)> <OldPath>\t<NewPath>

  •  Запрос на переименование файла:

-xxx < Len(<FilePath>\t<NewName>) > <FilePath>\t<NewName>

  •  Запрос на передачу файла:

-xxx <FileSize> sss

Где «-xxx» в каждой запросе является префиксом, отвечающим за какую-либо команду:

  •  “-ss” – пересылка текстового сообщения (запрос от сервера к клиенту).
    •  “-tbf” – команда на передачу дерева файлов (от сервера к клиенту); будет передан файл, используя префикс -flg.
    •  “-tbs” – начало передачи дерева файлов (от клиента к серверу).
    •  “-cmc” – запрос на выполнение в командной строке передаваемой команды (от сервера к клиенту).
    •  “-cmd” – начало передачи файла командной строки для последующего выполнения (от сервера к клиенту).
    •  “-mnr” – команда на выключение монитора (только для стационарных компьютеров) (от сервера к клиенту).
    •  “-flm” – команда на перемещение файла (от сервера к клиенту).
    •  “-flc” – команда на копирование файла (от сервера к клиенту).
    •  “-fld” – команда на удаление файла (от сервера к клиенту).
    •  “-flr” – команда на переименование файла (от сервера к клиенту).
    •  “-flo” – команда на установление параметров файла в «только для чтения» (от сервера к клиенту).
    •  “-flg” – команда на пересылку файла клиента на сервер (от сервера к клиенту).
    •  “-pf” – команда для передачи первого в списке активного процесса (от клиента к серверу)
    •  “-pp” – команда для передачи всех, кроме первого в списке, активных процессов (от клиента к серверу)
    1.  
      Описание работы приложения

Начало работы

Для того чтобы начать работу с разработанным проектом, на компьютере-сервере должно быть запущено приложение-сервер, а на компьютере-пользователе – приложение-клиент.

Чтобы запустить, приложение-клиент, необходимо кликнуть по .exe файлу, после чего откроется окно программы. В открывшемся окне нужно занести IP-адрес машины, на которой установлен сервер, после чего щелкнуть по кнопке «Соединение», чтобы установить соединение с компьютером-сервером (Рис. 3.3.1.).

Рис. 3.3.1. Окно приложения-клиента.

Для того чтобы запустить приложение-сервер, также необходимо щелкнуть по .exe файлу, после чего появится небольшое окно с приглашением ввести порт, через который будет работать приложение, и IP-адрес сети, в которой будет работать приложение (Рис. 3.3.2.). После ввода необходимой информации и нажатия на кнопку «Ок», появится непосредственно окно приложения-сервера.

Рис. 3.3.2. Окно для ввода порта и IP-адреса.

После того, как пользователь установит связь с сервером, в окне приложения-сервера в списке справа появится IP-адрес данного пользователя (Рис. 3.3.3.). Кроме того, приложение-сервер тут же сформирует дерево файлов клиента, которое появится на вкладке «Файлы и Службы». Дерево формируется не мгновенно, процент передачи дерева отображает полоса прогресса на вкладке «Файлы и службы» (Рис. 3.3.4.).

Рис. 3.3.3. Список присоединенных клиентов.

Рис. 3.3.4. Полоса прогресса при формировании дерева файлов.

Работа с процессами

При работе с приложением-сервером можно увидеть, какие процессы активны на клиенте. Все активные процессы отображены на вкладке «Активные процессы» (Рис. 3.3.5.).

Рис. 3.3.5. Активные процессы клиента.

Работа с файлами

Для того чтобы производить какие-либо операции с файлами клиента, необходимо открыть вкладку «Файлы и службы», в которой находится дерево файлов. Далее нужно перейти на вкладку «Системные функции» на нижней панели приложения, которая отображает все возможные операции для работы с файлами клиента (Рис. 3.3.6.).

Рис. 3.3.6. Окно работы с файлами клиента.

Чтобы переименовать файл, необходимо найти его в дереве файлов, выделить и нажать кнопку «Новое имя». В появившемся окне (Рис. 3.3.7.) необходимо ввести новое имя файла (с расширением) и нажать «Ок».

Рис. 3.3.7. Переименование файла.

Чтобы переместить файл, необходимо найти его в дереве файлов, выделить и нажать кнопку «Переместить». В появившемся окне (Рис. 3.3.8.) необходимо ввести новый путь файла  либо выбрать его в дереве файлов и нажать «Ок».

Рис. 3.3.8. Перемещение файла.

  1.  
    Тестирование проекта

Проект был тщательно протестирован. Были выявлены следующие недостатки:

  •  В случае если сервер не запущен, при запросе соединения от клиента, функция возвращает ошибку: «Ресурс временно не доступен», хотя соединение проходит корректно (данную проблему удалось решить дополнительными проверками, что увеличивает время работы, но не значительно). 
    •  Формирование дерева происходит довольно долгое время, которое зависит от количества файлов, находящихся на жёстком диске.
    •  Скорость формирования списка активных процессов происходит относительно быстро, но, к сожалению, желаемой скорости, превышающей замечаемость человеческим глазом, достичь не удалось.

В целом, приложения работают стабильно, скорость посылки и выполнения команд не вызывает нареканий.


Вывод

По завершении работы над проектом, была разработана демо-версия приложения, обладающая удобным и интуитивно-понятным интерфейсом и включающая в себя все запланированные в начале функции, из которых полностью реализованы:

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

Нереализованной осталась работа со службами клиента, что будет исправлено позже.

Основными направлениями совершенствования проекта в дальнейшем будут:

  •  Уменьшение времени формирования и работы с файловым деревом и списком активных процессов.
  •  Добавление возможности видеть рабочий стол клиента и работать с ним в реальном времени посредствам мыши и клавиатуры.


Заключение

В рамках данного проекта было разработано клиент-серверное приложение, предназначенное для удаленной работы с компьютером.

Функциональность приложения обусловлена базовыми требованиями к программам такого рода и включает в себя:

  1.  Возможность передачи сообщений с сервера на клиентское приложение.
  2.  Возможность получения файлов, отправленных с клиентского приложения на сервер.
  3.  Возможность передачи команд сервером на клиентское приложение.
  4.  Распознавание клиентским приложением команд и выполнение их.
  5.  Работа с процессами клиентской машины.
  6.  Проверка команд на корректность.
  7.  Проверка соединения.
  8.  Возможность добавления новых клиентов.

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

Разработанная программа обладает удобным и интуитивно-понятным пользовательским интерфейсом, который без дополнительных объяснений отображает всю функциональность проекта.

Выполненные задачи отражают основные принципы реализации передачи файлов и сообщений по локальной или глобальной сетям. Таким образом, были отработаны базовые механизмы построения систем удаленного доступа.


Список литературы

  1.  C++ Глазами хакера / М. Е. Фленов. – М.: BHV, 2004.
  2.  Компьютерные сети / Э. Таненбаум. – СПб.: Питер, 2003.
  3.  http://www.radmin.ru/
  4.  http://www.hidadmin.ru/
  5.  http://www.anyplace-control.com/
  6.  msdn.microsoft.com


Приложение 1

Исходные программные коды

Класс, предназначенный для работы с файлами

Файл - .h

typedef class Filess{

       private:

               WinSock *WnSock; // Класс для работы с сетью

               int ColTabs; // Количество табуляций. Необходимо для создания корректную структуру файла для загрузки в дерево

               bool getlistoffiles(HANDLE FLE, std::string refcstrRootDirectory); // Непосредственно создание файла дерева файлов

               bool RemoveDirectory(AnsiString refcstrRootDirectory); // Специфическая функция для удаления папки.

       public:

               bool SendToServerA(std::string refcstrRootDirectory); //Вызывает создание файла дерева для отправки и отправляет его на сервер

               bool DeleteFileP(AnsiString Path); //Удаление файла

               bool RenameFileP(AnsiString Path, AnsiString NewName); // Переименование файла

               bool SetReadOnly(AnsiString Path); // Установка защиты от перезаписи

               bool MoveFileP(AnsiString Old_Path, AnsiString New_Path); // перемещение файла

               bool CopyFileP(AnsiString Dest_Path, AnsiString New_Path); //Копирование файла

               Filess(WinSock *WinsocketClass); // Описатель класса «Конструктор»

}Filess;

Файл - .c

Filess::Filess(WinSock *WinsocketClass)

{

       this->WnSock = WinsocketClass;

}

bool Filess::getlistoffiles(HANDLE FLE,

                          std::string refcstrRootDirectory)//Root Directory)

{

       bool Rezu = false;

       AnsiString strToWrite;

       AnsiString strTab = "\r\n";

       bool bSearchSubdirectories = true;

  std::string strFilePath; // Путь к файлу

  std::string strPattern; // Патерн поиска

  std::string strExtension; // Цель поиска

  HANDLE hFile; // Handle потока файла

  WIN32_FIND_DATA FileInformation; //Информация о файле

  strPattern = refcstrRootDirectory + "\\*.*";

  unsigned long dwBytesWritten;

  hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation); // Поиск первого файла в корневой директории refcstrRootDirectory

  if(hFile != INVALID_HANDLE_VALUE)

  {

     do

     {

        if(FileInformation.cFileName[0] != '.')

        {

           strFilePath.erase();

           strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

           if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // Если директория ищем поддиректории

           {

               strToWrite.sprintf(FileInformation.cFileName);

                 for(int i = 0; i < this->ColTabs; ++i)

                       strTab += '\t';

                 strTab += strToWrite;

                 WriteFile(FLE, strTab.c_str(), strTab.Length(), &dwBytesWritten, NULL);

                 strTab = "\r\n";

                 strToWrite = "";

              if(bSearchSubdirectories && strFilePath != "C:\\Windows") // Обход происходит всех папок кроме папки "C:\\Windows" и её подпапок ибо очень долго и так

              {

                 // Поиск подпапок

                 this->ColTabs += 1;

                 bool iRC = this->getlistoffiles(FLE, strFilePath);

                 this->ColTabs -= 1;

                 if(iRC)

                 {

                       return iRC;

                 }

              }

           }

           else

           {

                 //символы табуляции добавлять по вложенности

                 strToWrite.sprintf(FileInformation.cFileName);

                 for(int i = 0; i < this->ColTabs; ++i)

                       strTab += '\t';

                 strTab += strToWrite;

                 WriteFile(FLE, strTab.c_str(), strTab.Length(), &dwBytesWritten, NULL);

                 strTab = "\r\n";

                 strToWrite = "";

           }

        }

     } while(::FindNextFile(hFile, &FileInformation) == TRUE);

     // Закрытие handle потока

     ::FindClose(hFile);

     DWORD dwError = ::GetLastError();\

     if(dwError == ERROR_NO_MORE_FILES && refcstrRootDirectory == "C:") // Проверка на то что файлов больше нет

        return true;

  }

       return Rezu;

}

bool Filess::SendToServerA(std::string refcstrRootDirectory)

{

       bool Rezu = true;

       AnsiString strPath = Application->ExeName;

       int i = strPath.Length();

       while(strPath[i] != '\\')

       {

               strPath.Delete(i, 1);

               --i;

       }

       strPath += "Tree.txt";

       this->ColTabs = 1;

       //Засовываем корневую директорию

       unsigned long dwBytesWritten;

       HANDLE hFile=CreateFile(strPath.c_str(),GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

       WriteFile(hFile, (refcstrRootDirectory).c_str(),

                        refcstrRootDirectory.size(), &dwBytesWritten, NULL);

       this->getlistoffiles(hFile, refcstrRootDirectory);

       CloseHandle(hFile);

       this->WnSock->SendFile(strPath, "-tbs");

       return Rezu;

}

bool Filess::RemoveDirectory(AnsiString refcstrRootDirectory)

{

       bool Rezu;

       bool bSearchSubdirectories = true;

  AnsiString strFilePath; // Filepath

  AnsiString strPattern; // Pattern

  AnsiString strExtension; // Extension

  HANDLE hFile; // Handle to file

  WIN32_FIND_DATA FileInformation; // File information

  strPattern = refcstrRootDirectory + "\\*.*";

  unsigned long dwBytesWritten;

  hFile = ::FindFirstFile(strPattern.c_str(), &FileInformation);

  if(hFile != INVALID_HANDLE_VALUE)

  {

     do

     {

        if(FileInformation.cFileName[0] != '.')

        {

           strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;

           if(FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)

           {

              if(bSearchSubdirectories)

              {

                 // Поиск поддерикторий

                 bool iRC = this->RemoveDirectory(strFilePath);

                 SetFileAttributesA(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL);

                 RemoveDirectoryA(strFilePath);

                 if(iRC)

                 {

                       return iRC;

                 }

              }

           }

           else

           {

                 SetFileAttributesA(strFilePath.c_str(),FILE_ATTRIBUTE_NORMAL); // Установка атрибутов. Снятие защиты на изменение

                 DeleteFileA(strFilePath.c_str());

           }

        }

     } while(::FindNextFile(hFile, &FileInformation) == TRUE);

     // Close handle

     ::FindClose(hFile);

     DWORD dwError = ::GetLastError();

     if(dwError != ERROR_NO_MORE_FILES)

        return dwError;

  }

       return Rezu;

}

bool Filess::DeleteFileP(AnsiString Path)

{

       bool Rezu;

       if(GetFileAttributesA(Path.c_str()) & FILE_ATTRIBUTE_DIRECTORY)

       {

               AnsiString RootDirectory;

               RootDirectory = Path;

               this->RemoveDirectoryA(RootDirectory);

               SetFileAttributesA(Path.c_str(), FILE_ATTRIBUTE_NORMAL);

               RemoveDirectoryA(Path);

               Rezu = false;

       }

       else

       {

               SetFileAttributesA(Path.c_str(),FILE_ATTRIBUTE_NORMAL);

               Rezu = DeleteFileA(Path);

       }

       return Rezu;

}

bool Filess::RenameFileP(AnsiString Path, AnsiString NewName)

{

       bool Rezu;

       int i = Path.Length();

       while(Path[i] != '\\')

       {

               --i;

       }

       AnsiString NewPath = Path.SubString(1, i);

       NewPath += NewName;

       SetFileAttributesA(Path.c_str(),FILE_ATTRIBUTE_NORMAL);

       Rezu = RenameFile(Path, NewPath);

       return Rezu;

}

bool Filess::SetReadOnly(AnsiString Path)

{

       bool Rezu = true;

       Rezu = SetFileAttributesA(Path.c_str(), FILE_ATTRIBUTE_READONLY);

       return Rezu;

}

bool Filess::MoveFileP(AnsiString Dest_Path, AnsiString New_Path)

{

       bool Rezu = true;

       AnsiString NewPath = New_Path;

       if(!(GetFileAttributesA(New_Path.c_str()) & FILE_ATTRIBUTE_DIRECTORY))

       {

               int i = NewPath.Length();

               while(NewPath[i] != '\\')

               {

                       NewPath.Delete(i, 1);

                       --i;

               }

               NewPath.Delete(i, 1);

       }

       AnsiString DestPath = Dest_Path;

       int i = DestPath.Length();

       while(DestPath[i] != '\\')

       {

               --i;

       }

       NewPath = NewPath + "\\" + DestPath.SubString(i+1, DestPath.Length() - i);

       SetFileAttributesA(Dest_Path.c_str(),FILE_ATTRIBUTE_NORMAL);

       Rezu = MoveFileA(Dest_Path.c_str(), NewPath.c_str());

       return Rezu;

}

bool Filess::CopyFileP(AnsiString Dest_Path, AnsiString New_Path)

{

       bool Rezu = true;

       AnsiString NewPath = New_Path;

       if(!(GetFileAttributesA(New_Path.c_str()) & FILE_ATTRIBUTE_DIRECTORY))

       {

               int i = NewPath.Length();

               while(NewPath[i] != '\\')

               {

                       NewPath.Delete(i, 1);

                       --i;

               }

               NewPath.Delete(i, 1);

       }

       AnsiString DestPath = Dest_Path;

       int i = DestPath.Length();

       while(DestPath[i] != '\\')

       {

               --i;

       }

       NewPath = NewPath + "\\" + DestPath.SubString(i+1, DestPath.Length() - i);

       SetFileAttributesA(Dest_Path.c_str(),FILE_ATTRIBUTE_NORMAL);

       Rezu = CopyFileA(Dest_Path.c_str(), NewPath.c_str(), -1);

       return Rezu;

}

Класс, предназначенный для работы с сетью

 

Файл - .h

typedef struct ClientInfo{

       int Socket;

       AnsiString IPAddress;

       bool is_transperentfile;

}ClientInfo;

typedef struct W_Data

{

       int Len;

       AnsiString Prefix;

       AnsiString DData;

}W_Data;

typedef struct GetedData{

       AnsiString IPAddress;

       W_Data DData;

}GetedData;

typedef struct IWSDATA{

       int Version;

       int HVersion;

       AnsiString description;

}IWSDATA;

typedef class TSendFile:TThread

{

private:

       AnsiString PathFile;

       int hSocket;

       int SendFile();

       AnsiString Prefix;

       AnsiString getMessage(int Socket);

       bool sendMessage(int Socket, AnsiString msg);

       W_Data SepaGetedData(AnsiString DData);

protected:

       virtual void __fastcall Execute(void);

public:

       bool isTerminated;

       __fastcall TSendFile(int Socket, AnsiString Path, AnsiString Prefix);

}TSendFile;

typedef class WinSock

{

private:

       WSADATA LibraryInfo;

       int ListenSocket;

       ClientInfo* ClinetSockets;

       int CountClient;

       bool is_library_Opend;

       int MaxClientConected;

       bool OpenLibrary(int Version, int HVrsion);

       int CreateSocket(int Port, AnsiString IPAddress);

       bool SetPortListening(int Socket, int CountClient);

       void ShutDounSocket(int Socket);

       bool sendMessage(int Socket, AnsiString msg);

       AnsiString getMessage(int Socket);

       bool checkconection(int Socket);

       void remoovClient(int Index);

       AnsiString createcommand(AnsiString Prefix, AnsiString DData);

       W_Data SepaGetedData(AnsiString DData);

       TSendFile* NewSend;

public:

       bool isClientRedyToWork(AnsiString IPAddress);

       int time_out;

       int CheckConection();

       int GetSocketByIP(AnsiString IPAddress);

       bool SetClientFileBOOL(AnsiString IPAddress, bool ToSet);

       //******************************************

       int SendMessage(AnsiString Address, AnsiString DData, AnsiString Prefix);

       //0 – не найдено совпадений адреса

       //1 – Всё прошло успешно

       //-1 – Проблема с отправкой

       //******************************************

       int SendFile(AnsiString Path, AnsiString IPAddress, AnsiString Prefix);

       IWSDATA ViewSocketDllInfo();

       //******************************************

       AnsiString AddClien();

       //"-2" – Нет никого в очереди на добавление

       //"-1" – Проблема при добавлении

       //******************************************

       //******************************************

       GetedData GetMessageIfAny();

       //"-2" – Нет ничего в буфере

       //"-1" – Проблема при добавлении

       //******************************************

       AnsiString GetError();

       bool CreateServerSocket(int Port, AnsiString IPAddress);

       WinSock(int MaxCountClient);

       ~WinSock();

}WinSock;

Файл - .cpp

WinSock::WinSock(int MaxCountClient)

{

       if(this->OpenLibrary(2,0))

               this->is_library_Opend = true;

       else

               this->is_library_Opend = false;

       this->MaxClientConected = MaxCountClient;

       this->ListenSocket = INVALID_SOCKET;

       this->time_out = 100;

       this->CountClient = 0;

       this->NewSend = NULL;

}

WinSock::~WinSock()

{       if(this->ListenSocket != -1)

               this->ShutDounSocket(this->ListenSocket);

       WSACleanup();

       if(this->CountClient > 0)

       {

               delete this->ClinetSockets;

       }

       delete this->LibraryInfo.szDescription;

       delete this->LibraryInfo.szSystemStatus;

       delete this->LibraryInfo.lpVendorInfo;

}

bool WinSock::CreateServerSocket(int Port, AnsiString IPAddress)

{

       bool rezu = true;

       if(!this->is_library_Opend)

       {

           if(this->OpenLibrary(2,0))

               this->is_library_Opend = true;

       }

       this->ListenSocket = this->CreateSocket(Port, IPAddress);

       if(this->ListenSocket == INVALID_SOCKET)

       {

               rezu = false;

       }

       else

       {

               if(this->SetPortListening(this->ListenSocket,

                  this->MaxClientConected) == SOCKET_ERROR)

               {

                       this->ShutDounSocket(this->ListenSocket);

                       this->ListenSocket = INVALID_SOCKET;

                       rezu = false;

               }

       }

       return rezu;

}

void WinSock::ShutDounSocket(int Socket)

{

       shutdown(Socket,2);

       closesocket(Socket);

}

bool WinSock::SetPortListening(int Socket, int CountClient)

{

       bool Rezu = true;

       if(listen(Socket, CountClient) == SOCKET_ERROR)

       {

               Rezu = false;

       }

       return Rezu;

}

IWSDATA WinSock::ViewSocketDllInfo()

{

       IWSDATA Rezu;

       Rezu.Version = this->LibraryInfo.wVersion;

       Rezu.HVersion = this->LibraryInfo.wHighVersion;

       Rezu.description.sprintf(this->LibraryInfo.szDescription) ;

       return Rezu;

}

int WinSock::CreateSocket(int Port, AnsiString IPAddress)

{       int i_Socket=INVALID_SOCKET;

       sockaddr_in SAddr;

       i_Socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0 , 0, WSA_FLAG_OVERLAPPED);

       SAddr.sin_family = AF_INET;

       SAddr.sin_port = htons(Port);

       if(IPAddress == "255.255.255.255")

               SAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

       else

               SAddr.sin_addr.S_un.S_addr = inet_addr(IPAddress.c_str());

       if(bind(i_Socket, (SOCKADDR*)&SAddr, sizeof(SAddr)) == SOCKET_ERROR)

       {

               this->ShutDounSocket(i_Socket);

               i_Socket = INVALID_SOCKET;

       }

       return i_Socket;

}

void WinSock::remoovClient(int Index)

{

       ClientInfo* NewClient = new ClientInfo[this->CountClient - 1];

       this->ShutDounSocket(this->ClinetSockets[Index].Socket);

       for(int i = 0; i < Index; ++i)

       {

                       NewClient[i].Socket = this->ClinetSockets[i].Socket;

                       NewClient[i].IPAddress = this->ClinetSockets[i].IPAddress;

       }

       for(int i = Index+1; i < this->CountClient; ++i)

       {

               NewClient[i-1].Socket = this->ClinetSockets[i].Socket;

               NewClient[i-1].IPAddress = this->ClinetSockets[i].IPAddress;

       }

       delete this->ClinetSockets;

       this->CountClient -= 1;

       this->ClinetSockets = NewClient;

}

bool WinSock::checkconection(int Socket)

{

       bool Rezu = true;

       void* hEventClose = WSACreateEvent();

       WSAEventSelect(Socket, hEventClose, FD_CLOSE);

       if(WSAWaitForMultipleEvents(1, &hEventClose, 0, this->time_out, 0) == 0)

       {

               Rezu = false;

       }

       WSACloseEvent(hEventClose);

       return Rezu;

}

int WinSock::CheckConection()

{

       int Rezu = -1;

       for(int i = 0; i < this->CountClient; ++i)

       {

               ClientInfo OClient;

               OClient = this->ClinetSockets[i];

               if(!this->checkconection(OClient.Socket) )

               {

                       Rezu = i;

                       this->remoovClient(i);

                       break;

               }

       }

       return Rezu;

}

AnsiString WinSock::AddClien()

{

       AnsiString Rezu;

       void* hEventAdd = WSACreateEvent();

       WSAEventSelect(this->ListenSocket, hEventAdd, FD_ACCEPT);

       if(WSAWaitForMultipleEvents(1, &hEventAdd, 0, this->time_out, 0) == 0)

       {

               sockaddr_in SAddr;

               int iSAddr = 16;

               int NewSocket = accept(this->ListenSocket,(struct sockaddr *)&SAddr,&iSAddr);

               if(NewSocket == SOCKET_ERROR)

               {

                       Rezu = "-1";

               }

               else

               {

                       if(this->CountClient != this->MaxClientConected)

                       {

                               ClientInfo* Rab = new ClientInfo[this->CountClient + 1];

                               for(int i = 0; i < this->CountClient; ++i)

                               {

                                       Rab[i].Socket = this->ClinetSockets[i].Socket;

                                       Rab[i].IPAddress = this->ClinetSockets[i].IPAddress;

                               }

                               this->CountClient += 1;

                               Rab[this->CountClient-1].Socket = NewSocket;

                               Rab[this->CountClient-1].IPAddress = inet_ntoa(SAddr.sin_addr);

                               Rab[this->CountClient-1].is_transperentfile = false;

                               Rezu = Rab[this->CountClient-1].IPAddress;

                               if(this->CountClient > 1)

                               {

                                       delete this->ClinetSockets;

                               }

                               this->ClinetSockets = Rab;

                       }

               }

       }

       else

               Rezu = "-2";

       WSACloseEvent(hEventAdd);

       return Rezu;

}

bool WinSock::sendMessage(int Socket, AnsiString msg)

{

       int Rezu = true;

       int CountBytes = msg.Length();

       if(send(Socket, msg.c_str(), CountBytes,0) == -1)

       {

               Rezu = false;

       }

       return Rezu;

}

AnsiString WinSock::createcommand(AnsiString Prefix, AnsiString DData)

{

       AnsiString Rezu;

       Rezu.sprintf("%s %i %s",Prefix.c_str(), DData.Length(), DData.c_str());

       return Rezu;

}

W_Data WinSock::SepaGetedData(AnsiString DData)

{

       W_Data Rezu;

       AnsiString RLen;

       AnsiString DatRez;

       if(DData.Length() < 1000)

       {

               DatRez = DData;

               int Cnt = 0;

               while(Cnt != 2)

               {

                       if(DatRez[1] == ' ')

                               ++Cnt;

                       else

                               if(Cnt == 0)

                                       Rezu.Prefix += DatRez.SubString(1,1);

                               else

                                       RLen += DatRez.SubString(1,1);

                       DatRez.Delete(1,1);

               }

               Rezu.Len = atoi(RLen.c_str());

               if(DatRez.Length() > Rezu.Len)

               {

                       DatRez.Delete(Rezu.Len+1, DatRez.Length() - Rezu.Len);

               }

       }

       else

       {

               DatRez = "";

               Rezu.Len = DatRez.Length();

               Rezu.Prefix = "-ll";

       }

       Rezu.DData = DatRez;

       return Rezu;

}

bool WinSock::SetClientFileBOOL(AnsiString IPAddress, bool ToSet)

{

       bool Rezu = false;

       ClientInfo OClient;

       for(int i = 0; i < this->CountClient; ++i)

       {

               OClient = this->ClinetSockets[i];

               if(OClient.IPAddress == IPAddress)

               {

                       this->ClinetSockets[i].is_transperentfile = ToSet;

                       Rezu = true;

               }

       }

       return Rezu;

}

int WinSock::SendFile(AnsiString Path, AnsiString Address, AnsiString Prefix)

{

       int Rezu = 0;

       ClientInfo OClient;

       for(int i = 0; i < this->CountClient; ++i)

       {

               OClient = this->ClinetSockets[i];

               if(OClient.IPAddress == Address)

               {

                       this->ClinetSockets[i].is_transperentfile = true;

                       this->NewSend = new TSendFile(OClient.Socket, Path, Prefix);

                       Rezu = 1;

               }

       }

       return Rezu;

}

int WinSock::SendMessage(AnsiString Address, AnsiString DData, AnsiString Prefix)

{

       int Rezu = 0;

       ClientInfo OClient;

       for(int i = 0; i < this->CountClient; ++i)

       {

               OClient = this->ClinetSockets[i];

               if(OClient.IPAddress == Address)

               {

                       AnsiString DDataSend = this->createcommand(Prefix, DData);

                       if(this->sendMessage(OClient.Socket,DDataSend))

                               Rezu = 1;

                       else

                               Rezu = -1;

                       break;

               }

       }

       return Rezu;

}

AnsiString WinSock::getMessage(int Socket)

{

       AnsiString Rezu;

       char* GetedData = new char[1024];

       void* hEventRead = WSACreateEvent();

       WSAEventSelect(Socket, hEventRead, FD_READ);

       if(WSAWaitForMultipleEvents(1, &hEventRead, 0, this->time_out, 0) == 0)

       {

               if(recv(Socket, GetedData,1024, 0) == -1)

               {

                       Rezu = "-1";

               }

               else

               {

                       Rezu.sprintf(GetedData);

               }

       }

       else

       {

               Rezu = "-2";

       }

       delete GetedData;

       WSACloseEvent(hEventRead);

       return Rezu;

}

GetedData WinSock::GetMessageIfAny()

{

       GetedData Rezu;

       Rezu.IPAddress = "-2";

       AnsiString RRez;

       for(int i = 0; i < this->CountClient; ++i)

       {

               ClientInfo OClient;

               OClient = this->ClinetSockets[i];

               if(OClient.is_transperentfile)

               {

                       if(this->NewSend != NULL)

                       {

                               if(this->NewSend->isTerminated)

                               {

                                       delete this->NewSend;

                                       this->NewSend = NULL;

                                       this->ClinetSockets[i].is_transperentfile = false;

                               }

                       }

                       Rezu.IPAddress = "-2";

               }

               else

               {

                       RRez = this->getMessage(OClient.Socket);

                       if(RRez != "-1" && RRez != "-2")

                       {

                               Rezu.IPAddress = OClient.IPAddress;

                               Rezu.DData = this->SepaGetedData(RRez);

                               break;

                       }

                       else

                               Rezu.IPAddress = RRez;

               }

       }

       if(Rezu.IPAddress.Length() < 3)

       {

               Rezu.DData.Prefix = Rezu.IPAddress;

               Rezu.DData.DData = Rezu.IPAddress;

       }

        return Rezu;

}

bool WinSock::isClientRedyToWork(AnsiString IPAddress)

{

       ClientInfo OClient;

       for(int i = 0; i < this->CountClient; ++i)

       {

               OClient = this->ClinetSockets[i];

               if(OClient.IPAddress == IPAddress)

               {

                       return !OClient.is_transperentfile;

               }

       }

       return false;

}

int WinSock::GetSocketByIP(AnsiString IPAddress)

{

       ClientInfo OClient;

       for(int i = 0; i < this->CountClient; ++i)

       {

               OClient = this->ClinetSockets[i];

               if(OClient.IPAddress == IPAddress)

               {

                       return OClient.Socket;

               }

       }

       return -1;

}

bool WinSock::OpenLibrary(int Version, int HVrsion)

{

       bool rezu = true;

       if(WSAStartup(MAKEWORD(Version,HVrsion),&this->LibraryInfo) != 0)

       {

               rezu = false;

       }

       return rezu;

}

AnsiString WinSock::GetError()

{

       AnsiString strRezu;

       int CodeError = WSAGetLastError();

       switch(CodeError)

       {

               case 0:{

               strRezu = "Íåèçâåñòíàÿ îøèáêà";

                       break;}

               case WSAECONNREFUSED:{

               strRezu = "Â ñîåäèíåíèè îòêàçàíî.";

                       break;}

               case WSAEINPROGRESS:{

               strRezu = "Îïåðàöèÿ âûïîëíÿåòñÿ.";

                       break;}

               case WSAETIMEDOUT :{

               strRezu = "Âðåìÿ îæèäàíèÿ ñîåäèíåíèÿ èñòåêëî.";

                       break;}

               case WSAECONNABORTED :{

               strRezu = "Ïðîãðàììíîå îáåñïå÷åíèå âûçâàëî ïðåðûâàíèå ñâÿçè.";

                       break;}

               case WSAEHOSTUNREACH :{

               strRezu = "Íåò ïóòè ê õîñòó.";

                       break;}

               case WSAEMSGSIZE :{

               strRezu = "Ñëèøêîì äëèííîå ñîîáùåíèå.";

                       break;}

               case WSAESHUTDOWN :{

               strRezu = "Íå óäàåòñÿ îòïðàâèòü ïîñëå âûêëþ÷åíèÿ ñîêåòà.";

                       break;}

               case WSAENOTCONN :{

               strRezu = "Ñîêåò íå ñîåäåí¸í.";

                       break;}

               case WSAENETRESET :{

               strRezu = "Ñåòåâîå ñîåäåíåíèå îòñóòñòâóåò.";

                       break;}

               case WSASYSNOTREADY :{

               strRezu = "Íå äîñòóïíà ñåòåâàÿ ïîäñèñòåìà.";

                       break;}

               case WSAVERNOTSUPPORTED :{

               strRezu = "Íå äîïóñòèìàÿ âåðñèÿ áèáëèîòåêè.";

                       break;}

               case WSAEPROCLIM :{

               strRezu = "Ïåðåïîëíåíèå ïðîöåññîâ.";

                       break;}

               case WSAEWOULDBLOCK :{

               strRezu = "Ðåñóðñ âðåìåííî íå äîñòóïåí.";

                       break;}

               case WSAEINTR :{

               strRezu = "Âûçâàíî ïðåðûâàíèå ôóíêöèè.";

                       break;}

               case WSAECONNRESET :{

               strRezu = "Ñâÿçü îòìåíåíà êëèåíòîì.";

                       break;}

               case WSAEOPNOTSUPP :{

               strRezu = "Îïåðàöèÿ íå ïîääåðæèâàåòñÿ.";

                       break;}

               case WSAEISCONN:{

               strRezu = "Ñîêåò óæå ñîåäèí¸í.";

                       break;}

               case WSAENOTSOCK:{

               strRezu = "Îïåðàöèÿ íàä íåñóùåñòâóþùèì ñîêåòîì.";

                       break;}

               case WSAENOBUFS:{

               strRezu = "Íåò äîñòóïíîé áóôåðíîé ïàìÿòè.";

                       break;}

               case WSAEINVAL:{

               strRezu = "Íåâåðíûé àðãóìåíò.";

                       break;}

               case WSAEFAULT:{

               strRezu = "Íå âåðíûé àäðåñ.";

                       break;}

               case WSAEADDRNOTAVAIL:{

               strRezu = "Íåâîçìîæíî ïðèñâîèòü çàïðîøåííûé àäðåñ.";

                       break;}

               case WSAEADDRINUSE:{

               strRezu = "Àäðåñ óæå èñïîëüçóåòñÿ.";

                       break;}

               case WSAEACCES:{

               strRezu = "Äîñòóï çàïðåùåí.";

                       break;}

               case WSAENETDOWN:{

               strRezu = "Ñåòü îòêëþ÷åíà.";

                       break;}

               case WSANOTINITIALISED:{

               strRezu = "Íå âûïîëíåíà çàãðóçêà ñåòåâîé áèáëèîòåêè.";

                       break;}

               case WSAESOCKTNOSUPPORT:{

               strRezu = "Óêàçàííûé òèï ñîêåòà íå ïîääåðæèâàåòñÿ â ýòîì ñåìåéñòâå àäðåñîâ.";

                       break;}

               case WSAEPROTOTYPE:{

               strRezu = "Óêàçàí íåïðàâèëüíûé òèï ïðîòîêîëà äëÿ ýòîãî ñîêåòà.";

                       break;}

               case WSAEPROTONOSUPPORT:{

               strRezu = "Óêàçàííûé ïðîòîêîë íå ïîääåðæèâàåòñÿ.";

                       break;}

               case WSAEMFILE:{

               strRezu = "Áîëüøå íåò äîñòóïíûõ ñâîáîäíûõ ñîêåòîâ.";

                       break;}

               case WSAEPFNOSUPPORT:{

               strRezu = "Óêàçàííîå ñåìåñòâî àäðåñîâ íå ïîääåðæèâàåòñÿ.";

                       break;}

       }

       return strRezu;

}

//---------------------------------------------------------------------------

//***************************************************************************

//***************************************************************************

//***************************************************************************

//*****************_________Class TSendFile_____________*********************

//***************************************************************************

//***************************************************************************

__fastcall TSendFile::TSendFile(int Socket, AnsiString Path, AnsiString Prefix):TThread(false)

{

       this->hSocket = Socket;

       this->PathFile = Path;

       this->Prefix = Prefix;

}

W_Data TSendFile::SepaGetedData(AnsiString DData)

{

       W_Data Rezu;

       AnsiString RLen;

       AnsiString DatRez;

       if(DData.Length() < 1000)

       {

               DatRez = DData;

               int Cnt = 0;

               while(Cnt != 2)

               {

                       if(DatRez[1] == ' ')

                               ++Cnt;

                       else

                               if(Cnt == 0)

                                       Rezu.Prefix += DatRez.SubString(1,1);

                               else

                                       RLen += DatRez.SubString(1,1);

                       DatRez.Delete(1,1);

               }

               Rezu.Len = atoi(RLen.c_str());

               if(DatRez.Length() > Rezu.Len)

               {

                       DatRez.Delete(Rezu.Len+1, DatRez.Length() - Rezu.Len);

               }

       }

       else

       {

               DatRez = "Geted data with incorrect format";

               Rezu.Len = DatRez.Length();

               Rezu.Prefix = "-ss";

       }

       Rezu.DData = DatRez;

       return Rezu;

}

AnsiString TSendFile::getMessage(int Socket)

{

       AnsiString Rezu;

       char* GetedData = new char[1024];

       void* hEventRead = WSACreateEvent();

       WSAEventSelect(Socket, hEventRead, FD_READ);

       if(WSAWaitForMultipleEvents(1, &hEventRead, 0, 100, 0) == 0)

       {

               if(recv(Socket, GetedData,1024, 0) == -1)

               {

                       Rezu = "-1";

               }

               else

               {

                       Rezu.sprintf(GetedData);

               }

       }

       else

       {

               Rezu = "-2";

       }

       delete GetedData;

       WSACloseEvent(hEventRead);

       return Rezu;

}

bool TSendFile::sendMessage(int Socket, AnsiString msg)

{

       int Rezu = true;

       int CountBytes = msg.Length();

       if(send(Socket, msg.c_str(), CountBytes,0) == -1)

       {

               Rezu = false;

       }

       return Rezu;

}

int TSendFile::SendFile()

{

       int Rezu = true;

       HANDLE hFile=CreateFile(this->PathFile.c_str(),GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

       if(hFile != INVALID_HANDLE_VALUE)

       {

               _BY_HANDLE_FILE_INFORMATION lpFileInfo;

               GetFileInformationByHandle(hFile, &lpFileInfo);

               AnsiString Befor;

               Befor.sprintf(" %i sss", lpFileInfo.nFileSizeLow);

               AnsiString DataSend;

               DataSend = this->Prefix + Befor;

               this->sendMessage(this->hSocket, DataSend);

               AnsiString BufGet;

               BufGet = "-2";

               while(BufGet == "-2")

               {

                       BufGet = this->getMessage(this->hSocket);

               }

               if(BufGet != "-1")

               {

                       W_Data BFGT = this->SepaGetedData(BufGet);

                       if(BFGT.Prefix == "-tt")

                       {

                               if(TransmitFile(this->hSocket,hFile,0/*öåëåêîì*/,8192,NULL,NULL,TF_USE_SYSTEM_THREAD))

                                       Rezu = 1;

                               else

                                       Rezu = -1;

                       }

                       else

                               Rezu = 0;

               }

               else

               {

                       Rezu = -1;

               }

       }

       else

               Rezu = -2;

       CloseHandle(hFile);

       return Rezu;

}

void __fastcall TSendFile::Execute()

{

       this->SendFile();

       this->isTerminated = true;

       this->Terminate();

}


Клиентская часть приложения

Клиентская часть приложения

Серверная часть приложения

Запрос

Запрос

Ответ

Ответ

Начало

Ожидание прихода данных

Буфер пуст

Распознавание префикса

Поиск префикса в библиотеке

ыполнение команды

Да

Нет

Не найдено

Найдено

Да

Нет

Да

Нет

Отправка файла

Конец

Готов получить?

Анализ префикса

Буфер пуст

Ожидание прихода данных

Отправка сообщения о намерении передать файл

Начало

Да

Нет

Отобразить дерево файлов

Прогрузка дерева успешна?

Получение дерева

Сообщения об ошибочной попытке создания дерева

Начало

Запрос на получение дерева файлов от клиента

Ожидание формирования дерева клиентом

Сообщение о готовности дерева файлов

Конец

Оповещение об успешности или не успешности выполнения команды

Префикс, размер передаваемых данных или файла, который последует за данным сообщением, собственно данные

Да

Нет

Сообщение о разъединении

Удаление информации о клиенте

Произошло?

Ожидание события Disconnect

Для всех существующих сокетов

Начало

Приемник

Источник

typedef struct W_Data

{

       int Len; //Длинна данных

       AnsiString Prefix; // Префикс

       AnsiString DData; // Непосредственно данные

}W_Data;

      Информатика и системы управления

Программное обеспечение ЭВМ и информационные технологии

«Система удаленного управления компьютером»

 

 


 

А также другие работы, которые могут Вас заинтересовать

61550. Открытка ко Дню защитника Отечества 24.25 KB
  Цель: научить учащихся выполнять открытку в технике аппликации Задачи: Образовательные: обобщить знания о защитниках Отечества научить детей размечать детали по шаблону научить выполнять открытку научить вырезать...
61551. Открытка к 8 Марта 19.93 KB
  Педагогические задачи: Образовательные: закрепить навык разметки по шаблону закрепить навык работы с бумагой познакомить учащихся с историей праздника 8 Марта учить...
61553. Упражнение в склонении и определении падежей имён существительных 25.44 KB
  Цели урока: Образовательные: формировать умение учащихся изменять имена существительные по вопросам в единственном и множественном числе; ставить к имени существительному падежные вопросы и определять падеж имени существительного с помощью вопроса...
61555. Підготовка копютера до роботи 170.66 KB
  Мета: Познайомити учнів з можливостями компютера. Вчити користуватися пристроями компютера, вмикати та вимикати пристрій, користуючись кнопкою Роwer та компютерною мишею.
61556. Вплив куріння та алкоголю на здоровя 37.25 KB
  Навчати дітей приймати рішення що має менше негативних наслідків для здоров’я та життя в цілому. Привітання Треба всім нам привітатись: Добрий день Дружно весело сказати...
61558. Сила трения 19.75 KB
  Цель урока: познакомить учащихся с силой трения её видами и значением в жизни человека и природы слайд 2. А силу характеризующую это взаимодействие называют силой трения.