Н.В. Вдовикина, И.В. Машечкин, А.Н. Терехин, А.Н. Томилин - Операционные системы - взаимодействие процессов (2008) (1114653), страница 25
Текст из файла (страница 25)
*/устанавливаемpthread_cond_signal(&cond);сигнализируем ей на условной переменной *//*признак...и}/* теперь ожидаем завершения нити-читателя */pthread_join(reader_tid, NULL);/* освобождаем ресурсы */pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);printf("main thread exits...\n");return 0;}1537 Взаимодействие процессов в сети7.1 Механизм сокетовСредства межпроцессного взаимодействия ОС UNIX,представленные в системе IPC, решают проблему взаимодействиядвух процессов, выполняющихся в рамках одной операционнойсистемы. Однако, очевидно, их невозможно использовать, когдатребуется организовать взаимодействие процессов в рамках сети.Это связано как с принятой системой именования, котораяобеспечивает уникальность только в рамках данной системы, так ивообще с реализацией механизмов разделяемой памяти, очередисообщений и семафоров, – очевидно, что для удаленноговзаимодействия они не годятся.
Следовательно, возникаетнеобходимостьвкаком-тодополнительноммеханизме,позволяющем общаться двум процессам в рамках сети. Однако еслиразработчики программ будут иметь два абсолютно разных подходак реализации взаимодействия процессов, в зависимости от того, наодной машине они выполняются или на разных узлах сети, им,очевидно, придется во многих случаях создавать два принципиальноразных куска кода, отвечающих за это взаимодействие. Понятно, чтоэто неудобно и хотелось бы в связи с этим иметь некоторыйунифицированный механизм, который в определенной степенипозволял бы абстрагироваться от расположения процессов и давалбы возможность использования одних и тех же подходов длялокального и нелокального взаимодействия.
Кроме того, как толькомы обращаемся к сетевому взаимодействию, встает проблемамногообразия сетевых протоколов и их использования. Очевидно,что было бы удобно иметь какой-нибудь общий интерфейс,позволяющий пользоваться услугами различных протоколов повыбору пользователя.Обозначенные проблемы был призван решить механизм,впервые появившийся в BSD UNIX 4.2 и названный сокетами(sockets)27.Сокеты представляют собой в определенном смыслеобобщение механизма каналов, но с учетом возможныхособенностей, возникающих при работе в сети.
Кроме того, онипредоставляют больше возможностей по передаче сообщений,27В русскоязычной литературе можно также встретить название «гнезда» или«коммуникационные гнезда», которое является приблизительным переводом слова sockets.154например, могут поддерживать передачу экстренных сообщений внеобщего потока данных.
Общая схема работы с сокетами любого типатакова: каждый из взаимодействующих процессов должен на своейстороне создать и отконфигурировать сокет, после чего процессымогут осуществить соединение с использованием этой пары сокетов.По окончании взаимодействия сокеты уничтожаются.Механизм сокетов чрезвычайно удобен при разработкевзаимодействующих приложений, образующих систему «клиентсервер».
Клиент посылает серверу запросы на предоставлениеуслуги, а сервер отвечает на эти запросы.Схема использования механизма сокетов для взаимодействия врамках модели «клиент-сервер» такова. Процесс-сервер запрашиваету ОС сокет и, получив его, присваивает ему некоторое имя (адрес),которое предполагается заранее известным всем клиентам, которыезахотят общаться с данным сервером. После этого сервер переходитв режим ожидания и обработки запросов от клиентов. Клиент, сосвоей стороны, тоже создает сокет и запрашивает соединение своегосокета с сокетом сервера, имеющим известное ему имя (адрес).После того, как соединение будет установлено, клиент и сервермогут обмениваться данными через соединенную пару сокетов.Ниже мы подробно рассмотрим функции, выполняющие всенеобходимые действия с сокетами, и напишем небольшие примерысерверной и клиентской программы, использующих сокеты.7.1.1 Типы сокетовСокеты подразделяются на несколько типов в зависимости оттипа коммуникационного соединения, который они используют.
Дваосновных типа коммуникационных соединений (и, соответственно,использующих их сокетов) представляет собой соединение сиспользованием виртуального канала и датаграммное соединение.Соединение с использованием виртуального канала – этопоследовательный поток байтов, гарантирующий надежнуюдоставку сообщений с сохранением порядка их следования. Данныеначинают передаваться только после того, как виртуальный каналустановлен, и канал не разрывается, пока все данные не будутпереданы. Примером соединения с установлением виртуальногоканала является механизм каналов в UNIX, аналогом такогосоединения из реальной жизни также является телефонный разговор.Заметим, что границы сообщений при таком виде соединенийне сохраняются, т.е. приложение, получающее данные, должно самоопределять, где заканчивается одно сообщение и начинается155следующее.
Такой тип соединения может также поддерживатьпередачу экстренных сообщений вне основного потока данных, еслиэто возможно при использовании конкретного выбранногопротокола.Платой за все положительные стороны установлениявиртуального канала является то, что сокет, участвующий в такомсоединении, будет «занят» (аналогично телефонному аппарату) напротяжении всего сеанса связи, пока соединение не будет разорвано.Это означает, что данный сокет в это время не может параллельноиспользоваться в других соединениях.Датаграммное соединение используется для передачиотдельных пакетов, содержащих порции данных – датаграмм. Длядатаграмм не гарантируется доставка в том же порядке, в каком онибыли посланы. Вообще говоря, для них не гарантируется доставкавообще, надежность соединения в этом случае ниже, чем приустановлении виртуального канала.
Однако датаграммныесоединения, как правило, более быстрые. Примером датаграммногосоединения из реальной жизни может служить обычная почта:письма и посылки могут приходить адресату не в том порядке, вкаком они были посланы, а некоторые из них могут и совсемпропадать. Другим примером датаграммного соединения являетсяпередача сообщений посредством SMS: в отличие от телефонногоразговора («соединения с установлением виртуального канала»), приэтом оба телефонных аппарата («сокета») почти все время остаютсянезаняты и параллельно могут использоваться для приема ипередачи сообщений, адресованных другим абонентам.
Однако припередаче каждого сообщения необходимо заново указыватьтелефонный номер адресата («адрес сокета»), кроме того, абонент(«вызвающая программа») сам должен сортировать сообщения,принятые от разных адресатов.При использовании сокетов с установлением виртуальногосоединения для создания программ с архитектурой «клиент-сервер»возникает один очень важный вопрос. Как можно обеспечитьпараллельную обработку сервером клиентских запросов, еслисерверный сокет на все время сеанса связи с конкретным клиентомбудет занят этим соединением и недоступен для поступлениязапросов от других клиентов? Для решения этой проблемы следуетиспользовать для серверного сокета режим прослушивания сокета.В этом режиме всякий раз при поступлении на серверный сокетзапроса на соединение, порождается новый уникальный сокетдубликат, который и участвует в этом соединении, в то время как156исходный серверный сокет остается свободным и продолжаетожидать поступления новых запросов.Продолжая аналогию с телефонными звонками, можносказать, что сервер представляет в этом случае подобие call-центра сединым многоканальным телефоном.
Всякий раз при поступлениизвонка (запроса на соединение) он переводится на конкретногооператора (новый уникальный сокет), который и занимается егообработкой, а входящая линия снова становится свободной и можетпринимать новые звонки от других клиентов.Общая схема работы с сокетами двух основных типовпоказана на рисунке ниже.создание иконфигурирование сокетасоздание иконфигурирование сокетаsocket(), bind()socket(), bind()установление соединенияустановление соединенияconnect()connect()прием и передача данныхприем и передача данныхsend(), recv()send(), recv()разрыв соединенияразрыв соединенияshutdown()shutdown()уничтожение сокетауничтожение сокетаclose()close()Рис. 21.
Схема работы с сокетами с установлением виртуального канала157создание иконфигурирование сокетасоздание иконфигурирование сокетаsocket(), bind()socket(), bind()вход в режимпрослушивания сокетаlisten()установление соединенияустановление соединенияaccept()connect()прием и передача данныхприем и передача данныхsend(), recv()send(), recv()разрыв соединенияразрыв соединенияshutdown()shutdown()уничтожение сокетауничтожение сокетаclose()close()Рис.
22. Схема работы с сокетами с установлением виртуального канала. Клиентсервер.создание иконфигурирование сокетасоздание иконфигурирование сокетаsocket(), bind()socket(), bind()прием и передача данныхприем и передача данныхsendto(), recvfrom()sendto(), recvfrom()уничтожение сокетауничтожение сокетаclose()close()Рис. 23. Схема работ с сокетами без установления виртуального канала.Далее мы рассмотрим подробно все системные вызовы,необходимые для реализации этих схем.7.1.2 Коммуникационный доменПоскольку сокеты могут использоваться как для локального,так и для удаленного взаимодействия, встает вопрос о пространстве158адресов сокетов. При создании сокета указывается так называемыйкоммуникационный домен, к которому данный сокет будетпринадлежать.
Коммуникационный домен определяет форматыадресов и правила их интерпретации. Мы будем рассматривать дваосновных домена: для локального взаимодействия – домен AF_UNIXи для взаимодействия в рамках сети – домен AF_INET (префикс AFобозначает сокращение от «address family» – семейство адресов). Вдомене AF_UNIX формат адреса – это допустимое имя файла, вдомене AF_INET адрес образуют имя хоста + номер порта.Заметим, что фактически коммуникационный доменопределяет также используемые семейства протоколов. Так, длядомена AF_UNIX это будут внутренние протоколы ОС, для доменаAF_INET – протоколы семейства TCP/IP.
Современные системыподдерживают и другие коммуникационные домены, например BSDUNIX поддерживает также третий домен – AF_NS, использующийпротоколы удаленного взаимодействия Xerox NS.Ниже приведен набор функций для работы с сокетами.7.1.3 Создание и конфигурирование сокетаСоздание сокета#include <sys/types.h>#include <sys/socket.h>int socket (int domain, int type, int protocol);Функция создания сокета так и называется – socket(). У нееимеется три аргумента.
Первый аргумент – domain – обозначаеткоммуникационный домен, к которому должен принадлежатьсоздаваемый сокет. Для двух рассмотренных нами доменовсоответствующие константы будут равны, как мы уже говорили,AF_UNIX и AF_INET. Второй аргумент – type – определяет типсоединения, которым будет пользоваться сокет (и, соответственно,тип сокета). Для двух основных рассматриваемых нами типовсокетов это будут константы SOCK_STREAM для соединения сустановлением виртуального канала и SOCK_DGRAM для датаграмм28.Третий аргумент – protocol – задает конкретный протокол,которыйбудетиспользоватьсяврамкахданного28Заметим, что данный аргумент может принимать не только указанные два значения,например, тип сокета SOCK_SEQPACKET обозначает соединение с установлениемвиртуального канала со всеми вытекающими отсюда свойствами, но при этом сохраняютсяграницы сообщений; однако данный тип сокетов не поддерживается ни в домене AF_UNIX,ни в домене AF_INET, поэтому мы его здесь рассматривать не будем159коммуникационного домена для создания соединения.