SBCL. Сеть

Материал из wiki.lissyara.su
Перейти к: навигация, поиск

14 Работа с сетью в SBCL

Модуль sb-bsd-sockets обеспечивает прозрачное API BSD сокетов. Идея была украдена с API BSD сокетов для языка C и классов IO::Socket для языка Perl за авторством Грэхема Барра (Graham Barr).
Сокеты представлены как CLOS объекты. Наименование API проводилось с учётом BSD имён и хорошего LISP стиля.

14.1 Обзор сокетов

Большинство функций смоделировано с API BSD сокетов. BSD сокеты являются широко поддерживаемым, переносимым ("переносимы" в UNIX стандартах, как минимум) доступны на многих системах, и хорошо задокументированы. Есть несколько различий в подходе между SBCL и Common Lisp, благодаря которым можно получить больше полезных свойств - кратко:
  • Там, где API языка C обычно возвращает -1 и устанавливает errno, sb-bsd-sockets сигнализирует ошибку. Все ошибки являются подклассами sb-bsd-sockets:socket-condition и в целом один в один соответствуют с существующими значениями errno.
  • Мы используем множественные возвращаемые значения во многих местах, где API языка C использовал бы значения прохода-по-ссылке.
  • Часто мы можем избегать предоставления явных аргументов длины для функций, поскольку мы всегда знаем длину этого аргумента.
  • IP адреса и порты представлены в более дружественном виде, чем "целые числа в сетевой записи" ("network-endian integers").

14.2 Главные сокеты

- Класс: socket [sb-bsd-sockets]
Список приоритетов класса: socket, standard-object, t
Слоты:
  • protocol — initarg: :protocol; reader: sb-bsd-sockets:socket-protocol
Protocol используется сокетом. Если используется ключевая фраза, symbol-name ключевой фразы будет передан к get-protocol-by-name, далее возвращённое значение используется как протокол. Другие значения используются как есть.
  • type — initarg: :type; reader: sb-bsd-sockets:socket-type
Тип socket: :stream или :datagram.
Общий базовый класс для всех сокетов, не обязательна прямая работа с экземплярами.
- Общая Функция: socket-bind [sb-bsd-sockets] socket &rest address
Связывание сокета (socket) к адресу (address), в соответствии к семейству socket. Для семейства inet, задавайте адрес и порт как два аргумента; для семейства сокетов с файловым адресом, задавайте строку filename. Смотрите также bind(2)
— Общая Функция: socket-accept [sb-bsd-sockets] socket
Выполняет вызов accept(2), возвращает подключённый сокет и адрес пира в виде многосоставного значения
— Общая Функция: socket-connect [sb-bsd-sockets] socket &rest address
Выполняет вызов connect(2) для соединения к удалённому пиру. Возвращаются не используемые значения.
— Общая Функция: socket-peername [sb-bsd-sockets] socket
Возвращаются сокеты пира; в зависимости от семейства адресов, могут возвращаться многосоставные значения
— Общая Функция: socket-name [sb-bsd-sockets] socket
Возвращаются адреса (в виде вектора байтов) и порт, с которым связан сокет, в виде многосоставного значения.
— Общая Функция: socket-receive [sb-bsd-sockets] socket buffer length &key oob peek waitall dontwait element-type element-type
Читает заданную количество (length) октетов с сокета (socket) в буфер (или в созданный буфер если buffer установлено в NIL), через recvfrom(2). Если длина установлена в nil, то в этом случае используется длина буфера, таким образом, один из этих двух аргументов не должен равняться NIL. Если используется буфер, то будет лучше, чтобы он (буфер) был шириной в один октет. Буфер возвращается в виде его длины и адреса пира, который его отправил. На датаграмме сокетов, устанавливается MSG_TRUNC, таким образом актуальная длина пакета возвращается каждый раз при уменьшении буфера.
- Общая Функция: socket-send [sb-bsd-sockets] socket buffer length &key address external-format oob eor dontroute dontwait nosignal confirm more external-format
Отправляется длина октетов из буфера в сокет, через sendto(2). Если буфер является строкой, то он будет конвертирован в октеты в соответствии с внешним форматов (external-format). Если длина установлена в nil, будет использована длина октета буфера. Формат адреса (address) зависит от типа сокета (на пример для домена inet сокеты должны быть списком из ip адресов и порта). Если адреса сокетов не предоставлены, то взамен будет вызван send(2). Возвращается число записанных октетов.
- Общая Функция: socket-listen [sb-bsd-sockets] socket backlog
Маркирует сокет как готовый для приёма входящих соединений. backlog обозначает максимальную длину очереди ожидаемых соединений, при превышении этих соединений последующие соединения будут обрываться. Смотрите также listen(2)
- Общая Функция: socket-open-p [sb-bsd-sockets] socket
Возвращает true если сокет открыт; в противном случае - возвращает false.
- Общая Функция: socket-close [sb-bsd-sockets] socket &key abort
Закрывает сокет, если он не был уже закрыт.
Если был вызван socket-make-stream, вызывается close с использованием abort в этом потоке. В противном случае закрывается файловый дескриптор сокета с помощью close(2).
— Общая Функция: socket-make-stream [sb-bsd-sockets] socket &key input output element-type external-format buffering timeout element-type buffering external-format auto-close serve-events
Находит или создаёт поток, который может быть использован для ввода-вывода в сокет (с которым уже установлена связь). Определяет для чего был открыт поток: для ввода, вывода или для одновременного ввода-вывода. element-type и external-format устанавливаются в соответствии с open. timeout обозначает таймаут чтения для потока.
— Метод: socket-make-stream [sb-bsd-sockets] (socket socket) &key input output (element-type (quote character)) (buffering full) (external-format default) timeout auto-close serve-events
Метод по умолчанию для объектов сокета.
element-type устанавливается по умолчанию для символов, для создания двухвалентного потока, работающего и с бинарным и с символьным вводом-выводом. Для данной опции используйте :default.
Принимаемые значения для буферизации следующие: :full, :line и :none, по умолчанию установлено в :full, то есть вывод буферизуется до тех пор, пока он не очистится путём использования close или finish-output. (force-output принудительно очищает вывод: для того, чтобы быть полностью уверенным в полной очистке, используйте finish-output.)
Потоки, по умолчанию, не имеют таймаута. Таймаут указывается в секундах, в течении которых система ожидает ввода и после пытается прочитать с него.
Если auto-close установлен в true, то нижележащий os сокет автоматически закроется после потока и впоследствии к этому сокету будет применена сборка мусора. По умолчанию установлено в false.
Если serve-events установлено в true, то в этом случае ввод-вывод будет блокироваться в рекурсивном событии loop. По умолчанию установлено в false.
Поток для сокета будет кэширован и вызов в течении секунды этого метода будет возвращать некоторый поток. Может привести к странному поведению в случае если эта функция вызвана с противоречивыми аргументами (то есть, запрос входящего потока и получение исходящего потока в ответ).
— Функция: socket-error [sb-bsd-sockets] where
— Общая Функция: non-blocking-mode [sb-bsd-sockets] socket
Для того, чтобы выяснить: находится ли сокет в не блокировочном режиме?

14.3 Опции Сокета

Поддерживается подмножество опций сокета, через использование общего фреймворка, который облегчает добавление многих других требуемых опций - смотрите SYS:CONTRIB;SB-BSD-SOCKETS:SOCKOPT.LISP для дополнительных деталей. Перенос имён с языка C достаточно легко: SO_RCVLOWAT преобразуется в sockopt-receive-low-water и (setf sockopt-receive-low-water).
— Функция: sockopt-reuse-address [sb-bsd-sockets] socket
Возвращает значение опции сокета so-reuseaddr. Может быть обновлено через setf.
— Функция: sockopt-keep-alive [sb-bsd-sockets] socket
Возвращает значение опции сокета so-keepalive. Также может быть обновлено через setf.
— Функция: sockopt-oob-inline [sb-bsd-sockets] socket
Возвращает значение опции so-oobinline сокета. Также может быть обновлено через setf.
— Функция: sockopt-bsd-compatible [sb-bsd-sockets] socket
Возвращает значение опции so-bsdcompat для сокета. Также может быть обновлено через setf. Доступно только под Linux.
— Функция: sockopt-pass-credentials [sb-bsd-sockets] socket
Возвращает значение опции so-passcred для сокета. Также может быть обновлено через setf. Доступно только под Linux.
— Функция: sockopt-debug [sb-bsd-sockets] socket
Возвращает значение опции so-debug для сокета. Также может быть обновлено через setf.
— Функция: sockopt-dont-route [sb-bsd-sockets] socket
Возвращает значение опции сокета so-dontroute. Также может быть обновлено через setf.
— Функция: sockopt-broadcast [sb-bsd-sockets] socket
Возвращает значение опции сокета so-broadcast. Также может быть обновлено через setf.
— Функция: sockopt-tcp-nodelay [sb-bsd-sockets] socket
Возвращает значение опции сокета tcp-nodelay. Также может быть обновлено через setf.

14.4 Сокеты Домена INET

TCP и UDP сокеты, которые Вы все знаете и любите. Некоторые виды запросов:
Интернет адреса представлены в виде векторов (без знаковый байт 8) - viz. #(127 0 0 1). Порты только целочисленные: 6010. В этом пакете не нужно производить какие-либо преобразования между данными сети и хостов со стороны пользователя.
Адреса сокетов представлены через два значения для адреса и порта, а теперь будет пример, (socket-connect s #(192 168 1 1) 80).
— Класс: inet-socket [sb-bsd-sockets]
Список приоритетов класса: inet-socket, socket, standard-object, t
Класс состоит из tcp и udp сокетов.
Примеры:
(make-instance 'inet-socket :type :stream :protocol :tcp)
             
(make-instance 'inet-socket :type :datagram :protocol :udp)
— Функция: make-inet-address [sb-bsd-sockets] dotted-quads
Возвращает вектор из октетов полученных в виде строки со знаком разделения "." в формате "127.0.0.1". Возвращает ошибку в случае если строка неправильно отформатирована.
— Функция: get-protocol-by-name [sb-bsd-sockets] name
Получает имя протокола, возвращает номер протокола, имя протокола и список псевдонимов протокола.

14.5 Сокеты Локальных (Unix) Доменов

Сокеты локального домена (AF_LOCAL) также известны как Unix-domain сокеты, но мы их переименовали, руководствуясь POSIX традициями, так, чтобы они также были доступны на других системах.
Адрес локального сокета является строкой, которая используется для создания узла в локальной файловой системе. Также, это означает, что они (локальные сокеты) не могут быть использованы через локальную сеть.
— Класс: local-socket [sb-bsd-sockets]
Список приоритетов класса: local-socket, socket, standard-object, t
Класс состоит из сокетов локального домена (AF_LOCAL), также известных как unix-domain сокеты.

14.6 Служба Имён

В данный момент служба имён реализовано с помощью вызова getaddrinfo(3) и gethostinfo(3) или gethostbyname(3) и gethostbyaddr(3) на платформах, где привелегированные функции не доступны. Точные детали процесса работы с именами (на пример, выбор между использованием DNS или файла хостов для работы с именем) зависит от конкретной платформы.
— Класс: host-ent [sb-bsd-sockets]
Список приоритета класса: host-ent, standard-object, t
Слоты:
  • имя — initarg: :name; reader: sb-bsd-sockets:host-ent-name
Имя хоста
  • адреса — initarg: :addresses; reader: sb-bsd-sockets:host-ent-addresses
Список адресов для хоста.
Этот класс представляет результат работы с именем.
— Функция: get-host-by-name [sb-bsd-sockets] host-name
Возвращает образец базирующийся на хосте или сигнал name-service-error. host-name может также быть ip адресом в точечной нотации или другой вещью - смотрите gethostbyname(3) или getaddrinfo(3) для дополнительных деталей.
— Функция: get-host-by-address [sb-bsd-sockets] address
Возвращает образец на основе адресов, которые должны быть вектором (целочисленные 0 255) или сигналами name-service-error. Смотрите gethostbyaddr(3) или gethostinfo(3) для дополнительных деталей.
— Общая Функция: host-ent-address [sb-bsd-sockets] host-ent
Возвращает соответствующие адреса для host-ent.