четверг, 18 октября 2007 г.

Рубиновые сокеты

Сокеты - это интерфейс для связи двух процессов. Процессы могут быть как локальные (на одной машине), так и распределенные. Сам сокет - это некий абстракный объект, являющийся конечной точкой соединения. С сокетом ассоциируются несколько понятий:

  • протокол (TCP, UDP, raw IP);
  • локальный IP адрес (к нему чему сокет привязывается при создании);
  • локальный порт (к нему чему сокет привязывается при создании);
  • удаленный IP адрес;
  • удаленный порт (используя эти параметры сокет конектится к удаленному сокету).

Сокеты реализуются с посредством библиотек, таких как Berkeley sockets (BSD sockets) или Winsock.

Ruby предоставляет свой инструментарий для работы с сокетами (на базе BSD sockets):

Работа с сокетами в Руби реализуется иерархией классов:

Из названий классов примерно понятно их назначение. BasicSocket - это абстрактный класс для всех сокетов. Методы этого класса ничем не оличаются от того, что можно увидеть в С++: accept, bind, listen и т.д. У BasicSocket есть методы класса (аналогия - статические методы С++) и методы объекта.

UNIXSocket - предоставляет IPC и использованием UNIX domain protocol (AF_UNIX).

UNIXServer - помогает создавать UNIX domain protocol серверы.

IPSocket - базовый класс для сокетов с протоколами, использующими IP (AF_INET).

UDPSocket и TCPSocket - классы для сокетов с UDP и TCP протоколами.

SOCKSSocket - помогает строить приложения, основанные на SOCKS-протоколе.

Socket - предоставляет доступ к лежажашей в основе всех сокетов реализации BSD Sockets API.

IO - базовый класс для операций ввода/вывода в Руби. При создании приложения с сокетами, полезным является метода IO#select( readArray [, writeArray [ errorArray [ timeout ] ] ] ) - ожидает, когда станут доступными данные с утройств ввода/вывода. Первый параметр метода - массив IO-объектов. Второй параметр - таймаут в секундах; если он равен nil, то ожидание происходит бесконечно.

Более подробно о классах и их методах можно почитать здесь: Sockets Programming in Ruby, The Pragmatic Programmer's Guide.

Создавать сокеты можно несколькими способами. Первый способ напроминает подход C:

В этом случает для создания используются методы класса Socket, с параметрами, характеризующими тип создаваемого сокета. Того же самого эффекта можно добиться вызывая методы конктерного класса:

Для удаления сокета используется метод close.

IP адреса в Руби могу быть представленны как в виде имени хоста, так и в виде '0.0.0.0':

Для сокетов можно устанавливать и получать параметры используя методы: getsockopt и setsockopt.

Простой пример использования сокетов:

Таким образом, работа с сокетами в Ruby не представляет большой сложности, особенно для тех, кто знаком с сокетами на С.

2 комментария:

Анонимный комментирует...

Kak vedet sebR potok s otkrytim ruby socket-priemnikom esli peredat4ik ni4ego ne posylaet?

sash_ko комментирует...

Поток может ждать сообщения от передатчика, если использовать IO#select (или, например, TCPSocket#get)

require 'socket'

#создаем сервер
server = TCPServer.new('localhost', 1000)
# ждем подключение
session = server.accept
session.write "login: "
puts "Accepted: #{session.gets}"
session.write 'Have a lot of fun\r\n'

#здесть можно использовать select,
#но для одного коннекта можно
#просто вызвать TCPSocket#gets

#вечно ждем и выводим принятые сообщения
while(msg = session.gets)
puts msg
end

Тепер можно коннектиться к этому серверу telnet localhost 1000.