Чтение онлайн

на главную - закладки

Жанры

Шрифт:

11.3. Слежение за компьютером по сети

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

Серверная программа предварительно запускается на наблюдаемом компьютере. В этом примере программа-сервер позволяет клиентской программе получать следующие сведения о компьютере, на котором она (программа-сервер) запущена:

• разрешение монитора;

• глубину цвета для монитора;

• полноразмерную копию экрана;

• копию экрана, уменьшенную (или увеличенную) до заданных размеров.

Для получения указанных сведений программа-клиент должна послать серверу следующие строковые значения:

• get_screen_width – для получения ширины и get_screen_height – для получения высоты экрана в пикселах;

• get_screen_colors – для получения значения установленной для монитора глубины цвета (бит на точку);

• get_screen – для получения полноразмерной копии экрана;

• get_screen: X, Y – для получения копии экрана, приведенной к размеру Хх Y.

Сначала рассмотрим реализацию сервера (проект SpyServer). Весь код, обеспечивающий работу сервера, помещен в модуле Unitl. pas формы Forml. Обработчик запросов клиентов – главная процедура для сервера – приводится в листинге 11.3.

...

Листинг 11.3.

Обработчик клиентских запросов

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);

var

strText: string;

width, height, i: Integer;

dc: HDC;

begin

//Принимаем от клиента строку

strText := AThread.Connection.ReadLn;

//Определяем, что нужно выполнить

if (strText = \'get_screen_height\') then

//Возвратим высоту экрана

Athread.Connection.WriteInteger(Screen.Height)

else if (strText = \'get_screen_width\') then

//Возвратим ширину экрана

Athread.Connection.WriteInteger(Screen.Width)

else if (strText = \'get_screen_colors\') then

begin

//Возвратим количество бит на точку

dc := GetDC(0);

Athread.Connection.WriteInteger(GetDeviceCaps(dc,

BITSPIXEL));

ReleaseDC(0, dc);

end

else if (strText = \'get_screen\') then

//Возвратим полноразмерную копию экрана

SendScreen(Screen.Width, Screen.Height, AThread.Connection)

else begin //строка вида \'get_screen:x,y\'

//Определим значения высоты и ширины,

//переданные пользователем

strText := Copy(strText, 12,Length(strText)-11);

i := Pos(\',\', strText); //Положение запятой

width := StrToInt(Copy(strText, 1, i-1));

height := StrToInt(Copy(strText, i+1, Length(strText)-i));

//Возвратим копию экрана

SendScreen(width, height, AThread.Connection);

end;

end;

Используемая в листинге 11.3 процедура SendScreen, отправляющая клиенту копию экрана, приведена в листинге 11.4.

...

Листинг 11.4.

Снятие копии экрана

//Процедура снимает копию экрана, приводит полученное

//изображение к заданному размеру и отправляет

//преобразованное изображение клиентской программе

procedure SendScreen(width: Integer; height: Integer;

Connection: TIdTCPServerConnection);

var

ScreenCopy: TCanvas;

gr: TBitmap;

stream: TMemoryStream;

rcDest, rcSource: TRect;

begin

rcDest := Rect(0, 0, width, height); //Конечный размер

//изображения

rcSource := Screen.DesktopRect; //Исходный размер

//изображения

//Создаем канву и присоединяем ее к контексту Рабочего стола

ScreenCopy := TCanvas.Create;

ScreenCopy.Handle := GetDC(0);

//Создаем объект для хранения копии экрана

//и копируем изображение

gr := TBitmap.Create;

gr.Height := height;

gr.Width := width;

gr.Canvas.CopyRect(rcDest, ScreenCopy,rcSource);

ReleaseDC(0, ScreenCopy.Handle);

//Сохраняем изображение в поток данных

stream := TMemoryStream.Create;

gr.SaveToStream(stream);

//Отправляем изображение клиенту

Connection.WriteStream(stream,True,True);

stream.Clear;

stream.Free;

gr.Free;

end;

Как можно увидеть, даже самая сложная операция рассматриваемого сервера копирование изображения – реализуется довольно просто благодаря наличию такого стандартного класса, как TMemoryStream.

При реализации сервера использован таймер. Он применен для скрытия формы сервера сразу при запуске приложения (не забудьте установить значения его свойств Enabled = True и Interval = 50). Компонент IdTCPServer (с именем IdTCPServerl) в этом примере присоединен к порту 12341 (не забудьте также установить свойство Active = True).

Теперь о реализации клиентского приложения (проект SpyClient). Внешний вид формы (Forml) клиента во время работы приводится на рис. 11.5 (видно, что пользователь наблюдаемого компьютера только что проиграл в игру Сапер ).

Рис. 11.5. Внешний вид клиента слежения

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

Работа клиентского приложения начинается с соединения с сервером. Код, отвечающий за эту операцию, приведен в листинге 11.5.

...

Листинг 11.5. Соединение с сервером

procedure TForm1.cmbConnectClick(Sender: TObject);

begin

if (cmbConnect.Caption = \'Подключиться\') then

begin

if (txtServer.Text = \'\') then

//Не введено имя сервера

MessageDlg(\'Введите имя машины-сервера в текстовое поле\',

mtInformation, [mbOK], 0)

else begin

//Подключаемся к серверу

IdTCPClient1.Host := txtServer.Text;

try

IdTCPClient1.Connect;

except

MessageDlg(\'Не удается соединиться с указанным сервером\',

mtError, [mbOK], 0);

Exit;

end;

end

end

else begin

//Отключаемся от сервера

IdTCPClient1.Disconnect;

end;

end;

Если соединение с сервером произошло успешно, то выполняется обработчик TForml. IdTCPClientlConnected, подготавливающий приложение-клиент к периодическим запросам данных с сервера (листинг 11.6).

...

Листинг 11.6.

Действия, выполняемые при соединении с сервером

procedure TForm1.IdTCPClient1Connected(Sender: TObject);

begin

txtServer.Enabled := False;

cmbConnect.Caption := \'Отключиться\

//Начинаем периодически запрашивать данные с сервера

Timer1.Enabled := True;

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

Timer1Timer (Nil);

end;

При отсоединении от сервера также выполняются действия, прекращающие периодические запросы данных и переводящие клиент в состояние ожидания подключения (первоначальное состояние программы) (листинг 11.7).

...

Листинг 11.7.

Действия при отсоединении от сервера

procedure TForm1.IdTCPClient1Disconnected(Sender: TObject);

begin

txtServer.Enabled := True;

cmbConnect.Caption := \'Подключиться\

Timer1.Enabled := False;

end;

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

...

Листинг 11.8.

Запрос и обработка данных, полученных с сервера

procedure TForm1.Timer1Timer(Sender: TObject);

var

stream: TMemoryStream;

begin

//Запрашиваем у сервера данные о наблюдаемом компьютере

with (IdTCPClient1) do

begin

//…разрешение

WriteLn(\'get_screen_width\');

WriteLn(\'get_screen_height\');

lblResolution.Caption := IntToStr(ReadInteger) + \'x\' +

IntToStr(ReadInteger);

//…глубина цвета

WriteLn(\'get_screen_colors\');

lblColors.Caption := IntToStr(ReadInteger);

//…копия экрана

//.....первый вариант – копирование экрана без сжатия

WriteLn(\'get_screen\');

//.....второй вариант – сжатие на стороне сервера

WriteLn(\'get_screen:\' + IntToStr(imgScreen.Width) + \',\' +

IntToStr(imgScreen.Height));

//....получаем данные

stream := TMemoryStream.Create;

ReadStream(stream);

stream.Position := 0;

//....формируем изображение

imgScreen.Picture.Bitmap.LoadFromStream(stream);

stream.Clear;

stream.Free;

end;

end;

Поделиться:
Популярные книги

Разведчик. Заброшенный в 43-й

Корчевский Юрий Григорьевич
Героическая фантастика
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.93
рейтинг книги
Разведчик. Заброшенный в 43-й

Точка Бифуркации IV

Смит Дейлор
4. ТБ
Фантастика:
героическая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации IV

Отряд

Валериев Игорь
5. Ермак
Фантастика:
альтернативная история
5.25
рейтинг книги
Отряд

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Дважды одаренный. Том VIII

Тарс Элиан
8. Дважды одаренный
Фантастика:
боевая фантастика
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Дважды одаренный. Том VIII

Убивая маску

Метельский Николай Александрович
13. Унесенный ветром
Фантастика:
боевая фантастика
5.75
рейтинг книги
Убивая маску

Кодекс Охотника. Книга XXXVI

Винокуров Юрий
36. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVI

Газлайтер. Том 39

Володин Григорий Григорьевич
39. История Телепата
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 39

Рассвет русского царства 3

Грехов Тимофей
3. Новая Русь
Фантастика:
историческое фэнтези
альтернативная история
5.00
рейтинг книги
Рассвет русского царства 3

Революция

Валериев Игорь
9. Ермак
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Революция

Камень. Книга восьмая

Минин Станислав
8. Камень
Фантастика:
фэнтези
боевая фантастика
7.00
рейтинг книги
Камень. Книга восьмая

Инкарнатор

Прокофьев Роман Юрьевич
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Инкарнатор

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Инженерный Парадокс

Cyberdawn
1. Инженерный Парадокс
Фантастика:
боевая фантастика
аниме
фэнтези
5.00
рейтинг книги
Инженерный Парадокс