Программирование программ удаленного доступа

Делаем свой удалённый доступ к компьютеру

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

Программ для удалённого доступа много — недавно мы делали подборку. Проблема в том, что все они работают через чужой сервер. Если он перестанет работать, сервис закроется или решит уйти из России, удалённого управления не будет. Например, из России ушёл сервис TeamViewer — самый популярный сервис удалённого доступа.

Сегодня мы поднимем собственный сервер удалённого доступа, чтобы ни от кого не зависеть.

Что нам понадобится

Мы будем использовать RustDesk — бесплатную программу с открытым исходным кодом для удалённого управления компьютером. Её можно поставить на свой сервер и компьютеры и ни от кого не зависеть.

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

Читайте также:  Нейролингвистическое программирование повышение квалификации

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

У RustDesk есть и то и другое, поэтому установим всё по очереди.

Устанавливаем серверную часть

Чтобы установить что-то на сервер, нам нужно сначала получить к нему доступ. Чаще всего доступ к серверу настраивают по SSH и работают из командной строки, поэтому мы будем делать точно так же: подключимся к серверу и введём нужные команды.

👉 Если не знаете, как подключиться к своему серверу, прочитайте наш текст про SSH. О запуске собственного сервера мы писали в статье про Nextcloud.

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

Делаем свой удалённый доступ к компьютеру

Во время установки у нас спросят: IP или DNS — выбираем IP:

Делаем свой удалённый доступ к компьютеру

Дальше скрипт нам предложить скачать HTTP-сервер, который нужен для работы программы. Соглашаемся и вводим 1:

Делаем свой удалённый доступ к компьютеру

Когда всё будет готово, скрипт отдаст нам пароль администратора и публичны ключ — они нам понадобятся в будущем:

Делаем свой удалённый доступ к компьютеру

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

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

Делаем свой удалённый доступ к компьютеру

После запуска программа сразу предлагает настроить разрешение на снимки экрана и универсальный доступ (в Windows такого нет, там с этим всё проще):

Делаем свой удалённый доступ к компьютеру

Нажимаем «Настроить», заходим в системные настройки, нажимаем замочек внизу и ставим галочку напротив RustDesk:

Делаем свой удалённый доступ к компьютеру

Теперь укажем адрес нашей серверной части, которую мы установили раньше. Для этого нажимаем на три точки, выбираем «ID/Сервер трансляции» и вводим там IP-адрес нашего сервера. Он совпадает с адресом, по которому мы подключались по SSH, а ещё этот адрес сообщаем нам сам сервер при установке:

Делаем свой удалённый доступ к компьютеру Делаем свой удалённый доступ к компьютеру

Внизу сразу меняется статус подключения на «Готово» — это значит, что сервер и клиент нашли друг друга и готовы работать вместе.

Теперь точно так же устанавливаем и настраиваем эту программу на том компьютере, которым мы хотим удалённо управлять. После этого на одном из них вводим ID другого, нажимаем «Подключиться»:

Делаем свой удалённый доступ к компьютеру

Апскиллинг — это, например, переход с уровня junior на уровень middle, а потом — senior. У «Яндекс Практикума» есть курсы ровно для этого: от алгоритмов и типов данных до модных фреймворков.

Апскиллинг, как говорится Апскиллинг, как говорится Апскиллинг, как говорится Апскиллинг, как говорится

В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.

Источник

Удаленное управление компьютером по сети: Введение

Одно из самых известных приложений по удаленному управлению компьютером — TeamViewer. Займемся разработкой своего упрощенного аналога подобной клиент-серверной системы на C++ с использованием Qt. В этот раз решим подготовительные задачи по анализу и планированию того, что у нас должно получиться.

Удаленное управление в разрезе

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

Для серверной части основными являются следующие функции:

  1. Захват экрана и событий мыши;
  2. Трансляция по сети видео-потока для графического отображения событий, происходящих на экране;
  3. Воспроизведение полученных от удаленного клиента действий по перемещению/щелчкам мыши и нажатию клавиш клавиатуры.

Клиентской части характерны такие функции:

  1. Прием и воспроизведение видео-потока от удаленного источника (сервера) с визуальным представлением происходящего на экране;
  2. Передача на удаленный сервер событий мыши и клавиатуры по сети.

Схематично это можно представить следующим образом:

remote-control-client-server-thumbnail

Какие модули нам понадобятся

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

  1. InputRecorder — модуль записи видео-потока экрана, событий мыши и клавиатуры. Он нам понадобится как на клиентской, так и на серверной стороне;
  2. InputPlayer — модуль воспроизведения событий мыши и клавиатуры. Нужен на серверной стороне;
  3. RemoteControlServer — сервер удаленного управления;
  4. RemoteControlClient — клиент удаленного управления.

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

Для реализации клиент-серверного взаимодействия я планирую использовать библиотеку LibQxt. Она достаточно проста в использовании. А от сетевой части кроме примитивной передачи сообщений в Qt-приложении нам ничего и не требуется. Поэтому идем на компромисс, и жертвуем переносимостью в пользу более простой реализации.

Выводы

Мы готовы начать разработку. Но хочу предупредить, что, полноценный TeamViewer у нас все же не получится. Мы заведомо игнорируем многие важные вопросы. Например, безопасность, чтобы не усложнять реализацию шифрованием. Так же на практике могут возникнуть проблемы из области оптимизации передачи данных по сети (в первую очередь для видео-потока). Все это не входит в наши цели, поэтому мы закрываем глаза на подобные сложности. Но даже то, что остается, уже можно считать полноценным приложением, при разработке которого мы решим много интересных задач.

Источник

Пишем шустрый Remote — Desktop клиент на C# и XNA

Привет, я покажу, как написать Remote — Desktop клиент, используя C# + XNA

На написание этой статьи меня вдохновил вот этот топик

Немного от себя

Я очень долго ждал второй части той статьи, но так и не дождался. Как утверждал автор, во второй статье должна была быть реализация передачи изображения по протоколу UDP на удалённый клиент. После я пытался сам реализовать второю часть статьи, но всегда выходило плохо. Из — за медленного рисования GDI — программа просто зависала на компьютере Core 2 Duo 2.66 GHz, Nvidia GeForce 9600 GT. Я использовал разные алгоритмы оптимизации, но это слабо помогало и тогда я решил использовать XNA.

Выбор протокола передачи

Очень сильно хотелось выбрать протокол передачи TCP, с ним меньше проблем, но я выбрал UDP, потомучто все говорят, что для таких дел лучше его брать бла бла бла… Вам наверное интересно почему с UDP больше проблем? Ответ прост- UDP сообщение не может превысить размер в 65 507 байт, что очень не удобно. Наши пакеты составляют в среднем размер 130 000 байт (для экрана размером 1366×768), при попытке отправить такой пакет возникает ошибка, как показано ниже.

Решить эту проблему можно двумя путями:
1) Создать костыль
2) Создать структуру

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

2) Можно разбивать экран на множество кусочков и запоминать их координаты. Всё это надо будет хранить в структуре, что очень удобно, кстати, этот алгоритм поможет в будущем сделать оптимизацию.

Практика

Начну с простого. С отправителя. Отправлять мы будем скриншоты нашего экрана на удалённый компьютер. Я написал функцию для загрузки данных и инициализации некоторых переменных.

Точкой запуска будет наша функция Run()

 public void Run() < Load(); // Загружаем данные и получаем размер экрана udpClient = new UdpClient(); Bitmap BackGround = new Bitmap(width, height); Graphics graphics = Graphics.FromImage(BackGround); while (true) < // Получаем снимок экрана graphics.CopyFromScreen(0, 0, 0, 0, new Size(width, height)); // Получаем изображение в виде массива байтов byte [] bytes = ConvertToByte(BackGround); Listlst = CutMsg(bytes); for (int i = 0; i < lst.Count; i++) < // Отправляем картинку клиенту udpClient.Send(lst[i], lst[i].Length, ipEndPoint); >> > 

Сначала загружаются данные Load(), после происходит объявление переменных и зацикливание. В цикле мы получаем изображение экрана, конвертируем в массив байтов, используем мой костыль (разбиение сообщения на несколько под сообщений — CutMsg(bytes)), отправляем все пакеты.

В функции Load() ничего интересного не происходит.
Из файла ip.txt будут считываться две строки. Первая строка — IP адрес на который нужно отсылать данные. Вторая строка — Порт, на который будет происходить отсылка. Также там будет происходить получение длины и ширины экрана.

private byte [] ConvertToByte(Bitmap bmp) < MemoryStream memoryStream = new MemoryStream(); // Конвертируем в массив байтов с сжатием Jpeg bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg); return memoryStream.ToArray(); >

И самое интересное — реализация костыля.

private List CutMsg(byte[] bt) < int Lenght = bt.Length; byte[] temp; Listmsg = new List(); MemoryStream memoryStream = new MemoryStream(); // Записываем в первые 2 байта количество пакетов memoryStream.Write( BitConverter.GetBytes((short)((Lenght / 65500) + 1)), 0, 2); // Далее записываем первый пакет memoryStream.Write(bt, 0, bt.Length); memoryStream.Position = 0; // Пока все пакеты не разделили - делим КЭП while (Lenght > 0) < temp = new byte[65500]; memoryStream.Read(temp, 0, 65500); msg.Add(temp); Lenght -= 65500; >return msg; > 

Я делю данные по блокам 65500 (число взял меньше, чтобы явно попасть) и записываю их в лист массивов байтов, после я возвращаю этот лист.

Код получателя

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

Асинхронное получение данных.

int countErorr = 0; private void AsyncReceiver() < IPEndPoint ep = new IPEndPoint(IPAddress.Loopback, 0); while (true) < try < MemoryStream memoryStream = new MemoryStream(); byte[] bytes = udpClient.Receive(ref ep); memoryStream.Write(bytes, 2, bytes.Length - 2); int countMsg = bytes[0] - 1; if (countMsg >10) throw new Exception("Потеря первого пакета"); for (int i = 0; i < countMsg; i++) < byte[] bt = udpClient.Receive(ref ep); memoryStream.Write(bt, 0, bt.Length); >GetData(memoryStream.ToArray()); memoryStream.Close(); > catch < countErorr++; >> > 

Снова видим зацикливание, далее получаем первый пакет, с него считываем первый байт (в этом байте записано количество будущих сообщений), если длина сообщения больше 10, то первый пакет мы явно потеряли, следовательно прибавим счётчик потерь, иначе получаем все сообщения — склеиваем в одно и вызываем событие GetData(byte []).

В GetData(byte[]) мы получаем Texture2D, конвертируя её из массива байтов.

private void Receive_GetData(byte[] Date) < BackGround = ConvertToTexture2D(Date); >private Texture2D ConvertToTexture2D(byte[] bytes) < MemoryStream memoryStream = new MemoryStream(bytes); System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(memoryStream); // Конвертируем картинку в .png, потомучто Texture2D ест только его memoryStream = new MemoryStream(); bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); // Получаем из потока Texture2D return Texture2D.FromStream(GraphicsDevice, memoryStream); >

Весь проект вы сможете скачать в конце статьи, что так не отчаивайтесь если что — то я не написал.

Итоги и вывод

В итоге при одновременном запуске «отправителя» и «получателя» на своём компьютере происходит рекурсия и огромное количество потерь (30 — 90 потерь), при запуске «отправителя» на моём компьютере, а на компьютере родителей «получателя», потерь минимум (10 — 15 потерь). Оба компьютера (родителей и мой) соединены в одну Wi-Fi сеть с каналом 54 Мбит/с. Есть пинг (около 250 мс.) — напоминает по пингу TeamViewer. Если добавить оптимизацию и заменить костыль, то получится отличная программа для передачи изображения.

Рекурсия

Компьютер родителей (передача изображения с моего компьютера на их)

Как выглядит потеря

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

Скачать проект
Скачать Receiver (Получает изображения)
Скачать Sender (Отправляет изображения)

Источник

Оцените статью