English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby базовый учебник

Ruby продвинутый учебник

Программирование Socket в Ruby

Ruby предоставляет два уровня доступа к сети, на низком уровне вы можете получить доступ к операционной системе, что позволяет вам реализовать поддержку базовых套ок для протоколов с соединением и без соединения.

Ruby поддерживает единую сеть приложений, такие как FTP, HTTP и другие.

Независимо от того, высокого или низкого уровня, Ruby предоставляет了一些 базовые классы, которые позволяют использовать множество протоколов, таких как TCP, UDP, SOCKS для взаимодействия, не ограничиваясь сетевым уровнем. Эти классы также предоставляют вспомогательные классы, которые позволяют легко выполнять чтение и запись на сервере.

Давайте теперь изучим, как выполнять Ruby Socket программирование

Что такое Sockets

Когда приложение层 передается данными через транспортный уровень, TCP и UDP сталкиваются с проблемой предоставления параллельной услуги для множества процессов приложений. Множественные TCP-соединения или процессы приложений могут нуждаться в передаче данных через один и тот же порт TCP-протокола. Чтобы отличать различные процессы приложений и подключения, многие операционные системы компьютеров предоставляют интерфейс, называемый socket, который позволяет различать сетевую передачу данных и подключения между различными процессами приложений.

Создание socket,主要有 3 параметра: IP-адрес цели для передачи, используемый транспортный уровень протокола (TCP или UDP) и используемый порт. Оригинальное значение слова Socket - "розетка". Комбинируя эти три параметра, и связывая их с "розеткой" Socket, приложение может отличать передачу данных от различных процессов приложений или сетевых подключений через интерфейс socket, реализуя параллельную службу передачи данных.

Парсинг词汇 Sockets:

ОпцииОписание
domainУказывает семейство протоколов, обычно это PF_INET, PF_UNIX, PF_X25 и т.д.
typeУказывает тип socket: SOCK_STREAM или SOCK_DGRAM, интерфейс Socket также определяет原始 Socket (SOCK_RAW), который позволяет программе использовать низкий уровень протоколов
protocolОбычно присваивается 0.
hostnameИдентификатор сетевого интерфейса:
  • Строка, которая может быть именем хоста или IP-адресом

  • Строка "<broadcast>", указывающая адрес INADDR_BROADCAST

  • Строка 0 длины, указывающая INADDR_ANY

  • Целое число, интерпретируемое как байтовая адреса хоста в порядке хоста.

portport - это номер порта, каждый сервер прослушивает один или несколько портов для подключения клиентов, номер порта может быть Fixnum, который включает имя сервера и порт.

Простой клиент

Ниже мы написали пример простого клиента, используя данные о хосте и порте, Ruby TCPSocket класс предоставляет метод open для открытия socket.

TCPSocket.open(hosname, port) открывает TCP-соединение.

Как только вы открываете соединение Socket, вы можете читать его, как объект IO, и после завершения работы, вам нужно закрыть это соединение, как файл.

Ниже приведен пример того, как подключиться к указанному хосту, прочитать данные из socket и в конце закрыть socket:

Онлайн-пример

require 'socket'     # Sockets являются стандартной библиотекой
 
hostname = 'localhost'
port = 2000
 
s = TCPSocket.open(hostname, port)
 
while line = s.gets   # Чтение каждой строки из socket
  puts line.chop   # Вывод в терминал
end
s.close               # Закрытие socket

Простой сервис

В Ruby можно использовать класс TCPServer для создания простого сервиса. Объект TCPServer является фабрикой для TCPSocket.

Теперь мы используем TCPServer.open(hostname, port) для создания объекта TCPServer.

Далее вызывается метод accept у TCPServer, который ждет подключения клиента к указанному порту и возвращает объект TCPSocket, представляющий подключение к клиенту.

Онлайн-пример

require 'socket'               # Получение стандартной библиотеки сокетов
 
server = TCPServer.open(2000)  # Порт для监听 сокета 2000
loop {                         # Вечно работающий сервис
  client = server.accept     # Ожидание подключения клиента
  client.puts(Time.now.ctime)  # Отправка времени клиенту
  client.puts "Closing the connection. Bye!"
  client.close               # Закрытие подключения клиента
}

Теперь запустите приведенный выше код на сервере и посмотрите на результат.

Многосайтовый TCP сервис

В Интернете большинство сервисов имеют множество подключений клиентов.

Класс Thread в Ruby позволяет легко создавать многопоточные сервисы, один поток обрабатывает соединение клиента, а главный поток ждет новых соединений.

Онлайн-пример

require 'socket'               # Получение стандартной библиотеки сокетов
 
server = TCPServer.open(2000)   # Порт для监听 сокета 2000
loop {                         # Вечно работающий сервис
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime) # отправка времени клиенту
    client.puts "Closing the connection. Bye!"
    client.close # закрытие подключения клиента
  end
}

В этом примере сокет работает постоянно, а когда server.accept принимает соединение от клиента, создается новый поток, который немедленно начинает обрабатывать запрос. Основная программа сразу же возвращается в цикл и ожидает нового подключения.

Микроскопический веб-браузер

Мы можем использовать библиотеку socket для реализации любого интернет-протокола. Следующий код показывает, как получить содержимое веб-страницы:

Онлайн-пример

require 'socket'
 
host = 'ru.oldtoolbag.com' # веб-сервер
port = 80 # стандартный порт HTTP
path = "/index.htm" # адрес файла, который нужно получить
 
# Это HTTP-запрос
request = "GET #{path} HTTP/1.0\r\n\r\n" # это HTTP-запрос
 
socket = TCPSocket.open(host, port) # соединение с сервером
socket.print(request) # отправка запроса
response = socket.read # чтение полного ответа
# Разделите ответ на первую пустую строку на заголовки и тело
headers, body = response.split('\r\n\r\n', 2) 
print body # вывод результатов

Чтобы реализовать клиент, подобный вебу, вы можете использовать библиотеки, предварительно построенные для HTTP, такие как Net::HTTP.

Следующий код эквивалентен предыдущему:

Онлайн-пример

require 'net/http' # необходимые библиотеки
host = 'ru.oldtoolbag.com' # веб-сервер
path = '/index.htm' # Мы хотим получить файл 
 
http = Net::HTTP.new(host) # Создание подключения
headers, body = http.get(path) # Запрос файла
if headers.code == "200" # Проверка кода состояния
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
end

Ниже мы просто кратко介绍了 применение socket в Ruby, более подробную документацию можно найти здесь:Библиотека Socket и методы класса Ruby