класс UNIXServer
UNIXServer представляет серверный сокет потокового типа домена UNIX.
Публичные методы класса
static VALUE
unix_svr_init(VALUE sock, VALUE path)
{
return rsock_init_unixsock(sock, path, 1);
} Создает новый серверный сокет UNIX, привязанный к path.
require 'socket'
serv = UNIXServer.new("/tmp/sock")
s = serv.accept
p s.read
Публичные методы экземпляра
static VALUE
unix_accept(VALUE server)
{
struct sockaddr_un buffer;
socklen_t length = sizeof(buffer);
return rsock_s_accept(rb_cUNIXSocket, server, (struct sockaddr*)&buffer, &length);
} Принимает входящее соединение. Возвращает новый объект UNIXSocket.
UNIXServer.open("/tmp/sock") {|serv|
UNIXSocket.open("/tmp/sock") {|c|
s = serv.accept
s.puts "hi"
s.close
p c.read #=> "hi\n"
}
}
# File ext/socket/lib/socket.rb, line 1780 def accept_nonblock(exception: true) __accept_nonblock(exception) end
Принимает входящее соединение с помощью accept(2) после установки O_NONBLOCK для базового файлового дескриптора. Возвращает принятый UNIXSocket для входящего соединения.
Пример
require 'socket'
serv = UNIXServer.new("/tmp/sock")
begin # emulate blocking accept
sock = serv.accept_nonblock
rescue IO::WaitReadable, Errno::EINTR
IO.select([serv])
retry
end
# sock is an accepted socket.
Список исключений, которые могут возникнуть при сбое вызова UNIXServer#accept_nonblock, см. в описании Socket#accept.
UNIXServer#accept_nonblock может вызвать любую ошибку, соответствующую сбою accept(2), включая Errno::EWOULDBLOCK.
Если исключение имеет тип Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::ECONNABORTED или Errno::EPROTO, к нему добавляется модуль IO::WaitReadable. Поэтому для перехвата исключений и повторной попытки вызова accept_nonblock можно использовать IO::WaitReadable.
Указав именованный аргумент exception в false, можно задать, чтобы accept_nonblock не вызывал исключение IO::WaitReadable, а возвращал вместо него символ :wait_readable.
См. также
VALUE
rsock_sock_listen(VALUE sock, VALUE log)
{
rb_io_t *fptr;
int backlog;
backlog = NUM2INT(log);
GetOpenFile(sock, fptr);
if (listen(fptr->fd, backlog) < 0)
rb_sys_fail("listen(2)");
return INT2FIX(0);
} Ожидает соединения, используя указанное значение int в качестве размера очереди ожидания. Вызов listen применим только в том случае, если socket имеет тип SOCK_STREAM или SOCK_SEQPACKET.
Параметр
-
backlog— максимальный размер очереди ожидающих соединений.
Пример 1
require 'socket' include Socket::Constants socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' ) socket.bind( sockaddr ) socket.listen( 5 )
Пример 2 (прослушивание произвольного порта; только в Unix-подобных системах):
require 'socket' include Socket::Constants socket = Socket.new( AF_INET, SOCK_STREAM, 0 ) socket.listen( 1 )
Исключения в Unix-подобных системах
В Unix-подобных системах приведенный выше код работает, потому что создается новая структура sockaddr с адресом ADDR_ANY и произвольным номером порта, назначенным ядром. В Windows этот код не работает, поскольку в Windows для вызова listen необходимо сначала привязать socket вызовом bind.
Если значение backlog превышает зависящий от реализации максимальный размер очереди, будет использован максимальный размер очереди, установленный реализацией.
В Unix-подобных системах при сбое вызова listen могут возникнуть следующие системные исключения:
-
Errno::EBADF — аргумент socket не является допустимым файловым дескриптором
-
Errno::EDESTADDRREQ — сокет socket не привязан к локальному адресу, а протокол не поддерживает прослушивание непривязанного сокета
-
Errno::EINVAL — сокет socket уже подключен
-
Errno::ENOTSOCK — аргумент socket не ссылается на сокет
-
Errno::EOPNOTSUPP — протокол сокета socket не поддерживает listen
-
Errno::EACCES — у вызывающего процесса нет необходимых привилегий
-
Errno::EINVAL — сокет socket был отключен
-
Errno::ENOBUFS — в системе недостаточно ресурсов для выполнения вызова
Исключения в Windows
В системах Windows при сбое вызова listen могут возникнуть следующие системные исключения:
-
Errno::ENETDOWN — сеть не работает
-
Errno::EADDRINUSE — локальный адрес сокета уже используется. Обычно это происходит во время выполнения bind, но ошибка может возникнуть позже, если вызов bind был выполнен для частично подстановочного адреса (с использованием ADDR_ANY) и конкретный адрес требуется назначить во время вызова listen
-
Errno::EINPROGRESS — выполняется вызов Windows Sockets 1.1 или поставщик служб продолжает обрабатывать функцию обратного вызова
-
Errno::EINVAL —
socketне был привязан вызовом bind. -
Errno::EISCONN —
socketуже подключен -
Errno::EMFILE — больше нет доступных дескрипторов сокетов
-
Errno::ENOBUFS — недостаточно места в буфере
-
Errno::ENOTSOC —
socketне является сокетом -
Errno::EOPNOTSUPP — ссылка
socketуказывает на тип, который не поддерживает метод listen
См. также
-
страницы руководства по listen в Unix-подобных системах
-
функция listen в справочнике функций Winsock компании Microsoft
static VALUE
unix_sysaccept(VALUE server)
{
struct sockaddr_un buffer;
socklen_t length = sizeof(buffer);
return rsock_s_accept(0, server, (struct sockaddr*)&buffer, &length);
} Принимает новое соединение. Возвращает новый файловый дескриптор в виде целого числа.
UNIXServer.open("/tmp/sock") {|serv|
UNIXSocket.open("/tmp/sock") {|c|
fd = serv.sysaccept
s = IO.new(fd)
s.puts "hi"
s.close
p c.read #=> "hi\n"
}
}
Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.