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

Programação de Socket do Ruby

Ruby oferece dois níveis de acesso à rede, no nível inferior você pode acessar o sistema operacional, o que permite que você realize suporte básico de soquetes conectados e não conectados para clientes e servidores.

O Ruby suporta uniformemente os protocolos de rede de aplicativos, como FTP, HTTP, etc.

Seja na camada alta ou na camada baixa. O Ruby fornece algumas classes básicas que permitem que você interaja com muitos protocolos, como TCP, UDP, SOCKS, etc., sem se limitar à camada de rede. Essas classes também fornecem classes auxiliares que permitem que você leia e escreva facilmente no servidor.

Vamos aprender como fazer programação de Socket Ruby a seguir

O que são Sockets

Quando a camada de aplicação se comunica através da camada de transporte, TCP e UDP enfrentam o problema de fornecer serviços concorrentes para múltiplos processos de aplicativos. Múltiplas conexões TCP ou múltiplos processos de aplicativos podem precisar transmitir dados através da mesma porta do protocolo TCP. Para distinguir diferentes processos de aplicativos e conexões, muitos sistemas operacionais de computadores fornecem uma interface chamada Socket para a interação do aplicativo com o protocolo TCP/IP, diferenciando a comunicação de rede entre diferentes processos de aplicativos.

A geração de sockets, principalmente3Esses parâmetros: endereço IP de destino da comunicação, protocolo de camada de transporte usado (TCP ou UDP) e porta usada. O Socket original é "plug".3Esses parâmetros combinados, ao se conectar a um "plug" Socket, permitem que a camada de aplicação se comunique com a camada de transporte através da interface Socket, diferenciando a comunicação de diferentes processos de aplicativos ou conexões de rede, implementando serviços de comunicação concorrente de dados.

Análise de vocabulário de Sockets:

OpçõesDescrição
domainEspecifica a família de protocolos usada, geralmente PF_INET, PF_UNIX, PF_X25, etc.
typeEspecifica o tipo de socket: SOCK_STREAM ou SOCK_DGRAM, a interface Socket também define o Socket original (SOCK_RAW), que permite que o programa use protocolos de baixa camada
protocolNormalmente atribuído 0.
hostnameIdentificador da interface de rede:
  • Uma string, que pode ser o nome do host ou o endereço IP

  • A string "<broadcast>", que especifica o endereço INADDR_BROADCAST

  • Uma string de comprimento 0, que especifica INADDR_ANY

  • Um inteiro, que representa o endereço binário de ordem de bytes do host.

portO port é o número da porta, cada servidor escuta uma ou mais portas de conexão do cliente, uma porta pode ser um número da porta Fixnum, que contém o nome do servidor e a porta.

Cliente simples

A seguir, apresentamos um exemplo simples de cliente usando o host e a porta fornecidos, a classe Ruby TCPSocket oferece o método open para abrir um socket.

TCPSocket.open(hosname, port) abre uma conexão TCP.

Uma vez que você abre uma conexão de Socket, você pode lê-lo como um objeto IO e, após a conclusão, você precisa fechá-la como um arquivo.

O exemplo a seguir demonstra como conectar-se a um host específico, ler dados do socket e, finalmente, fechar o socket:

Exemplo online

require 'socket' # Sockets são uma biblioteca padrão
 
hostname = 'localhost'
port = 2000
 
s = TCPSocket.open(hostname, port)
 
while line = s.gets # Ler cada linha de dados do socket
  puts line.chop # Imprimir no terminal
end
s.close # Fechar socket

Serviço simples

No Ruby, podemos usar a classe TCPServer para escrever um serviço simples. O objeto TCPServer é uma fábrica de TCPSocket.

Agora usamos TCPServer.open(hostname, port) para criar um objeto TCPServer.

A seguir, chamamos o método accept do TCPServer, que espera por uma conexão de cliente na porta especificada e então retorna um objeto TCPSocket que representa a conexão com o cliente.

Exemplo online

require 'socket' # Obter a biblioteca padrão de socket
 
server = TCPServer.open(2000) # O Socket está escutando na porta 2000
loop { # Serviço rodando permanentemente
  client = server.accept # Esperar por conexão do cliente
  client.puts(Time.now.ctime) # Enviar tempo para o cliente
  client.puts "Fechando a conexão. Adeus!"
  client.close # Fechar conexão do cliente
}

Agora, execute o código no servidor e veja o efeito.

Serviço TCP com múltiplos clientes

Na internet, a maioria dos serviços tem uma grande quantidade de conexões de clientes.

A classe Thread do Ruby pode criar serviços multithreaded facilmente, uma thread executa a conexão do cliente enquanto a thread principal espera por mais conexões.

Exemplo online

require 'socket' # Obter a biblioteca padrão de socket
 
server = TCPServer.open(2000) # O socket está escutando na porta}} 2000
loop { # Serviço em execução contínua
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime) # Envie o tempo para o cliente
    client.puts "Fechando a conexão. Adeus!"
    client.close # Feche a conexão do cliente
  end
}

Neste exemplo, o socket é executado permanentemente, enquanto o server.accept recebe a conexão do cliente, uma nova thread é criada e começa a processar a solicitação imediatamente. O programa principal volta ao loop e espera por novas conexões.

Micro navegador Web

Podemos usar a biblioteca socket para implementar qualquer protocolo da Internet. O seguinte código mostra como obter o conteúdo da página da web:

Exemplo online

require 'socket'
 
host = 'pt.oldtoolbag.com' # Servidor web
port = 80 # Porta HTTP padrão
path = "/index.htm" # Endereço do arquivo que você deseja obter
 
# Isso é uma solicitação HTTP
request = "GET #{path} HTTP/1.0\r\n\r\n"
 
socket = TCPSocket.open(host, port) # Conecte ao servidor
socket.print(request) # Envie a solicitação
response = socket.read # Leia a resposta completa
# Divida a resposta na primeira linha em branco em cabeçalhos e corpo
headers, body = response.split("\r\n\r\n", 2) 
print body # Resultado de saída

Para implementar um cliente semelhante ao web, você pode usar bibliotecas pré-construídas para HTTP, como Net::HTTP.

O seguinte código é equivalente ao anterior:

Exemplo online

require 'net/http' # Bibliotecas necessárias
host = 'pt.oldtoolbag.com'  # Servidor Web
path = '/index.htm'  # Arquivo Desejado 
 
http = Net::HTTP.new(host)  # Criação de Conexão
headers, body = http.get(path)  # Solicitação de Arquivo
if headers.code == "200"  # Verificação do Código de Status
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
end

Aqui, apenas apresentamos de maneira simples a aplicação de socket no Ruby, mais documentos podem ser consultados em:Biblioteca de Socket e Métodos de Classes do Ruby