Nasza strona używa cookies. Dowiedz się więcej o celu ich używania i zmianie ustawień w przeglądarce. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Jak programowanie sieciowe reprezentowane jest w Ruby?

Mehdi Farsi Ruby on Rails Senior Developer
Dowiedz się, jak działają biblioteki socket i net w Ruby.

W tym artykule przyjrzymy się następującym tematom:

  • biblioteka socket
  • biblioteka Net 


Wprowadzenie

Z biegiem czasu, komunikacja przez komputery była niezbędna dla ewolucji informatyki na świecie. W rzeczy samej, pozwoliła nam na:

  • wymianę informacji (czat, poczta itp.)
  • współdzielenie plików (FTP itp.)
  • rozpowszechnianie idei, opinii, przekazów (Internet, ...)
  • tworzenie nowych możliwości biznesowych


W tym artykule zobaczymy, jak Ruby zaimplementował programowanie sieciowe w swojej bibliotece standardowej.


Biblioteka socket 

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:

  • Gniazdo TCP -  poprzez klasę TCPSocket
  • Gniazdo UDP -   poprzez klasę UDPSocket
  • Gniazdo UNIX -   poprzez klasę UnixSocket
  • itp.


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:

  • protokół TCP dla TCPSocket
  • protokół UDP dla UDPSocket
  • mechanizm 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 

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:

  • dodaje zestaw klas błędów.
  • wczytuje inne biblioteki potrzebne przez protokoły - takie jak biblioteka socket.
  • dodaje zestaw klas do kontroli operacji read/write poprzez gniazda - 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.


Wniosek

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.

Masz coś do powiedzenia?

Podziel się tym z 120 tysiącami naszych czytelników

Dowiedz się więcej
Rocket dog