Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab5.rtf
Скачиваний:
1
Добавлен:
24.11.2019
Размер:
7.04 Mб
Скачать

2.2 Програмний інтерфейс сокетів

Сокет– це комунікаційний інтерфейс взаємодіючих процесів. Конк-ретний характер взаємодії залежить від типу використовуваних сокетів, акомунікаційний домен, у межах якого створено цей сокет, визначає базовівластивості цієї взаємодії. Нижче наведені типи сокетів та їхні назви:

–Сокет дейтаграм– SOCK_DGRAM

–Сокет потоку– SOCK_STREAM

–Сокет пакетів– SOCK_SEQPACKET

–Сокет низького рівня– SOCK_RAW

Останній тип сокетів використовується для переглядання ICMP-повідомлень.

Для створення сокета процес має зазначити тип сокета та комуніка-ційний домен, у рамцях якого використовуватиметься сокет. Комунікацій-ний домен може підтримувати використання кількох протоколів, томупроцес може зазначити конкретний комунікаційний протокол для взаємо-дії. Але якщо його не зазначено, система сама обирає найбільш придатнийзі списку протоколів, доступних для даного комунікаційного домена. Длястворення сокета використовується системний виклик socket(2):

#include <sys/types.h>

#include <sys/socket.h>

int socket (int domain, int type, int protocol)

Аргумент domain визначає комунікаційний домен, type– тип сокета,а protocol– використовуваний протокол, за умовчанням зазначається не-прямо і може дорівнювати 0. У разі успішного виконання системний ви-клик повертає додатне ціле число, аналогічне файловому дескриптору, якетрактується далі як адреса даного сокета у подальших викликах.

Комунікаційний домен визначає сім’ю протоколів (Protocol Family),припустимих у межах даного домена. Можливі значення аргументу domainтакі:

AF_UNIX– домен локальної міжпроцесної взаємодії у межах однієї

ОС UNIX, внутрішні протоколи.

AF_INET– домен взаємодії процесів віддалених систем, протокол

Internet (TCP/IP).

AF_NS– домен взаємодії процесів віддалених систем, протокол

Хerox NS.

Префікс AF визначає адресний простір взаємодії;припустимі є та-кож назви з префіксом PF (Protocol Family); PF_UNIX, PF_INET тощо. Длядомена AF_INET можливі такі комбінації типу сокета та використовувано-го комунікаційного протоколу:

SOCK_STREAMIPPROTO_TCP (TCP)

SOCK_DGRAMIPPROTO_UDP (UDP)

SOCK_RAWIPPROTO_ICMP (ICMP)

SOCK_ RAWIPPROTO_RAW (IP)

Для однозначної ідентифікації сокета його слід прив’язати до прос-тору імен конкретного комунікаційного домена. Кожний комунікаційнийканал визначається двома вузлами– джерелом та отримувачем даних ісхарактеризовується п’ятьма параметрами:

–комунікаційним протоколом,

–локальною адресою,

–локальним процесом,

–віддаленою адресою,

–віддаленим процесом.

Адреса визначає операційну систему (чи хост мережі), а процес–конкретний додаток, який передає чи то отримує дані. Конкретні ж зна-чення й формат цих параметрів визначаються комунікаційним доменом.При створенні сокета вказується лише один параметр– комунікаційнийпротокол, тому, перш ніж передавати або приймати дані, треба зазначитище чотири параметри для комунікаційного каналу. Взаємодіючі процесимають робити це узгоджено, використовуючи заздалегідь визначені адре-си, або домовляючись щодо них у перебігу встановлення зв’язку. Процедура встановлювання цих параметрів істотно залежить від типу створюва-ного каналу, який визначається типом сокета та комунікаційного протоколу.

На рис. 2.1 подано взаємодію поміж процесами при віртуальномукомунікаційному каналі з попереднім встановленням зв’язку.

На рис. 2.2 подано взаємодію, базовану на дейтаграмах без попере-днього встановлення зв’язку.

Фактичному передаванню даних передує первісна фаза зв’язування(Binding) сокета засобами встановлення додаткової інформації, необхідноїдля визначення комунікаційного вузла. Зв’язування зреалізовується за до-помогою системного виклику bind(2):

#include <sys/types.h>

#include <sys/socket.h>

int bind (int sockfd, struct sockaddr *localaddr, int addrlen).

Дескриптор сокета, sockfd, отримується при створюванні сокета; ар-гумент localaddr визначає локальну адресу, з якою треба зв’язати сокет;параметр addrlen визначає розмір адреси. У процедурі зазначається лока-льна адреса, яка визначає два параметри комунікаційного каналу: локальнуадресу та локальний процес.

Адреса сокета залежить від комунікаційного домена, в межах якогойого визначено. У титульному файлі <sys/types.h> адреса визначається утакий спосіб:

struckt sockaddr {

u_shortsa_family;

charsa_data[14];

};

Поле sa_family визначає комунікаційний домен (сім’ю протоколів), аsa_data вміщує саме адресу, формат якої визначено длякожного домена.Наприклад, для внутрішнього домена UNIX адреса, визначена y<sys/un.h>, має вигляд

struckt sockaddr_un {

short sun_family; /*= = AF_UNIX*/;

char sun_path[108];

};

У цьому разі взаємодіючі процеси виконуються під керуванням од-нієї ОС на одному хості, комунікаційний вузол може бути однозначно ви-значено лише одним параметром– локальним процесом. У домені UNIXза адресу вважається ім’я файла.

Рисунок 2.3– Адреси сокетів

У разі мережного обміну даними слід зазначити адресу як локально-го процесу, так і хоста, на якому виконується даний процес. Для доменаInternet (сім’я протоколів ТСР/ІР) використовується формат адрес, визна-чений у файлі <netinet/in.h>:

struct sockaddr_in {

short sin_family; /*= = AF_INET */;

u_shortsin_port;

struckt in_addrsin_addr;

charsin_zero[8];

};

Адреса цього домена (ІР-адреса)– це 32-розрядне ціле числоsin_addr, а процес-додаток адресується 16-розрядним номером портуsin_port (рис. 2.3).

Зв’язування потрібне для привласнення сокетові локальної адреси йтим самим визначення комунікаційного вузла і зреалізовується системноюфункцією bind(2):

1Сервер реєструє свою адресу, яка має бути відома заздалегідь клі-

єнтам, які “спілкуються” з сервером. Зв’язування необхідне перш

ніж сервер буде готовий до приймання запитів від клієнтів.

2За взаємодії без попереднього встановлення зв’язку та створення

віртуального каналу клієнт також повинен заздалегідь зареєстру-

вати свою адресу, яка є унікальною в межах комунікаційного до-

мена. У разі домена UNIX цим опікується додаток. Ця адреса не

повинна бути відома серверові, тому що запит завжди ініціює клі-

єнт і автоматично передає разом з ним власну адресу. Отримана

адреса віддаленого вузла використовується сервером для мульти-

плексування повідомлень, які надсилаються різнимклієнтам.

3У разі взаємодії з використанням віртуального каналу клієнт може

зареєструвати власну адресу й не спрямовувати цю функцію сис-

темі.

Призначення адреси для клієнта можна виконувати за допомогоюсистемного виклику connect(2), який встановлює зв’язок з сервером і ав-томатично зв’язує сокет клієнта з локальним комунікаційним вузлом. Ви-клик connect(2) має вигляд

#include <sys/types.h>

#include <sys/socket.h>

int connect (int sockfd, struct sockaddr *servaddr, int addrlen);

Системний виклик connect(2) створює віртуальний канал та викону-ється для попереднього встановлення зв’язку між комунікаційними вузла-ми. Клієнтові не треба зв’язувати сокет за допомогою системного викликуbind(2). Локальний вузол комунікаційного каналу зазначається дескрипто-ром сокета sockfd, для якого система автоматично обирає потрібні значення локальної адреси та процесу. Віддалений вузол визначається аргументом servaddr, який вказує на адресу серверові, а addrlen задає його довжи-ну.

Виклик connect(2) може також використовуватися і клієнтами, якістворюють сокети дейтаграм без створення віртуального каналу. У такомуразі connect(2) не зреалізовує фактичного з’єднання з сервером, а може бу-ти використаний для зберігання параметрів адреси сервера, якому будеспрямовано дейтаграми. Клієнт буде позбавлений від необхідності зазна-чати адресу серверові при кожному відправленні даних.

Системний виклик listen(2) інформує систему про готовність сервераприймати запитання. Він має такі параметри:

#include <sys/types.h>

#include <sys/socket.h>

int listen (int sockfd, int backlog);

Параметр backlog зазначає максимально можливу кількість запитаньна встановлення зв’язку, які можуть очікувати, коли їх опрацює сервер.Якщо запит надходить, коли черга очікуючих запитів є повна, викликconnect(2) клієнта завершиться для домена UNIX (AF_UNIX) з помилкоюECONNRЕFUSED. Для інших доменів результат буде залежати від того,чи підтримує протокол повторне передавання запиту. Протокол ТСР (до-мен AF_INET) передаватиме повторні запити, допоки кількість запитів учерзіне зменшиться або не настане тайм-аут, окреслений для протоколу. Уцьому разі виклик клієнта завершиться з помилкою ETIMEDOUT.

Фактичне опрацювання запиту клієнта на встановлення зв’язку зреа-лізовує системний виклик accept(2):

#include <sys/types.h>

#include <sys/socket.h>

int accept (int sockfd, struct sockaddr *clntaddr, *int addrlen);

Виклик accept(2) обирає перший запит з черги і створює новий со-кет, характеристики якого не відрізняються від сокета sockfd і завершуєстворення віртуального каналу з бокусервера. Одночасно accept(2) повер-тає параметри віддаленого комунікаційного вузла– адресу клієнта clntaddrта його розмір addrlen. Новий сокет використовується для обслуговуванняствореного віртуального каналу, а отримана ним адреса клієнта виключаєйогоанонімність. Типовий сценарій взаємодії має вигляд:

sockfd = socket(...);Створити сокет

bind (sockfd, …);Сполучити його з відомою локальною адре-сою

listen (sockfd, …);Організувати чергу запитів

for ( ; ; ) {

newsockfd = accept (sockfd, …); Отримати адресу

if /fork( ) = = 0{; Породити дочірній процес

close (sockfd); Дочірній процес

·

·

·

exit (0);

}

else

close (newsockfd);Батьківський процес

}

У цьому сценарії, у той час, коли дочірній процес забезпечує факти-чний обмін даними з клієнтом, батьківський процес продовжує “прослухо-вувати” запити, котрі знову надходять, породжуючи для кожного з нихокремий процес-опрацьовувач. Черга дозволяє буферизувати запити на тойчас, коли сервер завершує виклик accept(2), а потім створює дочірній про-цес. Новий сокетnewsockfd, який створюється викликом accept(2), адресуєповністю визначений комунікаційний канал: протокол та повні адресиобох вузлів– клієнта та сервера. Для сокета sockfd визначено лише лока-льну частину каналу. Це дозволяє серверові продовжувати використанняsockfd для “прослуховування” наступних запитів.

Системні виклики listen(2) та accept(2) використовуються серверомлише в разі встановлення віртуального каналу поміж сервером та клієн-том.

Якщо для сокетів потоку під час приймання та передавання данихможуть використовуватися стандартні виклики read(2) та write(2), то соке-ти дейтаграм мають користуватися спеціальними системними викликами,які також є доступними для інших типів сокетів.

#include <sys/types.h>

#include <sys/socket.h>

int send (int s, const char *msg, int len, int flags);

int sendto (int s, const char *msg, int len, int flags,

const struct sockaddr *toaddr, int tolen);

int recv (int s, char *buf, int len, int flags);

int rеcvfrom (int s, char *buf, int len, int flags,

struct sockaddr *fromaddr, int * fromlen)

Функції send(2) та sendto(2) використовуються для передавання да-них віддаленому вузлу, а функції recv(2) та rеcvfrom(2)– для їхнього при-ймання. Основною відміною поміж ними є те, що функції send(2) таrecv(2) використовуються лише для “долученого” сокета, тобто після ви-клику connect(2).

Усі ці виклики використовують перший аргумент– дескриптор со-кета, через який зреалізовується обмін даними. Аргумент msg вміщує по-відомлення довжиною len, яке передається за адресою toaddr, довжина йо-го становить tolen байтів. Для функції send(2) використовується адресаодержувача, встановлена попереднім викликом connect(2). Аргумент buf–це буфер, у який копіюються отримані дані.

Параметр flags може набирати таких значень:

MSG_OOBПередати або прийняти екстрені дані (out of band) за-

мість звичайних

MSG_PEEKПереглянути дані без вилучення їх з системного бу-

фера (наступні операції читання отримають ті ж самі

дані)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]