Лістинг 15-16.4. Програма 15–16-4.c . Приклад простого TCP-серверу для сервісу echo. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Лістинг 15-16.4. Програма 15–16-4.c . Приклад простого TCP-серверу для сервісу echo.

Поиск

Наберіть і відкомпілюйте програму. Запустіть її на виконання. Модифікуйте текст програми TCP-клієнта (программа 15–16-3.c), замінивши номер порту з 7 на 51000. Запустіть клієнта з іншого віртуального терміналу або з іншого комп'ютера і переконаєтеся, що клієнт і сервер взаємодіють коректно.

Вживання інтерфейсу мережних викликів для інших сімейств протоколів. UNIX Domain протоколи. Файли типу "сокет"

Розглянутий нами інтерфейс уміє працювати не тільки із стеком протоколів TCP/IP, але і з іншими сімействами протоколів. При цьому потрібна лише незначна зміна написаних з його допомогою програм. Розглянемо дії, які необхідно виконати для модернізації написаних для TCP/IP програм під інше сімейство протоколів.

  1. Змінюється тип сокета, тому для його точної специфікації потрібно задавати інші параметри в системному виклику socket().
  2. В різних сімействах протоколів застосовуються різні адресні простори для видалених і локальних адрес сокетів. Тому міняється склад структури для зберігання повної адреси сокета, назва її типу, найменування полів і спосіб їх заповнення.
  3. Опис типів даних і приречених констант знаходитиметься в інших include-файлах, тому буде потрібно замінити include-файли <netinet/in.h> і <arpa/inet.h> на файли, що відносяться до вибраного сімейства протоколів.
  4. Може змінитися спосіб обчислення фактичної довжини повної адреси сокета і вказівки його максимального розміру.


Мал. 15-16.9. Схема роботи TCP-серверу з паралельною обробкою запитів

Давайте докладніше розглянемо ці зміни на прикладі сімейства UNIX Domain протоколів. Сімейство UNIX Domain протоколів призначено для спілкування локальних процесів з використанням інтерфейсу системних викликів. Воно містить один потоковий і один датаграмний протокол. Ніякий мережний інтерфейс при цьому не використовується, а вся передача інформації реально відбувається через адресний простір ядра операційної системи. Багато програм, що взаємодіють і з локальними, і з видаленими процесами (наприклад, X-Windows), для локального спілкування використовують цей стек протоколів.

Оскільки спілкування відбувається в рамках однієї обчислювальної системи, в повній адресі сокета його видалена частина відсутня. Як адресний простір портів – локальної частини адреси – вибрано адресний простір, співпадаючий з безліччю всіх допустимих імен файлів у файловій системі.

При цьому як ім'я сокета вимагається задавати ім'я неіснуючого ще файлу в директорії, до якої у вас є права доступу як на запис, так і на читання. При настройці адреси (системний виклик bind()) під цим ім'ям буде створений файл типу "сокет" – останній ще невідомий нам тип файлу. Цей файл для сокетів грає роль файлу-мітки типа FIFO для іменованих pip’ов. Якщо на вашій машині функціонують X-Windows, то ви зможете знайти такий файл в директорії з ім'ям /tmp/.X11-unix – це файл типу "сокет", що служить для взаємодії локальних процесів з віконним сервером.

Для зберігання повної адреси сокета використовується структура наступного вигляду, описаного у файлі <sys/un.h>:

struct sockaddr_un{ short sun_family; /* Вибране сімейство протоколів – завжди AF_UNIX */ char sun_path[108]; /* Ім'я файлу типу "сокет" */};

Вибране ім'я файлу ми копіюватимемо всередину структури, використовуючи функцію strcpy().

Фактична довжина повної адреси сокета, що зберігається в структурі з ім'ям my_addr, може бути обчислена таким чином: sizeof(short)+strlen(my_addr.sun_path). В Linux для цих цілей можна використовувати спеціальний макрос мови З

SUN_LEN(struct sockaddr_un*)

Нижче приведені тексти переписаних під сімейство UNIX Domain протоколів клієнта і серверу для сервісу echo (програми 15–16-5.c і 15–16-6.c), що спілкуються через датаграми. Клієнт використовує сокет з ім'ям AAAA в поточній директорії, а сервер – сокет з ім'ям BBBB. Як випливає з опису типу даних, ці імена (повні або відносні) не повинні по довжині перевищувати 107 символів. Коментарі дані лише для змін в порівнянні з програмами 15–16-1.c і 15–16-2.c.

/* А simple echo UNIX Domain datagram server */#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h> /* Новий include-файл замість netinet/in.h і arpa/inet.h */#include <string.h>#include <stdio.h>#include <errno.h>#include <unistd.h>int main(){ int sockfd; int clilen, n; char line[1000]; struct sockaddr_un servaddr, cliaddr; /* новий тип даних під адреси сокетів */ if((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) /* Змінений тип сімейства протоколів */ { реrror(NULL); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_UNIX; /* Змінений тип сімейства протоколів і ім'я поля в структурі */ strcpy(servaddr.sun_path,"BBBB"); /* Локальний адреса сокета серверу – BBBB – в поточній директорії */ if(bind(sockfd (struct sockaddr *) &servaddr SUN_LEN(&servaddr)) < 0) /* Змінено обчислення фактичної довжини адреси */ { реrror(NULL); close(sockfd); exit(1); } while(1){ clilen = sizeof(struct sockaddr_un); /* Змінено обчислення максимальної довжини для адреси клієнта */ if((n = recvfrom(sockfd, line, 999, 0 (struct sockaddr *) &cliaddr &clilen)) < 0){ реrror(NULL); close(sockfd); exit(1); } if(sendto(sockfd, line, strlen(line), 0 (struct sockaddr *) &cliaddr, clilen) < 0){ реrror(NULL); close(sockfd); exit(1); } } return 0;}


Поделиться:


Последнее изменение этой страницы: 2017-01-20; просмотров: 236; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.196 (0.006 с.)