Программирование сокетов на Ruby
Ruby предоставляет два уровня доступа к сетевым службам. На низком уровне вы можете обращаться к операционной системе, что позволяет реализовать базовую поддержку сокетов для клиентов и серверов для протоколов с установлением соединения и без установления соединения.
Ruby обеспечивает унифицированную поддержку прикладных сетевых протоколов, таких как FTP, HTTP и т. д.
Будь то высокоуровневый или низкоуровневый, Ruby предоставляет некоторые базовые классы, которые позволяют взаимодействовать со многими протоколами, такими как TCP, UDP, SOCKS, не будучи привязанными к сетевому уровню. Эти классы также предоставляют вспомогательные классы, которые позволяют легко читать с серверов и записывать на серверы.
Далее давайте изучим, как выполнять программирование сокетов на Ruby.
Что такое сокеты
Когда прикладной уровень взаимодействует с транспортным уровнем для передачи данных, TCP и UDP сталкиваются с проблемой одновременного предоставления сервисов нескольким прикладным процессам. Несколько TCP-соединений или несколько прикладных процессов могут нуждаться в передаче данных через один и тот же порт протокола TCP. Чтобы различать разные прикладные процессы и соединения, многие компьютерные операционные системы предоставляют интерфейс, называемый сокетом, для взаимодействия приложений с протоколами TCP/IP, различая сетевую коммуникацию и соединения между разными прикладными процессами.
Создание сокета в основном включает три параметра: IP-адрес назначения для связи, используемый протокол транспортного уровня (TCP или UDP) и используемый номер порта. Изначальное значение Socket — «сокет». Комбинируя эти три параметра и привязывая их к «сокету», прикладной уровень может использовать интерфейс сокета с транспортным уровнем, чтобы различать связь от разных прикладных процессов или сетевых соединений, обеспечивая сервисы параллельной передачи данных.
Термины сокетов:
| Опция | Описание |
|---|---|
| domain | Указывает используемое семейство протоколов, обычно PF_INET, PF_UNIX, PF_X25 и т. д. |
| type | Указывает тип сокета: SOCK_STREAM или SOCK_DGRAM. Интерфейс Socket также определяет сырые сокеты (SOCK_RAW), позволяя программам использовать низкоуровневые протоколы. |
| protocol | Обычно присваивается 0. |
| hostname | Идентификатор сетевого интерфейса:
|
| port | port — это номер порта. Каждый сервер прослушивает один или несколько номеров портов для клиентских подключений. Номер порта может быть номером порта Fixnum или строкой, содержащей имя сервера и порт. |
Простой клиент
Ниже мы написали пример простого клиента, использующего заданные хост и порт. Класс Ruby TCPSocket предоставляет метод open для открытия сокета.
TCPSocket.open(hosname, port) открывает TCP-соединение.
После открытия соединения Socket вы можете читать из него как из объекта IO. По завершении нужно закрыть соединение, как при закрытии файла.
Следующий пример демонстрирует, как подключиться к указанному хосту, прочитать данные из сокета и в конце закрыть сокет:
Пример
Простой сервер
В Ruby можно использовать класс TCPServer для написания простого сервиса. Объект TCPServer — это фабричный объект для TCPSocket.
Теперь мы используем TCPServer.open(hostname, port) для создания объекта TCPServer.
Затем вызовите метод accept класса TCPServer. Этот метод ожидает, пока клиент подключится к указанному порту, а затем возвращает объект TCPSocket, представляющий соединение с этим клиентом.
Пример
Теперь запустите приведённый выше код на сервере и посмотрите результат.
Многоклиентская служба TCP
В Интернете большинство служб имеют большое количество клиентских соединений.
Класс Thread в Ruby позволяет легко создавать многопоточные службы. Один поток обрабатывает клиентские соединения, а главный поток ожидает новые соединения.
Пример
В этом примере сокет работает бесконечно. Когда server.accept получает клиентское соединение, создаётся новый поток, который сразу начинает обработку запроса. Затем главная программа немедленно возвращается к циклу и ожидает новые соединения.
Крошечный веб-браузер
Мы можем использовать библиотеку socket для реализации любого интернет-протокола. Следующий код показывает, как получить содержимое веб-страницы:
Пример
Чтобы реализовать клиент, подобный веб-клиенту, можно использовать готовые библиотеки для HTTP, такие как Net::HTTP.
Следующий код эквивалентен предыдущему коду:Пример
Выше мы лишь кратко рассмотрели применение сокетов в Ruby. Для получения дополнительной документации см.:Библиотека сокетов Ruby и методы класса
Другие расширения