W tym artykule przyjrzymy się następującym tematom:
socket
Net
Z biegiem czasu, komunikacja przez komputery była niezbędna dla ewolucji informatyki na świecie. W rzeczy samej, pozwoliła nam na:
W tym artykule zobaczymy, jak Ruby zaimplementował programowanie sieciowe w swojej bibliotece standardowej.
Po pierwsze, jeśli nie wiesz, co to jest gniazdo (socket):
Gniazda są punktami końcowymi dwukierunkowego kanału komunikacyjnego. Mogą komunikować się w ramach procesu, pomiędzy procesami na tej samej maszynie lub pomiędzy różnymi maszynami.
Biblioteka socket
jest odpowiedzialna za zapewnienie dostępu do różnego rodzaju istniejących gniazd:
TCPSocket
UDPSocket
UnixSocket
Biblioteka ta jest częścią biblioteki standardowej Ruby. W Rubym, root class każdego Socket
jest klasa BasicSocket
.
require 'socket'
BasicSocket.superclass # => IO
BasicSocket.methods(false) # => [:for_fd, :do_not_reverse_lookup, :do_not_reverse_lookup=]
BasicSocket.instance_methods(false) # => [:setsockopt, :connect_address, :local_address, :close_read, :sendmsg, :close_write, :remote_address, :recv_nonblock, :sendmsg_nonblock, :recvmsg, :recvmsg_nonblock, :do_not_reverse_lookup, :do_not_reverse_lookup=, :shutdown, :getsockopt, :getsockname, :getpeername, :getpeereid, :recv, :send]
Ta klasa dziedziczy po IO
. Klasa IO
jest odpowiedzialna za obsługę strumienia wejściowego (Input) i wyjściowego (Output) - takich jak instancje File
, $stdin
, $stdout
lub $stderr
. Oznacza to, że nasz socket
jest interpretowany jako strumień I/O.
Ponadto klasa BasicSocket
oferuje kilka metod dostępu do właściwości socket
i kilka metod zapisu i odczytu z gniazda - takich jak blokujące i nieblokujące read
i write
. Klasy TCPSocket
, UDPSocket
i UNIXSocket
wywodzą się z BasicSocket
.
Właściwie TCPSocket i UDPSocket wywodzą się z IPSocket, który wywodzi się z BasicSocket
. Wszystkie one używają procedur zdefiniowanych w BasicSocket
i implementują protokół związany z ich typem gniazda:
TCP
dla TCPSocket
UDP
dla UDPSocket
IPC
dla UNIXSocket
Biblioteka socket
jest odpowiedzialna za obsługę komunikacji niskopoziomowej poprzez protokół internetowy (UDP i TCP) oraz międzyprocesowy mechanizm komunikacji.
Teraz zobaczmy, jak Ruby implementuje wysokopoziomowe protokoły, takie jak HTTP
, IMAP
, SMTP
i FTP
.
Biblioteka Net
jest odpowiedzialna za zapewnienie implementacji protokołów wysokiego poziomu. Obsługiwane protokoły to FTP
, HTTP
, IMAP
, POP
i SMTP
.
Widzimy, że wszystkie te protokoły są zaimplementowane w określonej klasie w przestrzeni nazw Net
. Również te klasy wywodzą się z klasy Net::Protocol
.
Przyjrzyjmy się zawartości tej klasy.
require 'net/protocol'
Net::Protocol.superclass # => Object
Net::Protocol.methods(false) # => [:protocol_param]
Net::Protocol.instance_methods(false) # => []
Klasa Net::Protocol
dziedziczy po Object
- klasie domyślnie dziedziczonej w Ruby.
Zapraszam do przeczytania mojego artykułu na temat Ruby Object Model jeśli nie znasz klasy Object
w Ruby.
Implementuje również metodę klasową protocol_param
, która jest wykorzystywana do definiowania oczekiwany parametrów protokołu. Jest to bardzo lekki obiekt. Poza tym, wczytanie biblioteki net/protocol
dodaje trochę więcej niż samą klasę.
Jeśli nie znasz metody Kernel#require
w Ruby, możesz przeczytać o używaniu require do wczytywania pliku lub biblioteki w Ruby.
Rzeczywiście, oprócz klasy Net::Protocol
, biblioteka net/protocol
:
socket
.BufferedIO
, WriteAdapter
, itp.
Tak więc, klasa, która wywodzi się z Net::Protocol
zapewnia implementację danego protokołu i obsługuje błędy oraz operacje na strumieniu I/O przy użyciu narzędzi dostarczanych przez bibliotekę net/protocol
.
Ponieważ Ruby jest w pełni obiektowym językiem programowania, implementacja programowania sieciowego wykorzystuje wszystkie narzędzia dostarczane przez te języki - takie jak namespacing, dziedziczenie, klasa root, obsługa błędów, wczytywanie zależności (słowo kluczowe require
).
Ruby implementuje również niskopoziomowe i wysokopoziomowe protokoły sieciowe w dwóch różnych bibliotekach: socket
i net/*
.
I co najważniejsze, korzystając z abstrakcji dostarczonej przez Ruby można łatwo wdrożyć nowy protokół - poprzez dziedziczenie BasicSocket
lub Net::Protocol
w zależności od Twoich potrzeb.
Oryginał tekstu w języku angielskim przeczytasz tutaj.