Дані методичні вказівки містять рекомендації для студентів щодо виконання лабораторних робіт з дисципліни "Операційні системи компьютерних мереж". Передбачається знання студентами теоретичного матеріалу з основних функцій мови високого рівня Сі. До кожної лабораторної роботи додаються короткі теоретичні відомості, необхідні для її виконання, контрольні запитання, на які студент повинен дати відповідь під час захисту роботи, варіанти завдань, список рекомендованої літератури.
Лабораторна робота №1
Знайомство з операційною системою Unix (Linux, FreeBSD), реєстрація користувача
Мета роботи: ознайомити студентів з операційною системою Unix (Linux, FreeBSD) на рівні користувача (робота з файлами і каталогами) та з текстовим редактором vi.
Загальні відомості
UNIX є однією з найбільш вдалих операційних систем за всю історію розвитку комп'ютерної техніки [1]. Це єдина система, яка створена без будь-яких вимог до підтримки старого програмного забезпечення. Принцип найскорішого застосування та розвитку всіх її новітніх технологій зберігається й по теперішній час.
UNIX сьогодні - це найпотужніша 32- або 64-розрядна багатозадачна, багатокористувачева, високопродуктивна та високонадійна операційна система мережі. Жодна з існуючих на сьогоднішній день інших операційних систем не може перевищити усіх вишеперерахованих показників.
UNIX була першою операційною системою, побудованою за модульним принципом. Мінімізоване ядро системи знаходиться в оперативній пам'яті комп'ютера і не виконує жодної безпосередньої функції користувача. Для продуктивної роботи між користувачем і ядром системи існує багато модулів, які виконують ролі посередників.
Ядро має обмежений і строго оптимізований набір системних програм, які керують базовими ресурсами комп'ютерної системи. Такий підхід дає можливість дуже вдало будувати відношення між користувачем та системою, додаючи, при необхідності, окремі модулі для обслуговування нових вимог клієнтів. У цьому випадку ядро бере на себе диспетчерські функції: розподілення пам'яті, контроль доступу до системних ресурсів і таке інше. Крім того, у ядрі UNIX знаходяться важливі системні таблиці, необхідні для побудови зв'язаних програмних ланцюжків.
Вхід до системи
Вхід до системи здійснюється на початку кожного сеансу роботи за терміналом і дає можливість користувачу ідентифікувати себе для ведення обліку використання обчислювального комплексу.
Для реєстрації в системі користувачу необхідно задати своє вхідне ім'я (login) та пароль (password).
З метою убезпечення від несанкціонованого входу до системи іншого користувача, існує можливість змінювати свій пароль через певний час. Так, при використанні команди passwd (зміна пароля) система спочатку запитає стару послідовність символів, а потім задається нова комбінація. Після першого запиту виконується перевірка на відповідність нового пароля технічним вимогам. Якщо така відповідність існує, система запитає іншу копію нового пароля, потім копії порівнюються. У випадку невідповідності нових копій, цикл введення паролей буде повторений.
Технічні вимоги до паролей
Кожний пароль повинен мати не менше 6-ти символів. У випадках, коли послідовність символів перевишує 6, - значущими є тільки перші 8;
Кожен пароль повинен мати, як мінімум, дві букви (велику чи маленьку) та одну цифру або знак;
Кожен пароль повинен відрізнятися від вхідного імені (login'у), яке прочитане зліва направо або навпаки, та від циклічних зсувань вхідного імені;
Новий пароль повинен відрізнятись від попереднього хоча б трьома знаками (не враховуючи регістру великих та маленьких букв).
При виконанні багатьох робіт в операційній системі Unix важливо вміти користуватися деякими основними командами маніпулювання з файлами та каталогами.
До таких команд відносяться:
роздрук змісту каталогу
наприклад: ls -l /home/usr1
роздрук змісту каталогу /home/usr1 користувача usr1
копіювання файлів
наприклад: cp Mydocument /usr/doc/
копіювання файла Mydocument у каталог /usr/doc/
зміна назви файла
наприклад: mv Mydocument MyNewdocument
зміна назви файла Mydocument на MyNewdocument
створення каталогу
наприклад: mkdir NewDirectory
створення каталогу NewDirectory
вилучення каталогу
наприклад: rmdir OldDirectory
вилучення каталогу OldDirectory
зміна назви каталогу
наприклад: mvdir OldDirectory NewDirectory
зміна назви каталогу OldDirectory на NewDirectory
роздрук змісту файла
наприклад: cat MyNewFile або less MyNewFile
роздрук змісту файла MyNewFile
Основні режими редактора vi:
командний режим (зразу після входу у редактор);
порядкового редагування;
режим редагування.
Основні команди редактора vi:
а,і,о - вхід до режиму редагування,
ZZ - вихід з редактора з записом,
esc - вхід до командного режиму,
: - вхід до режиму порядкового редагування,
:wq - вихід з редактора з записом,
:q! - вихід з редактора без запису,
enter - вхід до режиму командного режиму з порядкового
редагування,
h чи стрілка вліво - перехід на знак ліворуч,
l чи стрілка вправо - перехід на знак праворуч,
j чи стрілка вниз - перехід на рядок вниз,
k чи стрілка вверх - перехід на рядок вверх,
Ctrl - F - перехід на екран вверх,
Ctrl - B - перехід на екран вниз,
х - вилучає знак у командному режимі,
(n) - коефіцієнт повторення (встановлюється перед вилученням,
копіюванням, і т.ін.)
(n)х - вилучає n знаків у командному режимі,
dd - вилучає рядок у командному режимі,
(n)dd - вилучає n рядків у командному режимі,
сс - заміна рядка з командного режиму (переходом до режиму
введення і вилучення тексту з рядка)
u - відміна останньої операції,
p - розташовування поперед курсора активного або вилученого
тексту,
(n)dd p - переміщення n рядків,
(n)уу p - копіювання n рядків.
Редактор vi вважається першим і найпродуктивнішим редактором в операційній системі UNIX. Існуюча величезна кількість команд також дозволяє виконувати однакові операції за допомогою різних команд. Це зроблено як для зручності при роботі на різних апаратних платформах, так і для задоволення різного смаку користувачів.
Контрольні питання
Перерахуйте технічні вимоги щодо паролей.
Назвіть основні команди роботи з файлами та каталогами, їх застосування.
Назвіть основні режими та команди роботи з редактором vi.
Завдання
1.Зареєструватись в операційній системі як користувач (ім'я та пароль візьміть у викладача);
Замінити пароль:
за допомогою простого пароля (наприклад 123456)
за допомогою отриманого у викладача пароля зі зміною двох символів;
за допомогою введення складного пароля (наприклад ReW#2z)
Одержати у викладача контрольну картку по основних командах маніпулювання з файлами та каталогами;
Одержати у викладача контрольну картку по основних командах редактора vi;
Підготувати звіт по лабораторній роботі.
Зміст звіту:
короткі відповіді на контрольні питання;
призначення описаних команд операційної системи Unix;
призначення основних команд редактора vi.
Лабораторна робота №2
Компіляція, налагодження, трасування Сі-програм
Мета роботи: ознайомити з компіляцією, написанням та налагоджування Сі-програм в оперативній системі UNIX.
Загальні відомості
Сі-компілююча система складається з компілятора, асемблера та редактора зв'язків. Коли користувач виконує компіляцію за допомогою командного рядка, то кожен з цих компонент виконується послідовно:
Сс -o MyProgram MyProgram.c
Виконувана Сі-програма створюєтся у три етапи:
початковий текст програми обробляється препроцесором, котрий виконує відповідні підстановки для таких рядків, як #include, #define і т.і.;
компілятор виконує трасування Сі-програми та переведе її з початкового коду в асемблерний;
асемблер транслює програму в машинні інструкції комп'ютера для безпосереднього виконання. При цьому формується об'єктний модуль, який є вхідним файлом для редактора зв'язку;
редактор зв'язку приєднує один чи декілька об'єктних файлів (отриманих в результаті компіляцій) до завантажувального модуля і автоматично слідкує за всіма зовнішніми посиланнями у програмах та підключанням їх до бібліотечних модулів.
В результаті цього формується виконуваний файл з ім'ям за замовчуванням a.out. Наприклад:
cc MyFile.c
Користувач може змінити назву файла:
mv a.out MyCompileFile
або вказати у командному рядку ключ -о:
cc -o MyFile MyFile.c
У випадку роботи з математичними функціями:
сс -lm -o MyFile MyFile.c
Для виконання налагоджувальних робіт, необхідно при компіляції залишати таблицю:
сс -g -o MyFile MyFile.c
Для розробки програми на мові високого рівня Сі слід набути елементарні поняття про структуру програми та основні функції (вираз, формат, вкладеність, складовий оператор).
Вираз - структурна одиниця програми, яка складається з одного чи більшої кількості операндів і символів операцій.
Наприклад: а++; в=10; x=(y*z)/w
Арифметичні операції: i=j+2; last=arname + arsize - 1;
Операції відношення: if (i==0) break;
while (i!=3) i=func();
if (x<0) printf("negative");
Логічні операції: if(!good) printf("not good");
if (x<A || x>B) printf("out of ragne");
Побітові операції: opposite=x>>3;
Інші операції, наприклад: abs=(i<=0)? -i:i;
Формат - це структура, яка складається з одного оператора, який займаює один чи більше рядків. Два чи більше операторів можуть бути розташовані в одному рядку.
Вкладеність - це метод обробки операторів, які управляють порядком виконання операцій (if, if-else, switch, while, do-while та for). Вони можуть бути вкладені один в один.
Складний оператор (блок) - це структура, яка складається з одного чи більшої кількості операторів різного типу, які заключаються у фігурні дужки.
Наприклад: {x=1; y=2; z=3}
Функції (стандартні):
- форматоване введення-виведення (fprintf, printf, scanf, fscanf і т.і.), наприклад:
printf("%6.3f", 65.37);
- введення-виведення рядків (gets, fgets, put, fputs і т.і.), наприклад:
fgets(Line[i], LINESIZE, stdin);
Існує величезна кількість інших стандартних функцій: доступу до файлів та каналів, обробки і перетворення рядків, доступу до аргументів та розподілу пам'яті і т.п.
Саме мова високого рівня Сі надає можливість поширеного використання функцій користувача, наприклад:
void errmesg(s)
char *s;
{
printf("\nError message is: %s\n", s);
}
Найпростіша програма на мові високого рівня Сі може виглядати таким чином:
#include <stdio.h>
main()
{
printf("This is a test message…\n");
}
Компілююча система Сі дозволяє користувачу уникнути синтаксичних помилок. За допомогою налагоджувача gdb в багатьох випадках користувач може уникнути логічних помилок. Викликатись налагоджувач може так:
gdb MyProgram
До основних команд налагоджувача відносяться:
run команда запуску,
break (n) команда встановлення точки зупинки,
наприклад break 20
встановлення точки зупинки на 20 рядку програми,
continue команда продовження,
step (n) команда продовження виконання на n кроків,
наприклад step 3
продовження виконання програми на 3 кроки,
clear (n) команда вилучення точки зупинки,
наприклад clear 34
вилучення точки зупинки на 34 рядку,
print db команда роздруку змісту змінної,
наприклад print var_list7
роздрук змісту змінної var_list7,
help команда отримання довідкової інформації.
Існуює багато інших команд та модифікацій вищеперерахованих. З деякими з них можна познайомитись за допомогою довідкової системи та інших матеріалів.
Контрольні питання
З яких компонентів складається Сі-компілююча система.
З яких етапів складається виконувана Сі-програма.
Які Ви знаєте опції компіляції програм з математичними модулями та налагоджувальними таблицями.
Назвіть основні відомі функції мови високого рівня Сі.
Назвіть основні команди налагоджувача gdb.
Завдання
Написати за допомогою текстового редактора vi програму обчислення коренів квадратного рівняння (ах2+вх+с=0). Здійснити цикл розгалуження при значенні дискримінанта більшим 0, рівним 0 та меншим 0. Коефіцієнти а, в, с одержати у викладача.
У режимі налагоджувача роздрукуйте значення дискримінанта.
Підготувати звіт по лабораторній роботі.
Зміст звіту:
короткі відповіді на контрольні питання;
призначення програми;
алгоритм і текст програми.
Лабораторна робота №3
Знайомство з основними механізмами реалізації технології "клієнт-сервер" в ОС Unix, робота з неіменованими каналами
Мета роботи: ознайомити з основними механізмами реалізації новітніх технологій ("клієнт-сервер"), розбір програми роботи з неіменованими каналами.
Загальні відомості
На сьогоднішній день ключовими компонентами в галузі створення передових комп'ютерних технологій є технологія "клієнт-сервер". Ця універсальна модель служить основою побудови будь-яких складних систем, у тому числі, і мережних. Розробники систем керування базами даних, комунікаційних систем, систем електронної пошти, банківських систем і т.ін. у всьому світі використовують цю технологію. В даному випадку операційна система Unix є для розробників системного та прикладного програмування ідеальним засобом, який найбільш повно відповідає вимогам "клієнт-сервер" і далеко залишає позаду своїх конкурентів. Для побудови моделі типу "клієнт-сервер" в Unix існує багато механізмів, які реалізуються за допомогою:
сигналів,
семафорів,
програмних каналів,
черг повідомлень,
сегментів поділяємої пам'яті,
спеціальних команд (write, cu, mail),
засобів міжкомп'ютерних взаємодій (uucp, tcp/ip, nfs, rfs).
Ознайомимось з деякими з них більш детально.
Одну з центральних позицій при реалізації моделі типу "клієнт-сервер" займають програмні канали. Вони були створені як засіб обміну потоками інформації між процесами, тобто коректної взаємодії між різними завданнями в операційній системі.
На фізичному рівні програмні канали являють собою спеціальні файли, до яких можна писати будь-яку інформацію або читати з них. Вибірка та розташування інформації в таких особливих файлах відбувається за принципом FIFO (First In/First Оut, Першим Зайшов/Першим Вийшов).
Після створення програмного каналу і початку роботи з ним система забезпечує зупинку процесів (котрі працюють з каналом), якщо він заповнений (у більшості випадків 4096 байт). Це означає, що при запису операція write виконується успішно, якщо в каналі наявне вільне місце, або переходить до стану очікування, якщо об'єм створеної інформації перевищує надані розміри.
При введенні/виведенні завжди використовується потокова модель даних. Це означає, що дані, які передаються через програмні канали, ніяк не інтерпретуються (обробляються). Довжина повідомлень не контролюється. Відразу декілька "процесів-клієнтів" мають змогу бути записаними до каналу, а один "процес-сервер" може їх читати та робити обмін повідомленнями зі своїми клієнтами тим же чином. При цьому повідомлення ніяк не відокремлюються один від одного - сервер сам повинен визначати, хто з клієнтів до нього звертається і яке повідомлення надіслав до нього.
Неіменовані канали можуть встановити зв'язок тільки між процесами, які народжені одним початковим процесом. В цьому випадку народжені процеси одержують в спадок дескриптор відкритого каналу і одержують можливість бути записаними до каналу і читати з нього будь-яку інформацію (рис. 3.1.).
Первісний
процес
Народжений
процес
Створення Створення каналу
каналу (закриття (закриття каналу за
каналу за дескрип- дескриптором 0)
тором 1)
Неіменований
програмний канал
Рис. 3.1. Взаємодії між процесами і створеним каналом
Процес має можливість встановити декілька програмних каналів таким чином, що дані будуть проходити у вигляді лінійних або мережних структур (рис. 3.2.).
Вхід
Вихід
Вхід
Рис. 3.2. Можливість проходження даних у вигляді лінійних та мережних структур
В операційній системі Unix подібні механізми конвеєрної обробки інформації дуже поширене явище. Наприклад, командна послідовність proc1 | proc2 | proc3 визначається як декілька процесів, які мають програмні канали від proc1 до proc2 та від proc2 до proc3.
За допомогою команд Unix також можна реалізувати мережну структуру (рис. 3.3.) такої послідовності:
сat veglist | sort | tee sortlist | lpr
1
2
4
Вхід Вихід
3
Рис. 3.3. Структура проходження даних за допомогою програмних каналів у мережі.
В цьому прикладі роздруковується зміст файла veglist у програмний канал (блок 1), після цього сортуються рядки (блок 2), записуються до файла sortlist та друкуються на принтері (блок 4).
Для того, щоб створити окремий процес (рис. 3.1.), необхідно використати функцію fork(програма 3.1, рядки 11-15.).
Неіменований канал створюється за допомогою функції pipe(fdptr) (програма 3.1, рядок 10), де
fdptr - це показник масиву двох цілих чисел для розміщення дескриптора читання (за допомогою функції read) та запису (за допомогою функції write) до програмного каналу.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "This is a test string…\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Народжений процес закриває вхід до каналу */
close(fd[0]);
/* Введений рядок */
write(fd[1], string, strlen(string));
exit(0);
}
else
{
/* Первісний процес закриває вхід до каналу */
close(fd[1]);
/* Читання рядка через канал */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}