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.