Prawie każda aplikacja jest obecnie aplikacją w jakiś sposób korzystającą z sieci — najczęściej za pośrednictwem protokołu HTTP. Czasem jednak konieczna jest wiedza ‘jak to działa pod spodem’ i o tym będzie kolejna część Niezbędnika Juniora.
Ten wpis będzie raczej teoretyczny — obecnie bardzo rzadko konieczne jest programowanie bezpośrednio z użyciem połączeń sieciowych. Mimo tego zagadnienia z tym związane pojawiają się podczas rekrutacji, wiedza na ten temat pomoże Ci też zrozumieć dlaczego pewne elementy działają tak, a nie inaczej. Ale przejdźmy do rzeczy.
Model ISO / OSI
Model ten jest standardem, jeśli chodzi o opis sieci. O ile nie aplikujesz na stanowisko inżyniera sieci, nie musisz znać go na pamięć — warto jednak pamiętać nazwę, aby móc odnieść się do niego w razie potrzeby.
Model ten opisuje tzw. stos sieciowy — czyli logiczny podział komponentów związanych z komunikacją sieciową na oddzielne warstwy. W praktyce często jedno urządzenie / oprogramowanie obejmuje kilka warstw, jednak nadal rozróżnienie to jest istotne szczególnie przy opisywaniu i szukaniu informacji. Co ważne — model ten obowiązuje dla wszystkich typów sieci, nie tylko Ethernet czy WiFi — dzięki abstrakcyjnemu podejściu, pozwala na stosowanie wspólnych mechanizmów dla różnych zastosowań, typów sieci czy nośnika.
Wyróżniamy 7 warstw (w tabelce przedstawiono także protokoły na poszczególnych warstwach oraz odniesienie do Internetu — który działa z użyciem tego modelu, ale rozróżnia nieco inne warstwy):
Model OSI | Internet | Protokoły |
---|---|---|
7. Aplikacji | Danych | J2EE, EJB, Jetty |
6. Prezentacji | CSS, HTML, XML, JSON | |
5. Sesji | HTTP, TLS, SSH, FTP | |
4. Transportowa | Segment (TCP) / Datagram (UDP) | TCP, UDP |
3. Sieci | Pakiet | IPv4, IPv6 |
2. Łącza danych | Ramka | IEEE 802.2, PPP, MAC |
1. Fizyczna | Bit | DSL, ISDN, RS-232 |
Dzięki takiej organizacji warstwa ‘wyżej’ nie musi się martwić o to, co jest ‘poniżej’, pomijając warstwę z którą bezpośrednio sąsiaduje. Dlatego np. Twoja aplikacja nie musi rozróżniać pomiędzy połączeniem za pośrednictwem kabla oraz wifi czy wręcz rodzajem kabla użytego do połączenia — interesują ją tylko protokoły warstwy 5 i wyższych. Poszczególne warstwy mają określone funkcje:
- warstwa 1 (fizyczna) — określa jak reprezentowana jest informacja (np. binarnie, gdzie sygnał elektryczny ‘wysoki’ oznacza 1), przykładem może być Ethernet lub RS-232 (połaczenie szeregowe)
- warstwa 2 (łącza danych) — określa, jak dwa połączone za pomocą warstwy pierwszej urządzenia mogą ze sobą rozmawiać (np. jak zapewnić komunikację w obu kierunkach, jak rozwiązywać konflikty itp), przykładem może być protokół PPP (używany np. w modemach ADSL — popularnej niegdyś neostradzie) czy IEEE 802.2 (używana np. przy WiFi) lub MAC (używany w sieciach Ethernet)
- warstwa 3 (sieci) — określa sposób, w jaki mogą być transmitowane dane o różnej długości oraz to, jak komunikacja może się odbywać pomiędzy większą ilośćią węzłów w tej samej sieci w uporządkowany sposób, przykładami są protokoły IPv4 oraz IPv6
- warstwa 4 (transportowa) — definiuje w jaki sposób zapewnić niezawodność transmisji segmentów (pakietów) danych lub inne charakterystyki związane z transmisją, przykładem są protokoły TCP oraz UDP
- warstwy 5–7 czasem bywają przedstawiane razem, jako że niektóre protokoły czy aplikacje zacierają granice pomiędzy nimi — formalnie są one jednak oddzielnymi warstwami
- warstwa 5 (sesji) — określa co oznacza ‘połączenie’ czy ‘pojedyncza sesja’, jak takie połączenie przebiega oraz jak należy zainicjować / zakończyć sesję, przykładami są protokoły TLS/SSL, HTTP, SMTP, SSH
- warstwa 6 (prezentacji) — określa ‘znaczenie’ danych, czyli sposób interpretacji danych, przykładami są np. JSON, XML, CSS czy HTML (choć nie zwykliśmy myśleć o nich jak o protokołach, w istocie standardy te określają pewien kontrakt pomiędzy ‘twórcą’ i ‘czytającym’ — są więc protokołem)
- warstwa 7 (aplikacji) — są to wysokopoziomowe API oraz interfejsy pozwalające na korzystanie z niższych warstw, do przykłądów zaliczymy np. JSP czy ogólnie J2EE
Czasem możesz się spotkać z określeniami typu ‘loadbalancer warstwy 4’ (ang. ‘layer 4 loadbalancing’) — oznacza to tyle, że dla tego loadbalancera istotne (i dostępne) są tylko informacje do warstwy 4 (transportowej) — a więc np. adres IP, port itp, ale nie ‘rozumie’ on (i nie potrafi na tej podstawie podejmować decyzji) zapytań HTTP. Tego typu urządzenia są często realizowane jako urządzenia elektroniczne, podczas gdy w warstwie 7 często mają one formę oprogramowania (w praktyce stosuje się je czasem łącznie lub tylko jeden z nich, w zależności od potrzeb).
To tyle z wstępu, którego nie musisz pamiętać :) Przejdźmy do najważniejszych protokołów.
IP
Protokół IP to jeden z podstawowych protokołów internetowych, który w skrócie określa w jaki sposób jeden komputer może rozmawiać bezpośrednio z drugim — definiuje on standard adresowania komputerów (i innych urządzeń podłączonych do sieci), dzięki czemu nawiązując komunikację możemy jednoznacznie określić, z jakim urządzeniem chcemy się komunikować.
Obecnie najczęściej używaną wersją protokołu jest IPv4, w którym adresy IP składają się z czterech liczb z zakresu 0–255, połączonych kropkami, np. 127.0.0.1 (jest to jeden ze ‘specjalnych’ adresów — w tym wypadku oznaczający zawsze komputer lokalny). Nowsza wersja protokołu — IPv6 — znacząco powiększa pulę dostępnych adresów (co jest coraz większym problemem w przypadku IPv4), są one jednak mniej czytelne dla ludzi (przykładowy adres wygląda następująco: 2001:0db8:0000:0000:0000:0000:1428:57ab).
Protokół IP jest bazowym ‘klockiem’ budulcowym — definiuje on, że dane pomiędzy dwoma systemami są przesyłane w postaci tzw. pakietów. Jeden pakiet zawiera dane oraz nagłówek, gdzie w nagłówku zapisane są informacje takie jak źródło pakietu, cel (adres docelowy), suma kontrolna (pozwala na szybką weryfikację, czy podczas transmisji danych nie wystąpił błąd transmisji), czas życia pakietu (po upływie tego czasu pakiet, o ile nie trafi do adresata, zostanie porzucony) czy tzw. flagi (są to specjalne ‘właściwości’ pakietu, które można przełączać pomiędzy wartością prawda/fałsz).
Zgodnie z zasadą separacji warstw (patrrz wyżej), protokół IP może działać w oparciu o różne protokoły niższego rzędu — zarówno Ethernet (zwykłe połączenie kablowe), jak i IEEE 802.11 (WiFi). Dokument RFC 1149 opisuje także wykorzystanie gołębii do transmisji pakietów IP — choć był to primaaprilisowy żart, technicznie jest to możliwe do implementacji rozwiązanie ;)
Więcej informacji o samym protokole IP oraz szczegółowy opis pakietu znajdziesz np. na wikipedii.
TCP i UDP
TCP oraz UDP są podobnymi protokołami, które bazują na protokole IP (z tego powodu często możesz spotkać się z określeniem TCP/IP — oznacza to protokół TCP działający przy wykorzystaniu protokołu IP). Technicznie rzecz ujmując TCP jest określone oddzielnie od IP i możliwe jest wykorzystanie innego protokołu (jako przykład w dokumentacji można znaleźć np. kombinację TCP / IPX).
Podstawową różnicą pomiędzy TCP oraz UDP jest to, że TCP gwarantuje dostarczenie pakietu lub zwrócenie błędu (innymi słowy nadawca ma pewność, że informacja została dostarczona), UDP z kolei nie zapewnia żadnego mechanizmu tego typu. Ponieważ ‘powiadomienie’ wymaga wysłania informacji powrotnej, protokół TCP jest wolniejszy od UDP jeśli chodzi o przesyłanie danych (formalnie — wymaga więcej interakcji, co powoduje, że ilość przesyłanych danych w sumie jest większa). Z tego powodu UDP jest używany w sytuacjach kiedy czas ma większe znaczenie niż dostarczenie wszystkich danych w niezmienionej postaci — np. streaming audio/video czy synchronizacja zegarów, a także w przypadkach kiedy niskie obciążenie sieci jest ważnym czynnikiem — np. wykrywanie komputerów i urządzeń podłączonych do tej samej sieci. TCP z kolei jest zorientowany na połączenie i dłuższą komunikację, lepiej nadaje się do zastosowań, w których spójność danych i fakt ich dostarczenia w kolejności jest znacznie ważniejszy od szybkości — ma to miejsce np. w przypadku komunikacji email, chatów, czy webserwisów. Bardziej dokładne porównanie i różnice znajdziesz np. na stronie diffen.com .
Poza powyższymi różnicami protokoły te są do siebie podobne — definiują one porty, dzięki którym na jednym urządzeniu może niezależnie działać wiele usług. Istnieją standardowe porty dla różnych protokołów wyższego rzędu (np. 80 — HTTP, 21 — FTP, 22 — SSH, 443 — HTTPS etc), nie ma jednak ograniczeń co do ich używania (poza zabezpieczeniami systemu operacyjnego) — Twoja aplikacja może używać dowolnego z portów do komunikacji. Protokoły te posiadają własne nagłówki — określające m.in. port źródłowy i docelowy, oraz oczywiście właściwe dane. Wszystkie te informacje trafiają do sekcji danych pakietu IP.
SSL i TLS
TLS oraz SSL to protokoły związane z bezpieczeństem komunikacji i jej szyfrowaniem, które zapewniają uwierzytelnianie (obustronne — zarówno serwera jak i klienta), szyfrowanie oraz integralność danych. Ponieważ TLS jest nowszą wersją SSL oraz oba protokoły często bywają nazywane po prostu SSL, takiego skrótu będziemy używać w dalszej części tej sekcji.
SSL (akronim od angielskiego Secure Socket Layer) to zbiór technologii oraz protokołów pozwalających zabezpieczyć dowolną komunikację — choć najczęściej jest używana (i przez to utoższamiana) z protokołem HTTP (HTTPS), znajduje zastosowanie także w innych protokołach i aplikacjach (np. SSH — umożliwiającym bezpieczną komunikację pomiędzy dwoma komputerami).
Przyjrzyjmy się poszczególnym elementom bliżej:
Uwierzytelnianie i wymiana kluczy
Uwierzytelnianie to proces, w którym potwierdzamy toższamość drugiej strony komunikacji. W przypadku SSL uwierzytelnianie jest niejako pobocznym elementem — jest ono możliwe bez zastosowania żadnych dodatkowych zabiegów, ale nie jest integralną częścią protokołu. Cały mechanizm opiera się o tzw. wymianę kluczy — jest to proces, podczas którego obie strony w bezpieczny sposób ustalają między sobą jednorazowe klucze, które będą używane do szyfrowania dalszej komunikacji. Jeśli jesteś zainteresowana, jak to się dzieje dokładnie, polecamy zapoznać się z artykułami na temat PKI (public Key Infrastructure) oraz algorytmu Diffiego-Hellmana. Wystarczy wiedzieć, że można w tym procesie wykorzystać certyfikaty — o ile certyfikat jest zaufany (np. został wystawiony przez nas w przeszłości lub przez zaufane centrum certyfikacji — przykładem może być podpis elektroniczny), dane zapisane w takim certyfikacie można uznać za bezpieczne i na ich podstawie potwierdzić tożsamość drugiego uczestnika komunikacji.
Szyfrowanie
Szyfrowanie to drugi bardzo ważny aspekt protokołu SSL — sam protokół wspiera wiele różnych algorytmów szyfrowania, konkretny jest dobierany za każdym razem kiedy inicjowana jest komunikacja mając na uwadze takie czynniki jak bezpieczeństwo, wydajność oraz obsługa poprzez obie strony (niektóre algorytmy mogą nie być wspierane przez którąś ze stron). Za pomocą kluczy (ustalonych w pierwszym kroku), wszystkie transmitowane dane są szyfrowane, aby uniemożliwić ich odczytanie.
Integralność danych
Integralność danych to innymi słowy zapewnienie, że dane nie zostały zmodyfikowane podczas transmisji. Zastanawiasz się pewnie jak to możliwe — przecież dane są zaszyfrowane, powinny więc być bezpieczne? Otóż szyfrowanie to nic innego jak proces matematyczny, często niepozbawiony wad i słabości. Wielu pasjonatów analizuje algorytmy szyfrujące znajdując ich problemy i słabości, co przekłada się na bezpieczeństwo ich stosowania. Co więcej, niektóre algorytmy są podatne na specjalny rodzaj manipulacji, w której nie odszyfrowując wiadomości możemy zmienić jej treść w określony sposób! Byłoby to bardzo niebezpieczne, biorąc pod uwagę że atakujący mógłby np. zmienić numer konta w naszym zleceniu przelewu na swoje, czy też zmienić kwotę, nie mówiąc już o zmianie rozkazów w wojsku czy informacji od szpiegów i innych jednostek (bo nie ukrywajmy — armie i powiązane organizacje są obecnie najbardziej aktywne na polu tworzenia i analizy algorytmów szyfrujących ;) ). Integralność danych w SSL zapewniana jest poprzez dołączenie ‘podpisu’ — podpis ten wykorzystuje także klucze użyte do szyfrowania i zawiera unikalny ‘skrót’ wiadomości — nie jest możliwe jego prawidłowe zmodyfikowanie zmieniając część wiadomości, wymaga ponownego wyliczenia i znajomości kluczy szyfrujących. Dzięki takiej kombinacji protokół SSL zapewnia, że dane nie są zmanipulowane.
Więcej o protokole SSL oraz szczegółach jego działania znajdziesz np. na wikipedii.
Pozostałe
Istnieje oczywiście wiele innych protokołów — nie wnikając w szczegóły każdego z nich, poniżej przedstawiamy krótką listę protokołów wraz z opisem do czego służy. Po szczegóły odsyłamy do Wikipedii lub dokumentacji :)
- DNS — protokół, który pozwala zamieniać ‘przyjazne’ nazwy (np. google.pl czy kobietydokodu.pl) na adres IP zrozumiały dla komputerów
- HTTP — podstawowy protokół internetowy, więcej o nim znajdziesz w naszym wpisie na jego temat
- FTP — pozwala na wymianę plików pomiędzy dwoma komputerami
- SMTP — służy do przesyłania (wysyłania) poczty elektronicznej
- POP3 — służy do komunikacji z serwerem i odczytywania poczty elektronicznej
- IMAP — bardziej rozbudowany protokół do odczytywania poczty elektronicznej (w odróżnieniu od POP3 pozwala np. na synchronizacje statusu wiadomości — czy jest przeczytana/oznaczona jako ważna itp — oraz wyszukiwanie wiadomości po stronie serwera)
Jeśli chciałabyś poczytać więcej o protokołach, które ‘tworzą’ internet, jaki znamy, na Wikipedii znajduje się rewelacyjne podsumowanie wraz ze szczegółowymi opisami wszystkich.
Rodzaje komunikacji pomiędzy aplikacjami
Aplikacje mogą także komunikować się ze sobą na różne sposoby — protokoły możemy podzielić wg dwóch zasadniczych kryteriów:
- czy aplikacje komunikują się bezpośrednio ze sobą czy uczestniczy w tym także serwer ‘centralny’
- czy aplikacje komunikują się tylko w przypadku wystąpienia jakiegoś zdarzenia (np. wpisanie adresu w przeglądarce) czy utrzymują połączenie cały czas
Komunikacja P2P i za pośrednictwem serwera centralnego
Te dwa modele komunikacji różnią się w szczególności tym, jaka jest ‘trasa’ wymienianych danych.
Komunikacja P2P
Komunikacja P2P (ang. point-to-point) to sytuacja, w której dwa urządzenia komunikują się bezpośrednio ze sobą, bez udziału centralnego serwera pośredniczącego w komunikacji. Taka komunikacja ma kilka zalet — zwykle jest szybsza, odporniejsza na ataki (brak centralnego serwera, który mógłby ‘podsłuchać’ wszystko) oraz awarie (nie ma znaczenia, czy serwer działa czy nie, jeśli nie uczestniczy w komunikacji). Jest ona jednak bardziej wymagająca w implementacji — oba urządzenia muszą się ‘widzieć’ — tj muszą być w stanie rozmawiać ze sobą bezpośrednio, muszą też ‘odnaleźć’ się na początku komunikacji — co może nie być proste, z uwagi na zmieniające się adresy IP w przypadku domowych łącz internetowych.
Komunikacja z wykorzystaniem serwera centralnego
W tym modelu komunikacja odbywa się wyłącznie pomiędzy serwerem a klientem — jeśli informacja ma trafić do innego klienta, jest ona przekazywana przez serwer. Taki model znacząco upraszcza implementację, ponieważ serwer najczęściej jest widoczny ‘publicznie’ (tj. w Internecie) oraz można go ‘odnaleźć’ korzystając z łatwej nazwy (np. google.com — nawet jeśli fizycznie serwer zostanie przeniesiony, to nadal może być dostępny pod tą samą nazwą). Wadą takiej komunikacji jest dłuższa ‘trasa’ danych, co ma wpływ na szybkość transmisji (z tego powodu komunikatory transmitujące wideo często nie korzystają z tej metody). Tworzy to także centralny punkt, który może zawieść (ang. single point of failure, SPOF) — jeśli serwer centralny ulegnie awarii lub zostanie przejęty, zagrożona będzie cała komunikacja lub klienci nie będą w stanie przesyłać żadnych informacji.
Każdy z tych modeli ma wady i zalety — ważne jest, żeby wiedzieć o istnieniu obu oraz dobrać poprawne rozwiązanie do zastosowania, nad którym aktualnie pracujesz :)
Komunikacja zapytanie-odpowiedź oraz strumieniowa
Drugi podział rozróżnia sposób, w jaki dane są przesyłane — czy w odpowiedzi na konkretne zapytanie czy raczej jako ciągły ‘strumień’.
Komunikacja zapytanie-odpowiedź ma miejsce wtedy, kiedy jedna strona odpowiada na konkrente zapytanie drugiej strony — bardzo dobrym przykładem jest protokół HTTP, w którym klient wysyła zapytanie (z informacją o adresie strony, jaką chce wyświetlić, przesyłanych danych itp), na które serwer wysyła odpowiedź (przygotowaną pod to konkretne zapytanie — np kod HTML strony).
Komunikacja strumieniowa to komunikacja, w której dane są przesyłane w sposób ciągły, a nie w odpowiedzi na konkretne zapytanie. Przykładem może być tutaj transmisja wideo w komunikatorze czy np. obraz z kamery internetowej lub internetowego radio.
Podsumowanie
W tym wpisie było sporo teorii — nie martw się jeśli nie pamiętasz wszystkiego, zawsze możesz wrócić za jakiś czas i poprawić swoją wiedzę :) Z punktu widzenia szukania pracy oraz codziennej pracy, możesz się sprawdzić czy potrafisz odpowiedzieć na poniższe pytania:
- Jaka jest różnica pomiędzy TCP a UDP?
- Implementując komunikator video, użyłabyś protokołu UDP czy TCP i dlaczego?
- Do czego służy protokół SMTP / POP3 / HTTP / DNS / SSH / TLS … ?
- Jakie znasz protokoły związane z sieciami? Wymień i krótko opisz 3
- Czym się różni aplikacja korzystająca z P2P od takiej, która korzysta z serwera centralnego?
- W jaki sposób mogą się komunikować dwie aplikacje (chodzi o wyjaśnienie różnicy pomiędzy komunikacją zapytanie-odpowiedź oraz komunikacją strumieniową (streamingiem)?