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

Programmazione Socket Ruby

Ruby offre due livelli di accesso ai servizi di rete, al livello inferiore puoi accedere al sistema operativo, il che ti permette di implementare il supporto di base per protocolli connessi e non connessi per client e server.

Ruby supporta uniformemente i protocolli di rete delle applicazioni, come FTP, HTTP e altri.

Che sia alto o basso strato, Ruby fornisce alcune classi di base che ti permettono di interagire con molti protocolli come TCP, UDP, SOCKS, senza essere vincolato al livello di rete. Queste classi forniscono anche classi ausiliarie, che ti permettono di leggere e scrivere sui server in modo semplice.

Quindi, diamo iniziamo a imparare come fare programmazione Ruby Socket

Cos'è Sockets

Quando il livello di applicazione comunica attraverso il livello di trasporto, TCP e UDP si incontrano con il problema di fornire servizi concorrenti a più processi di applicazione. Più connessioni TCP o processi di applicazione possono necessitare di trasmettere dati attraverso lo stesso protocollo TCP di porta. Per distinguere diversi processi di applicazione e connessioni, molti sistemi operativi per computer forniscono un'interfaccia chiamata Socket (Socket) per l'interazione dell'applicazione con il protocollo TCP/IP, distinguendo la comunicazione di rete e le connessioni tra diversi processi di applicazione.

Generazione di socket, principalmente con 3 parametri: indirizzo IP del destinatario della comunicazione, protocollo di livello di trasporto utilizzato (TCP o UDP) e porta utilizzata. L'originale del termine Socket è "presa". Combinando questi tre parametri, associati a una "presa" Socket, il livello di applicazione può distinguere la comunicazione proveniente da diversi processi di applicazione o connessioni di rete attraverso l'interfaccia di socket, realizzando servizi di trasmissione dati concorrenti.

Analisi del vocabolario Sockets:

OpzioniDescrizione
domainIndica la famiglia di protocolli utilizzata, di solito PF_INET, PF_UNIX, PF_X25, ecc.
typeSpecifica il tipo di socket: SOCK_STREAM o SOCK_DGRAM, l'interfaccia Socket definisce anche il Socket originale (SOCK_RAW), che permette ai programmi di utilizzare protocolli di basso livello
protocolDi solito assegnato a 0.
hostnameIdentificatore dell'interfaccia di rete:
  • Stringa, può essere il nome dell'host o l'indirizzo IP

  • La stringa "<broadcast>", specifica l'indirizzo INADDR_BROADCAST

  • Stringa di lunghezza 0, specifica INADDR_ANY

  • Un intero che rappresenta l'indirizzo binario di ordine di byte dell'host.

portoIl porto è il numero di porta, ogni server ascolta una o più porte di connessione client, una porta può essere un numero di porta Fixnum che contiene il nome del server e la porta.

Client semplice

Di seguito abbiamo scritto un esempio di client semplice utilizzando un host e un porto forniti, la classe Ruby TCPSocket fornisce un metodo open per aprire una socket.

TCPSocket.open(hosname, port) apre una connessione TCP.

Una volta aperta una connessione Socket, puoi leggerla come un oggetto IO e, una volta completata, devi chiuderla come un file.

Esempio seguente dimostra come connettersi a un host specifico, leggere dati dal socket e infine chiudere il socket:

Esempio online

require 'socket' # Sockets sono parte della libreria standard
 
hostname = 'localhost'
port = 2000
 
s = TCPSocket.open(hostname, port)
 
while line = s.gets # Leggi ogni riga di dati dal socket
  puts line.chop # Stampa sul terminale
fine
s.close # Chiudi il socket

Servizio semplice

In Ruby, è possibile scrivere un semplice servizio utilizzando la classe TCPServer. L'oggetto TCPServer è un oggetto factory per TCPSocket.

Ora stiamo usando TCPServer.open(hostname, port) per creare un oggetto TCPServer.

Successivamente, chiama il metodo accept di TCPServer, che aspetta una connessione client al porto specificato e poi restituisce un oggetto TCPSocket che rappresenta la connessione al client.

Esempio online

require 'socket' # Ottieni la libreria standard socket
 
server = TCPServer.open(2000) # Porta di ascolto del socket impostata su 2000
loop { # Servizio in esecuzione perpetua
  client = server.accept # Attendere la connessione del client
  client.puts(Time.now.ctime) # Invia l'ora al client
  client.puts "Closing the connection. Bye!"
  client.close # Chiudi la connessione del client
}

Ora, esegui il codice sopra nel server per vedere l'effetto.

Servizio TCP multi-client

Sulla rete, la maggior parte dei servizi ha un gran numero di connessioni client.

La classe Thread di Ruby può creare servizi multithreadati con facilità, una thread esegue la connessione del client mentre la thread principale aspetta altre connessioni.

Esempio online

require 'socket' # Ottieni la libreria standard socket
 
server = TCPServer.open(2000) # Porta di ascolto del socket impostata su 2000
loop { # Servizio in esecuzione perpetua
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime) # send time to the client
    client.puts "Closing the connection. Bye!"
    client.close # close the client connection
  fine
}

In questo esempio, il socket rimane in esecuzione in modo permanente, mentre quando server.accept riceve la connessione del client, viene creato un nuovo thread che inizia immediatamente a gestire la richiesta. Il programma principale torna immediatamente in esecuzione e aspetta una nuova connessione.

Micro Web Browser

Possiamo utilizzare la libreria socket per implementare qualsiasi protocollo di Internet. Ecco un esempio di come ottenere il contenuto di una pagina web:

Esempio online

require 'socket'
 
host = 'it.oldtoolbag.com' # web server
port = 80 # default HTTP port
path = "/index.htm" # the address of the file to be retrieved
 
# This is an HTTP request
request = "GET #{path} HTTP/1.0\r\n\r\n"
 
socket = TCPSocket.open(host, port) # connect to the server
socket.print(request) # send the request
response = socket.read # read the complete response
# Split response at first blank line into headers and body
headers, body = response.split("\r\n\r\n", 2) 
print body # output result

Per implementare un client simile a web, puoi utilizzare librerie predefinite per HTTP come Net::HTTP.

Il seguente codice è equivalente al codice precedente:

Esempio online

require 'net/http' # library needed
host = 'it.oldtoolbag.com' # web server
path = '/index.htm' # File desiderato 
 
http = Net::HTTP.new(host) # Creazione della connessione
headers, body = http.get(path) # Richiesta del file
if headers.code == "200" # Verifica lo stato della richiesta
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
fine

In questo articolo abbiamo presentato semplicemente l'applicazione di socket in Ruby, per ulteriori documenti consulta:Libreria Socket e Metodi di Classi Ruby