Индустрия программирования

Одна из возможных конфигураций программных гнезд



Допустимые комбинации протоколов и драйверов задаются
при конфигурации системы

  • во время работы системы менять нельзя

По духу организация программных гнезд близка к идее
потоков
Но менее гибкая схема

  • не допускает изменения конфигурации "на
    ходу"



Взаимодействие процессов основано на модели "клиент-сервер"

  • процесс-сервер "слушает (listens)"
    свое программное гнездо
  • процесс-клиент пытается общаться с процессом-сервером
    через другое программное гнездо
  • ядро поддерживает внутренние соединения и маршрутизацию
    данных от клиента к серверу

Программные гнезда с общими коммуникационными свойствами,
такими как способ именования и протокольный формат адреса, группируются
в домены

  • "домен системы UNIX"
    для процессов, которые взаимодействуют через программные гнезда
    в пределах одного компьютера
  • "домен Internet"
    для процессов, которые взаимодействуют в сети в соответствии с
    семейством протоколов TCP/IP

Два типа программных гнезд

  • с виртуальным соединением (stream sockets)
  • дейтаграммные гнезда (datagram sockets)

Виртуальные соединения:

  • передача данных от клиента к серверу в виде непрерывного
    потока байтов с гарантией доставки
  • до начала передачи данных должно быть установлено
    соединение

Дейтаграммные программные гнезда:

  • не гарантируют абсолютной надежной, последовательной
    доставки сообщений и отсутствия дубликатов дейтаграмм
  • не требуется предварительное установление соединений

По умолчанию обеспечивается подходящий протокол
для каждой допустимой комбинации "домен-гнездо"


  • TCP для виртуальных соединений
  • UDP для дейтаграммного способа коммуникаций

Создание нового программного гнезда:
sd = socket(domain, type,
protocol);

  • domain
    - домен гнезда
  • type - тип (с
    виртуальным соединением или дейтаграммное)
  • protocol - желаемый
    сетевой протокол
  • sd - дескриптор
    программного гнезда

Закрытие (уничтожение) гнезда
close(sd)
Связывание ранее созданного программного гнезда
с именем:


bind(sd, socknm, socknlen);

  • sd
    - дескриптор ранее созданного программного гнезда
  • socknm - адрес
    структуры, которая содержит имя (идентификатор) гнезда, соответствующее
    требованиям домена данного гнезда и используемого протокола
  • для домена системы UNIX имя является именем объекта в файловой
    системе
  • при создании программного гнезда создается файл
  • socknlen - длина
    в байтах структуры socknm

Запрос связи с существующим программным гнездом
со стороны процесса-клиента:

connect(sd, socknm, socknlen);

  • смысл параметров, как у функции bind
  • имя программного гнезда на другой стороне коммуникационного
    канала
  • у гнезда с дескриптором sd
    и у гнезда с именем socknm
    должны быть одинаковые домен и протокол
  • если тип гнезда с дескриптором sd
    - дейтаграммный, то connect
    служит для информирования системы об адресе назначения пакетов,
    которые в дальнейшем будут посылаться с помощью функции send

Информирования о том, что процесс-сервер планирует
установление виртуальных соединений через указанное гнездо:

listen(sd, qlength);

  • qlength
    - максимальная длина очереди запросов на установление соединения,
    которые должны буферизоваться системой, пока их не выберет процесс-сервер

Выборка процессом-сервером очередного запроса на
установление соединения с указанным программным гнездом служит
функция accept:
nsd = accept(sd, address, addrlen);

  • sd
    - дескриптор существующего программного гнезда, для которого ранее
    была выполнена функция listen
  • address
    - массив данных, в который должна быть помещена информация, характеризующая
    имя программного гнезда клиента
  • addrlen
    - адрес, по которому находится длина массива address
  • выполнение функции приводит к установлению виртуального
    соединения
  • nsd
    - новый дескриптор программного гнезда, который должен использоваться
    при работе через данное соединение
  • по адресу addrlen
    помещается реальный размер массива данных, которые записаны по
    адресу address

Передача и прием данных через программные гнезда
с установленным виртуальным соединением:


count = send(sd, msg, length,
flags);
count = recv(sd, buf, length,
flags);
В send:

  • msg
    указывает на буфер с данными, которые требуется послать
  • length
    - длина этого буфера
  • flags
    == MSG_OOB
    внеочередная посылка данных

В recv:

  • buf
    указывает на буфер, в который следует поместить принимаемые данные
  • length
    - максимальная длина этого буфера
  • flags
    == MSG_PEEK
    перепись сообщения в пользовательский буфер без его удаления
    из системных буферов

Вместо send
и
recv
можно использовать
read
и
write

  • выполняются аналогично send
    и recv

Для посылки и приема сообщений в дейтаграммном
режиме:

count = sendto(sd, msg,
length, flags, socknm, socknlen);
count = recvfrom(sd, buf,
length, flags, socknm, socknlen);

  • смысл параметров sd,
    msg,
    buf
    и lenght
    аналогичен смыслу одноименных параметров функций send
    и recv
  • socknm
    и socknlen
    функции sendto
    задают имя программного гнезда, в которое посылается сообщение
  • могут быть опущены, если до этого вызывалась
    функция connect
  • параметры socknm
    и socknlen
    функции recvfrom
    позволяют серверу получить имя пославшего сообщение процесса-клиента

Немедленная ликвидация установленного соединения:
shutdown(sd, mode);

  • немедленно остановить коммуникации
  • со стороны посылающего процесса
  • со стороны принимающего процесса
  • с обеих сторон
  • в зависимости от значения параметра mode

shutdown отличаются
от close:

  • выполнение close
    последней "притормаживается" до окончания попыток системы
    доставить уже отправленные сообщения
  • shutdown разрывает
    соединение, но не ликвидирует дескрипторы ранее соединенных гнезд
  • для ликвидации требуется вызов close


Содержание раздела