Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Програмний інтерфейс сокетів Берклі
У розділі 6 наводилися загальні принципи взаємодії між клієнтом і сервером у разі використання сокетів. У цьому розділі опишемо особливості використання інтерфейсу сокетів Берклі (Berkeley Sockets) [38, 47, 75, 106]. Програмний інтерфейс сокетів Берклі - це засіб зв'язку між прикладним рівнем мережної архітектури TCP/IP і транспортним рівнем. Причина такого розташування полягає в тому, що це засіб зв'язку між кодом застосування (який виконують на прикладному рівні) і реалізацією стека протоколу ОС (найвищим рівнем якої є транспортний). Фактично цей інтерфейс є набором системних викликів ОС. Назва цього АРІ пов'язана з тим, що він уперше був реалізований у 80-х роках XX століття у версії UNIX, розробленій Каліфорнійським університетом у Берклі (BSD UNIX).
Особливості роботи з адресами Цей розділ буде присвячено особливостям відображення даних про адреси і порти, необхідних для використання сокетів.
Відображення адрес сокетів Більшість системних викликів роботи із сокетами приймають як параметри покажчики на спеціальні структури даних, що відображають адреси сокетів. У разі використання TCP/IP зі звичайним ІР-протоколом (IPv4) адресу задають структурою sockaddrin. Вона визначена у заголовному файлі <netinet/in.h> і містить, зокрема, такі поля: ♦ sin_family - для TCP/IP має дорівнювати константі AF_INET; Sin_port - цілочисловий номер порту для TCP або UDP; ♦ sin_addr - відображення IP-адреси (структура і naddr з одним полем saddr). Реалізуючі системні виклики роботи із сокетами, необхідно враховувати можливість використання різних протоколів, а отже, передавання в них різних структур, що відображають адреси. Під час розробки АРІ сокетів Берклі було ухвалено рішення використати як універсальний тип відображення адрес покажчик на спеціальну структуру sockaddr, визначену у <sys/socket.h>. Наприклад, прототип системного виклику bindO, що пов'язує сокет з адресою, має такий вигляд:
int bindOnt. struct sockaddr *. socklent): На практиці адреса задається так: визначають структуру типу sockaddr і п і під час виклику покажчик на неї перетворюють до sockaddr *:
struct sockaddr_in my_addr: II... заповнення структури my_addr. див. далі bind(sockfd. (struct sockaddr *) &my_addr, sizeof(my_addr)); Безпосередньо структуру sockaddr у застосуваннях не використовують. Якщо виклик повернув покажчик на неї, перед використанням у застосуванні його потрібно привести до покажчика на структуру для конкретного протоколу (наприклад, на sockaddr_in).
Порядок байтів Історично так склалося, що відображення у пам'яті даних, для яких виділяють більш як один байт (наприклад, двобайтового цілого, що відповідає у С типу short), відрізняється для різних комп'ютерних архітектур. У деяких із них старший байт розташовують у пам'яті перед молодшим (такий порядок називають зворотним -big-endian byte order), а в інших - молодший перед старшим (це прямий порядок - little-endian byte order). Наприклад, архітектура ІА-32 використовує прямий порядок байтів, а комп'ютери Sun Sparestation та Power PC - зворотний. Проблема полягає в тому, що деякі елементи пакетів (керуючі дані), якими обмінюються комп'ютери для організації передавання інформації, займають у пам'яті більш як один байт. Так, відображення порту займає 2 байти, а IP-адреси -4 байти. Якщо такий блок інформації буде передано комп'ютеру з іншим порядком байтів, він не зможе коректно його інтерпретувати. Для вирішення цієї проблеми реалізації стека протоколів на клієнті та на сервері потрібно під час передавання даних мережею узгоджено використовувати єдиний порядок байтів. Такий порядок, який називають мережним порядком байтів (network byte order), визначає мережний протокол. Фактично, це зворотний порядок. Відповідно, порядок байтів, прийнятий для локального комп'ютера, називають порядком байтів хоста (host byte order). Він може бути як прямим, так і зворотним. Програміст має перетворювати керуючі дані в мережний порядок байтів перед передаванням інформації із мережі та робити зворотне перетворення після її отримання. Це зокрема стосується IP-адрес і номерів портів. Для реалізації перетворення використовують функції htonK) і htonsO (перетворення до мережного порядку), ntohl () і ntohs() (перетворення до порядку хоста):
#include <netinet/in.h> uintl6 _t htons (uintl6 _t hostval): // htonlO - для 32 -бітних даних uintl6 _t ntohs (uintl6 _t netval): // ntohlO - для 32 -бітних даних
Далі наведемо приклади використання цих функцій.
Робота з ІР-адресами У протоколі IPv4 IP-адреса є цілим значенням розміром 4 байти. Для того щоб перетворити крапково-десяткове подання такої адреси (n. n. п. п) у ціле число, слід використати функцію inet_aton():
#include <arpa/inet.h> int inet_aton(const char *c_ip. struct in_addr *s_ip); де: c_ip - рядкове відображення IP-адреси: "192.168.10.28"; s_ip - структура inaddr, що міститиме цілочислове відображення адреси, розташоване в пам'яті відповідно до мережного порядку байтів (поле S addr); цю структуру заповнюють усередині виклику. У разі успішного перетворення ця функція повертає ненульове значення, у разі помилки — нуль.
Розглянемо приклад заповнення структури, що задає адресу сокета:
struct sockaddrin my_addr = { 0 }: // структура має бути обнулена my_addr.sin_family = AFINET: my_addr.sin_port = htons (7500); // задання порту inet_aton ("192.168.10.28". &(my_addr.sin_addr)): // задання адреси
Для обнулення структур часто використовують функцію bzero():
include <strings.h> bzero(&my_addr. sizeof(my_addr)): // заповнення my_addr
Зворотне перетворення IP-адреси (із цілого числа у крапково-десяткове подання) здійснюють функцією ine_tntoра():
#include <arpa/inet.h> char *inet_ntoa(struct in_addr sip):
Ця функція розміщає у статичному буфері рядок із крапково-десятковим поданням IP-адреси, заданої структурою s_ip, і повертає покажчик на цей буфер:
printfС'ІР-адреса: *s\n". inet_ntoa(my_addr.s_addr)); Зазначимо, що наступні спроби виклику функції стиратимуть статичний буфер, тому для подальшого використання його вміст потрібно копіювати в окремий буфер пам'яті.
Створення сокетів Перший етап, який необхідно виконати на клієнті та сервері, - створити дескриптор сокета за допомогою системного виклику socket ():
#include <sys/socket.h> int socket(int family, int type, int protocol):
де: family - комунікаційний домен (AFINET - домен Інтернету на основі IPv4, AFUNIX - домен UNIX);
type - тип сокета (S0CK_STREAM - потоковий сокет, S0CKDGRAM - дейтаграмний сокет, S0CKRAW - сокет прямого доступу (raw socket), призначений для роботи із протоколом мережного рівня, наприклад IP);
protocol - тип протоколу (звичайно 0; це означає, що протокол вибирають автоматично, виходячи з домену і типу сокета; наприклад, потокові сокети домену Інтернет використовують TCP, а дейтаграмні - UDP).
Ось приклад використання socket (): int sockfd = socket (AF_INET. SOCKJTREAM. 0);
Виклик socket О повертає цілочисловий дескриптор сокета або -1, якщо сталася помилка (при цьому, як і для інших викликів, змінна errno міститиме код помилки). Цей сокет можна використовувати для різних цілей: організації очікування з'єднань сервером, задання з'єднання клієнтом, отримання інформації про мережну конфігурацію хоста (в останньому випадку він може бути навіть не пов'язаний з адресою). Для системних викликів інтерфейсу сокетів Берклі далі за замовчуванням передбачатиметься використання заголовного файла <sys/socket.h>.
|
||||||
Последнее изменение этой страницы: 2017-02-06; просмотров: 321; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.138.125.2 (0.015 с.) |