- •Практичне заняття 10
- •Сокети (sockets) в unix і основи роботи з ними.
- •Системні виклики sendto() і recvfrom()
- •Визначення ip-адрес для обчислювального комплексу
- •Приклад програми udp-клієнта
- •Приклад програми udp-серверу
- •Організація зв'язку між процесами за допомогою установки логічного з'єднання
- •Встановлення логічного з'єднання. Системний виклик connect()
- •Приклад програми tcp-клієнта
- •Як відбувається встановлення віртуального з'єднання
- •Системний виклик listen()
- •Системний виклик accept()
- •Приклад простого tcp-серверу
- •Вживання інтерфейсу мережних викликів для інших сімейств протоколів. Unix Domain протоколи. Файли типу "сокет"
Як відбувається встановлення віртуального з'єднання
Протокол TCP є надійним дуплексним протоколом. З погляду користувача робота через протокол TCP виглядає як обмін інформацією через потік даних. Усередині мережних частин операційних систем потік даних відправника нарізається на пакети даних, які, власне, подорожують по мережі і на машині-одержувачі знов збираються у вихідний потік даних. В лекції 4 мова йшла про те, яким чином може забезпечуватися надійність передачі інформації в засобах зв'язку, що використовують в своїй основі передачу пакетів даних. В протоколі TCP використовуються прийоми нумерації передаваних пакетів і контролю порядку їх отримання, підтвердження про прийом пакету з боку одержувача і щодо контрольних сум за передаваною інформацією. Для правильного порядку отримання пакетів одержувач повинен знати початковий номер першого пакету відправника. Оскільки зв'язок є дуплексним, і в ролі відправника пакетів даних можуть виступати обидві взаємодіючі сторони, вони до передачі пакетів даних повинні обмінятися, принаймні, інформацією про їх початкові номери. Узгодження початкових номерів відбувається за ініціативою клієнта при виконанні системного виклику connect().
Для такого узгодження клієнт посилає серверу спеціальний пакет інформації, який прийнято називати SYN (від слова synchronize – синхронізувати). Він містить, як мінімум, початковий номер для пакетів даних, який використовуватиме клієнт. Сервер повинен підтвердити отримання пакету SYN від клієнта і відправити йому свій пакет SYN з початковим номером для пакетів даних, у вигляді єдиного пакету з сегментами SYN і ACK (від слова асknowledgement – підтвердження). У відповідь клієнт пакетом даних ACK винен підтвердити прийом пакету даних від серверу.
Описана вище процедура, що одержала назву трьохетапного рукостискання (three-way handshake), схемно зображена на рисунку 15–16.8. При прийомі на машині-сервері пакету SYN, направленого на пасивний (слухаючий) сокет, мережна частина операційній системі створює копію цього сокета – приєднаний сокет – для подальшого спілкування, відзначаючи його як сокет з не повністю встановленим з'єднанням. Після прийому від клієнта пакету ACK цей сокет переводиться в стан повністю встановленого з'єднання, і тоді він готовий до подальшої роботи з використанням викликів read() і write().
Системний виклик listen()
Системний виклик listen() є першим з ще невідомих нам викликів, вживаним на TCP–сервері. В його задачу входить переклад TCP–сокета в пасивний (слухаюче) стан і створення черг для породжуваних при встановленні з'єднання приєднаних сокетів, що знаходяться в змозі не повністю встановленого з'єднання і повністю встановленого з'єднання. Для цього виклик має два параметри: дескриптор TCP–сокета і число, що визначає глибину створюваних черг.
Мал. 15-16.8. Схема встановлення TCP з'єднання
Системний виклик listen()
Прототип системного виклику
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockd, int backlog);
Опис системного виклику
Системний виклик listen використовується сервером, орієнтованим на встановлення зв'язку шляхом віртуального з'єднання, для перекладу сокета в пасивний режим і встановлення глибини черги для з'єднань.
Параметр sockd є дескриптором створеного раніше сокета, який повинен бути переведений в пасивний режим, тобто значенням, яке повернув системний виклик socket(). Системний виклик listen вимагає попередньої настройки адреси сокета за допомогою системного виклику bind().
Параметр backlog визначає максимальний розмір черг для сокетів, що знаходяться в станах повністю і не повністю встановлених з'єднань.
Значення, що повертається
Системний виклик повертає значення 0 при нормальному завершенні і значення -1 при виникненні помилки.
Останній параметр на різних UNIX-подібних операційних системах і навіть на різних версіях однієї і тієї ж системи може мати різний сенс. Десь це сумарна довжина обох черг, десь він відноситься до черги не повністю встановлених з'єднань (наприклад, Linux до версії ядра 2.2) десь – до черги повністю встановлених з'єднань (наприклад, Linux, починаючи з версією ядра 2.2), десь – взагалі ігнорується.
