Istnieje wiele programów służących wymianie plików w Internecie, wyróżniających się interfejsem, rozbudowanym sposobem wyszukiwania plików czy obsługiwanym systemem operacyjnym. Do tej grupy możemy zaliczyć programy oparte o protokół Gnutella.
Historia Gnutelli rozpoczyna się 14 marca 2000 roku, gdy program został umieszczony na stronie firmy Nullsoft (znanej jako producent popularnego odtwarzacza audio/video Winamp). W kilka godzin program został pobrany przez tysiące użytkowników. W obawie o względy prawne jego pobieranie zostało wkrótce zablokowane. Jednak program szybko znalazł uznanie użytkowników, którzy odtworzyli kod źródłowy programu i został on opublikowany na licencji GNU General Public License2 (GPL), otwierając drogę do powstania programów opensource, bazujących na tym protokole.
Gnutella jest jednym z niewielu rozwiązań P2P, będącym całkowicie zdecentralizowanym, co oznacza, że w sieci nie występuje żaden centralny serwer i nie wymaga do swojego działania stałego elementu w sieci. Słowo Gnutella odnosi się zarówno do protokołu, jak i sieci go wykorzystującej. Często używa się terminu GnutellaNet lub GNet do określenia sieci i w niniejszej pracy ten termin również będzie obowiązywał.
Podstawą protokołu Gnutella jest specyfikacja w wersji 0.4 [2], Jednakże większość obecnie działających programów opiera się o ciągle rozwijaną i niemającą statusu stabilnego wersję 0.6 [3].
Przy projektowaniu Gnutelli zrezygnowano z dotychczasowego modelu komunikacji internetowej opartej o serwer. Każdy klient sieci jest zarazem serwerem. Ten nowy model określono mianem serwentu (ang. servent od słów server/client). To założenie miało za zadanie uniemożliwić niedostępność sieci bądź jej wyłączenie przez pozbycie się newralgicznych punktów, jakimi do tej pory były centralne serwery.
Poniżej wymieniona została terminologia występująca w opisie protokołu i sieci Gnutella:
Serwent – komputer z programem, pełniący jednocześnie rolę klienta i serwera. Podobne znaczenie mają również wyrazy „peer”, „node” (węzeł) i „host”. Jeżeli opisywana jest funkcjonalność typowa dla klienta bądź serwera, terminologia klient i serwer również ma zastosowanie
Komunikat (ang. Message) – jednostka, którą informacje przesyłane są poprzez sieć. Czasami podobne znaczenie mają wyrazy „pakiet” (ang. packet) lub deskryptor (ang. descriptor)
GNet – akronim sieci Gnutella służącej do łączenia hostów z zaimplementowanym protokołem Gnutella
GUID - Globally Unique Identifier (globalnie unikatowy identyfikator). To 16-sto bitowy generowany losowo identyfikator, używany do identyfikacji serwentów i komunikatów w sieci.
Bazowa wersja protokołu zakładała równorzędność wszystkich węzłów sieci. Każdy węzeł – serwent był jednocześnie klientem, jak i serwerem w sieci i żaden nie był wyróżniony spośród innych. Sieć skonstruowana w ten sposób posiada bardzo prostą strukturę. Każdy serwent łączy się z kilkoma sąsiednimi serwentami w sieci (rys. 7).
Rysunek 7 Podstawowa struktura sieci zbudowana ze zwykłych węzłów
To rozwiązanie wprowadzało niestety sporo ograniczeń i problemów takich jak:
Mała skalowalność
Duża ilość informacji wysyłanych przez każdy równouprawniony węzeł
Kolejne wersje protokołu wprowadziły jednak podział węzłów, aczkolwiek obecność węzłów sieci spełniających wcześniejsze założenia (zwanych dalej zwykłymi węzłami) w obecnej wersji protokołu jest dozwolona.
Podział hierarchiczny węzłów sieci został dokonany ze względu na opisane powyżej problemy ze skalowalnością i uczestnictwem wszystkich węzłów w wymianie komunikatów, co powodowało duże obciążenie sieci.
Specyfikacja 0.6 protokołu zakłada wyróżnienie dwóch rodzajów węzłów:
Ultrapeer (UP) – pełna funkcjonalność
Leaf (ang liść)- ograniczona funkcjonalność
UP utrzymują połączenia miedzy sobą, jak i z węzłami Leaf połączonymi z nimi. Każdy UP może mieć podłączonych od 10 a 100 węzłów Leaf i utrzymuje połączenia z kilkoma węzłami typu UP bądź zwykłymi węzłami. Dodatkowo UP chronią Leaf przed nadmierną ilością zapytań, jak i przyjmują od nich zapytania.
Leaf jest węzłem o mniejszej funkcjonalności. Utrzymuje on tylko kilka aktywnych połączeń i to tylko z węzłami UP, nie są do niego również przekazywane wszystkie komunikaty.
Struktura sieci z węzłami UP i Leaf przedstawia się nieco inaczej (porównaj rys. 7), co obrazuje rysunek 8. Na rysunku znajdują się również zwykłe węzły. Są to węzły używające poprzedniej wersji protokołu, gdzie wszystkie węzły były równorzędne (określane jako serwent). Umieszczenie tych węzłów na rysunku podkreśla kompatybilność obecnej wersji protokołu z wcześniejszymi.
Rysunek 8 Struktura sieci z węzłami typu UP, Leaf i węzłami zwykłymi
Węzeł typu Ultrapeer spełnia następujące założenia:
otwarty port połączeń przychodzących
odpowiedni system operacyjny, preferowane są Linux, Windows 2000/NT/XP i Mac OS/X
odpowiednio szybkie połączenie internetowe
odpowiedni uptime – czas, w którym węzeł jest połączony z siecią GNet, zazwyczaj jest to kilka godzin
odpowiednia szybkość procesora i wielkość pamięci RAM, ze względu na możliwość obsługi wielu połączeń i przechowywania tablicy rutingu3 (ang. routing)
Powyższe parametry nie gwarantują serwentowi, że będzie on typu UP. Spełniając powyższe wymagania jest on kandydatem do bycia UP w momencie, gdyby w sieci zaistniała taka konieczność.
Standardowym portem, na którym serwent przyjmuje połączenia jest 6346, aczkolwiek inny port może być również wykorzystywany; wiadomość o numerze portu przekazywana jest poprzez komunikaty Gnutelli.
By połączyć się do sieci serwentowi potrzebna jest znajomość przynajmniej jednego adresu IP innego serwentu. Adresy IP innych serwentów mogą być dostarczone różnymi drogami. W starszych implementacjach wyróżniamy następujące sposoby wyszukiwania węzłów sieci:
zdefiniowana lista węzłów w programie instalacyjnym
GwebCaches – strony www, zawierające listę potencjalnych aktywnych węzłów sieci
IRC (ang. Internet Relay Chat)
ręczne wprowadzenie adresów IP aktywnych węzłów
lista węzłów aktywnych i awaryjnych zapisana podczas poprzedniego logowania
W obecnych rozwiązaniach wyróżnia się 4 sposoby pozyskiwania adresów innych serwentów i są to:
GwebCaches
zapisywanie adresów z nagłówków X-Try (lista adresów serwentów, z którymi można nawiązywać połączenia)
zapisywanie adresów z komunikatów Pong
zapisywanie adresów z komunikatów QueryHit
Najbardziej podstawowym i rozwijanym sposobem uzyskiwania adresów jest GwebCache (Gnutella Web Caching System). Jest to aplikacja zainstalowana na serwerze WWW hosta sieci GNet, zbierająca i udostępniająca adresy aktywnych węzłów.
W czasie, gdy dany serwent ma już listę innych serwentów, z którymi może się połączyć, następuje procedura inicjowania połączenia - handshaking. Handshaking odbywa się z wykorzystaniem protokołu TCP/IP. Jeżeli przyjmiemy, że host inicjujący połączenie to klient, a odbierający serwer, procedura przebiega w następujący sposób:
Klient nawiązuje połączenie TCP
Klient wysyła komunikat GNUTELLA CONNECT/0.6<cr><lf>
Klient wysyła wszystkie swoje nagłówki kończąc każdy poprzez <cr><lf>
Serwer powinien odpowiedzieć komunikatem GNUTELLA/0.6 200 <string><cr><lf>
Serwer wysyła wszystkie swoje nagłówki w schemacie opisanym w podpunkcie c.
Klient powinien odpowiedzieć GNUTELLA/0.6 200 OK<cr><lf>
Klient powinien wysłać inne swoje nagłówki, jeżeli zachodzi taka potrzeba w formacie jak w podpunkcie c.
Klient i serwer wysyłają między sobą komunikaty binarne, używając informacji z podpunktów c. i e.
Oto przykładowa wymiana komunikatów między klientem i serwerem podczas inicjowania połączenia:
Rysunek 9 Inicjowanie połączenie między zwykłymi węzłami4
Jeżeli klient podczas inicjowania połączenia wyśle inny komunikat niż opisany w punkcie c, serwer powinien go odrzucić. Serwer może również odrzucić połączenia z innych przyczyn, np. braku wsparcia wersji protokołu, którego używa klient.
Powyższy opis odnosi się do sytuacji, gdy mamy do czynienia ze zwykłymi węzłami sieci. Jeżeli mamy do czynienia z węzłami typu UP i Leaf komunikaty wzbogacone są o dodatkowe zmienne:
X-Ultrapeer – zmienna informująca czy dany host jest typu UP
X-Ultrapeer-Needed – zmienna potrzebna do zestawiania liczby węzłów UP
X-Try-Ultrapeer – lista adresów węzłów UP
X-Query-Routing – zmienna wspierająca protokół QRP (rozdział 2.1.8.2)
Poniżej zostaną przedstawione typowe schematy połączeń w sieci między węzłami różnego typu z wykorzystaniem powyższych zmiennych.
2.1.5.1. Połączenie UP – Leaf
W tym przypadku Leaf nawiązuje połączenie z UP, jeżeli połączenie zakończy się sukcesem, Leaf odrzuca wszystkie połączenia z węzłami innego typu niż UP (o ile je posiadał) i wysyła do UP swoją tablicę QRP.
Rysunek 10 Połączenia typu UP - Leaf
2.1.5.2. Połączenie Leaf – Leaf
Próba połączenia węzła typu Leaf z innym węzłem typu Leaf powinna zakończyć się rozłączeniem tak, jak na poniższym rysunku.
Rysunek 11 Połączenie typu Leaf – Leaf
2.1.5.3. Połączenia UP - UP
Połączenia UP – UP mogą przebiegać w dwojaki sposób. Pierwszy (rys. 12) zakłada połączenie dwóch UP, mających podłączone do siebie inne węzły typu Leaf.
Rysunek 12 Połączenie UP – UP
Może jednak zdarzyć się przypadek, w którym do danego węzeł typu UP nie jest połączony żaden węzeł typu Leaf, a dodatkowo w sieci jest już wystarczająca liczba węzłów UP. Wtedy status jednego z węzłów może zostaje zmieniony na Leaf, co przedstawia poniższy rysunek.
Rysunek 13 Połączenie UP – UP zakończone zmianą statusu jednego z węzłów.
Gdy połączenie do sieci GNet zostało już nawiązane, komunikacja między serwentami odbywa się poprzez kilka zdefiniowanych komunikatów. Każdy komunikat poprzedzony jest nagłówkiem komunikatu o ustalonej strukturze. W jednym pakiecie IP może znajdować się kilka komunikatów Gnutelli, jak i dozwolona jest sytuacja, gdy jeden komunikat Gnutelli zajmuje kilka pakietów IP.
2.1.6.1. Nagłówek komunikatów Gnutelli
Struktura nagłówka komunikatów Gnutelli przedstawiona jest na rysunku 14. Każdy nagłówek zawiera 23 bajty.
Fields | GUID | Payload Descriptor | TTL | HOPS | Payload Length |
Byte offset | 0...15 | 16 | 17 | 18 | 19..22 |
Rysunek 14 Nagłówek komunikatów Gnutelli
Poszczególne pola nagłówka komunikatu mają następujące znaczenie:
GUID - Globally Unique Identifier (globalnie unikatowy identyfikator). To 16-sto bitowy generowany losowo identyfikator, używany do identyfikacji serwentów i komunikatów w sieci
Payload Descriptor (rodzaj komunikatu) – określa, jakiego typu jest dany komunikat
TTL (ang. Time to Live) - określa on liczbę przeskoków, jaką komunikat będzie przekazywany kolejnym serwentom. Każdy serwent musi obniżyć liczbę TTL o jeden w momencie przekazywania komunikatu dalej. Jeżeli TTL osiągnie wartość 0 (zero), komunikat nie będzie już dalej przekazywany
Hops – określa ile razy dany komunikat został przekazany kolejnemu serwentowi, jeżeli komunikat przekazywany jest od serwentu do serwentu. TTL i Hops muszą spełniać następujący warunek: TTL(0) = TTL(i) + Hops(i), gdzie TTL(i) i Hops(i) jest wartością umieszczoną w komunikacie, TTL(0) to maksymalna wartość startowa ( zazwyczaj równa 7)
Payload Length (długość ładunku) – określa liczbę bajtów znajdujących się w pakiecie, licząc od końca nagłówka. Jest to bardzo ważny element, gdyż na jego podstawie serwent rozpoznaje, gdzie znajduje się początek kolejnego komunikatu.
2.1.6.1. Rodzaje komunikatów
Protokół Gnutella określa kilka podstawowych komunikatów, aczkolwiek dozwolone jest używanie niestandardowych komunikatów zdefiniowanych, np. dla konkretnego programu. Informacje o dodatkowych rodzajach komunikatów wymieniane są miedzy serwentami w czasie inicjowania połączenia. Rodzaje poszczególnych komunikatów opisane są w poniższych podrozdziałach.
2.1.6.1.1. Ping
Komunikat wysyłany w celu aktywowania połączenia z innym serwentem. Serwent odbierający przekazuje go dalej do innych serwentów, może też sam odpowiedzieć komunikatem Pong, jeżeli chce nawiązać połączenie z nadawcą komunikatu Ping. Komunikat ten nie zawiera standardowo danych, aczkolwiek istnieje możliwość umieszczenia w tym komunikacie bloku GGEP (Gnutella Generic Extension Protocol, patrz rozdział 2.1.6.2)
2.1.6.1.2. Pong
Komunikat wysyłany w odpowiedzi na Ping. Powinien zawierać GUID komunikatu Ping, na który odpowiada. Zawiera następujące dane:
adres IP i numer portu, na którym przyjmuje połączenia
liczbę plików, które udostępnia
ilość danych, które udostępnia w kB
(opcjonalnie) blok GGEP
2.1.6.1.3. Query
Komunikat Query (zapytanie) jest używany w celu wyszukania danego pliku.. Długość zapytania nie powinna przekraczać 256 bajtów i nie może przekraczać 4 kB, Zapytanie przekraczające 4kB będzie odrzucone.
Komunikat Query zawiera następujące pola:
minimalną prędkość w kb/s – jeżeli serwent odbierający zapewnia mniejszą prędkość przesyłu danych nie może odpowiedzieć na zapytanie
tekst lub słowo kluczowe (określające nazwę wyszukiwanego pliku)
(opcjonalne) bloki rozszerzające funkcjonalność komunikatu
2.1.6.1.4. QueryHits
Jest komunikatem wysyłanym w odpowiedzi na komunikat Query. Zawiera następujące pola:
liczbę plików spełniających kryterium zapytania
adres IP i numer portu , na którym przyjmuje połączenia
prędkość przesyłu danych z jaką może odbyć się komunikacja
nazwę, wielkość i unikalny identyfikator pasującego do zapytania pliku
GUID serwentu, wysyłającego komunikat QueryHits, głównie dla potrzeb komunikatu Push
opcjonalny, ale rekomendowany blok EQHD zawierający takie informacje jak; nazwa programu hosta, informację o zajętych slotach dla połączeń przychodzących (tzw. flaga flagBusy) czy bardzo ważną informację o niemożliwości przyjmowania połączeń przychodzących z powodu firewalla5 (tzw. flaga flagPush)
2.1.6.1.5. Push
Ten komunikat jest wysyłany przez serwent wyszukujący plik w momencie otrzymania komunikatu QueryHits, z informacją o niemożliwości przyjmowania połączeń przychodzących.
Komunikat Push zawiera następujące informacje:
GUID wysłany w QueryHits serwentu „proszącego” o Push
GUID pliku wysłany w QueryHits serwentu „proszącego” o Push
adres IP i numer portu, na którym serwent wysyłający komunikat Push może przyjąć połączenia
opcjonalnie blok GGEP
2.1.6.1.6. Bye
Bye jest komunikatem opcjonalnym i używanym do powiadomienia serwentów, z którymi dany serwent jest połączony, o wyłączeniu się z sieci wraz z podaniem przyczyny. Komunikat wysyłany jest z TTL=1, by nie był wysyłany dalej przez serwent, który go otrzymał.
2.1.6.2. GGEP – rozszerzenie protokołu Gnutella
GGEP - Gnutella Generic Extension Protocol jest protokołem rozszerzającym możliwości protokołu Gnutella, pozwalającym na zwiększenie funkcjonalności jego komunikatów. Serwenty używające GGEP muszą powiadomić o tym fakcie inne serwenty w czasie inicjacji połączenia, dołączając tę wiadomość do nagłówka. Jeżeli serwent używający GGEP wysyła komunikaty do serwentów nieobsługujących to rozszerzenie, to powinien usunąć ten blok ze swoich komunikatów.
Jeżeli węzeł został już podłączony do innego węzła wymienia z nim listę aktywnych węzłów i próbuje się z nimi połączyć. Dany serwent buduje w ten sposób listę aktywnych węzłów. Teoretycznie wymiana informacji z kolejnymi węzłami może trwać aż do wyszukania wszystkich aktywnych węzłów, jednak praktycznie ilość węzłów, z którymi nawiązuje się połączenie, jest definiowalna. Zazwyczaj liczba węzłów, z którymi nawiązano połączenie wynosi około 5.
Serwent utrzymuje również listę innych węzłów, z którymi nie nawiązał jeszcze połączenia (jako alternatywne) oraz odrzuca te z którymi połączyć mu się nie udało.
Informacje na temat aktywnych węzłów sieci, z którymi można się połączyć zdobywana jest za pośrednictwem komunikatów Ping i Pong.
W bazowej wersji protokołu serwent wysyła komunikat Ping do węzłów, z którymi jest połączony, a te przekazują ten komunikat dalej do swoich sąsiadów (czyli węzłów, z którymi mają aktywne połączenie), zmniejszając o 1 wartość TTL i zwiększając o 1 wartość Hops. Oczywiście każdy Ping opatrzony jest odpowiednią wartością TTL, by wiadomość nie krążyła w sieci bez końca. Zazwyczaj wartość ta ustawiona jest na 7. Serwent odbierający, o ile może nawiązać połączenie, odsyła komunikat Pong. Serwent ma też za zadanie nie przekazywać dalej komunikatów Pong z tym samym GUID i Payload Descriptor, które odebrał wcześniej. Przykładowy ruting komunikatów Ping i Pong przedstawia rysunek 15.
Rysunek 15 Ruting komunikatów Ping i Pong6
Komunikat Pong wraca do nadawcy tą samą drogą, którą przebył komunikat Ping. Takie rozwiązanie niesie za sobą bardzo duże natężenie ruchu w sieci, więc w nowszych implementacjach protokółu, wprowadzono mechanizm zwany Pong-cache.
2.1.7.2. Mechanizm Pong-cache
Pong-cache jest mechanizmem pozwalającym znacznie ograniczyć ilość komunikatów Pong w sieci. Każdy serwent tworzy bazę danych komunikatów Pong dla każdego z połączeń, które aktualnie obsługuje. W bazie tej zapisuje odebrane wiadomości Pong. Liczba rekordów w bazie jest ograniczona (zazwyczaj do kilkunastu). Gdy serwent otrzymuje nowy komunikat Pong, zapisuje go w bazie, nadpisując najstarszą zanotowaną wartość. W momencie, gdy serwent otrzymuje komunikat Ping, odsyła od razu kilka komunikatów Pong (zazwyczaj 10) ze swojej bazy danych i przesyła Ping dalej, jak miało to miejsce wcześniej. Serwent wysyłając komunikaty Pong zmienia GUID na GUID adresata Ping. Dla ciągłego odświeżania bazy Pong-cache serwent wysyła co 3 sekundy komunikat Ping z TTL=7 i Hops=0. Oczywiście serwenty podczas nawiązywania połączenie powinny wymienić ze sobą informacje o wersji Pong-caching, jaki obsługują np.: "Pong-Caching: 0.1".
Wyszukiwanie plików jak i wyszukiwanie hostów również można podzielić na dwie grupy. Pierwsza to standardowe wyszukiwanie zgodne z podstawową wersją protokołu Gnutelli, drugie pojawiło się wraz z rozszerzeniem protokołu i wprowadzeniem podziału na hosty UP i Leaf. Obie wersje mogą ze sobą współpracować, a szczegółowy opis każdej z nich zamieszczony jest w kolejnych podrozdziałach.
2.1.8.1. Wyszukiwanie plików w wersji podstawowej
Wyszukanie pliku polega na wysłaniu komunikatu Query do innych węzłów sieci, z którymi wcześniej nawiązano połączenie. Tak jak w przypadku komunikatów Ping i Pong, Query przekazywane jest dalej zgodnie z wartością TTL zawartą w komunikacie. Każdy węzeł, który otrzymał komunikat Query, sprawdza kryteria wyszukiwania i dopasowuje je do listy swoich zbiorów. Jeżeli spełnia te kryteria (posiada dany plik), odsyła tą samą drogą komunikat QueryHits. W przypadku, gdy nie może przyjmować połączeń przychodzących, informuje o tym nadawcę, ustawiając bit flagPush w odpowiednią wartość. Odbiorca po otrzymaniu takiej informacji może użyć komunikatu Push w celu pobrania interesującego go pliku (rozdział 2.1.9.1). GUID QuueryHit powinien być identyczny z identyfikatorem komunikatu Query, na który dany serwent odpowiada. Nadawca Query po otrzymaniu odpowiedzi w postaci QueryHits nawiązuje bezpośrednie połączeni z nim. Jeżeli węzeł otrzyma odpowiedź od więcej niż jednego węzła, może wykonać tzw. swarm download - ściągnięcie kawałków pliku z różnych komputerów, przez co skraca się czas pobierania pliku. Plik pobierany jest z wykorzystaniem protokołu HTTP, a nie Gnutella (rozdział 2.1.9). Rysunek 16 przedstawia ruting komunikatu Query.
Rysunek 16 Routing komunikatów Query i QueryHit
2.1.8.2. Wyszukiwanie plików w wersji rozszerzonej
W przypadku, gdy mamy węzły typu UP i Leaf, wyszukiwanie pliku odbywa się w nieco inny, rozszerzony sposób. Jak już wcześniej wspomniano, podział węzłów sieci został dokonany ze względu na ograniczenie ruchu sieciowego i zwiększenie skalowalności sieci. Dodatkowo hosty z łączami o słabszych parametrach odciążone są przez węzły UP poprzez zastosowanie protokołu QRP - Query Routing Protocol.
Zasada działania protokołu QRP przedstawia się następująco. Każdy węzeł typu Leaf buduje bazę nazwaną boolean vector, wyrazów z nazw plików, które udostępnia, a następnie przesyła ją do UP, z którym jest połączony. Węzeł UP zapisuje wszystkie boolean vector, które otrzymał od swoich węzłów typu Leaf. W momencie, gdy do UP przychodzi komunikat Query, ten przed wysłaniem go do węzłów Leaf porównuje warunki zapytania z bazami boolean vector i jeżeli jakieś zapytanie pasuje, przekazuje komunikat Query danemu Leaf. W przeciwnym wypadku, komunikaty Query nie są przekazywane. Węzeł UP przekazuje Query tylko innym węzłom UP, a także serwentom niewspierającym tej technologii (zwykłym węzłom). Także węzeł typu Leaf będzie otrzymywał wszystkie komunikaty Query, o ile nie wyśle do swojego UP tablicy boolean vector.
Po otrzymaniu komunikatu QueryHit serwent może zainicjować procedurę pobierania pliku. Pobieranie pliku odbywa się poza siecią GNet z wykorzystaniem protokołu HTTP. Rekomendowaną wersją protokołu HTTP jest 1.1.
Serwent nawiązuje bezpośrednie połączenie z serwentem udostępniającym plik, wysyłając komunikat w następującej formie:
GET /get/<File Index>/<File Name> HTTP/1.1<cr><lf>
User-Agent: Gnutella<cr><lf>
Host: 123.123.123.123:6346<cr><lf>
Connection: Keep-Alive<cr><lf>
Range: bytes=0-<cr><lf>
<cr><lf>
gdzie:
<File Index> - jest indeksem pliku
<File Name> - jest nazwą pliku
IP:port – IP i port serwera, z którym się łączy
Jak widać w powyższym przykładzie Gnutella wprowadziła wsparcie dla parametru Range protokołu HTTP, co pozwala na wznowienie pobierania pliku w momencie przerwania połączenia. Przykładowe inicjowanie pobierania pliku przedstawia rysunek 17.
Rysunek 17 Pobieranie pliku z wykorzystaniem protokołu HTTP
2.1.9.1. Pobieranie pliku zza zapory sieciowej
Jak wspomniano w rozdziale 2.1.8.1, może zdarzyć się sytuacja, w której serwent odpowiadający na komunikat Query jest za zaporą sieciową i nie może przyjmować połączeń przychodzących. W takim wypadku serwent chcący pobrać plik wysyła komunikat Push z informacją o swoim adresie IP i porcie, na którym przyjmie połączenie (rys. 18). Adresat komunikatu Push może zainicjować połączenie i w ten sposób pobieranie pliku może się odbyć. Inicjowanie połączenia odbywa się komunikatem:
GIV <File Index>:<Servent GUID>/<File Name>\n\n
Serwent obierający komunikat GIV odpowiada komunikatem:
GET /get/<File Index>/<File Name>/ HTTP/1.0\r\n
User-Agent: Gnutella/0.4\r\n
Range: bytes=0-\r\n
Connection: Keep-Alive\r\n
Dalszy przebieg komunikacji jest taki sam, jak w przypadku opisanym w rozdziale 2.1.9.
Rysunek 18 Ruting komunikatów Push.
Opisana powyżej sieć GNet i związany z nią protokół Gnutella jest podstawą wielu programów P2P dostępnych obecnie w świecie komputerowym. Do najpopularniejszych należą takie programy jak:
Morpheus - klient Gnutelli i innych sieci p2p
LimeWire (napisany w Javie, niezależny od platformy), na licencji GPL open-source
BearShare (Windows), program komercyjny
Shareaza (Windows), open-source na licencji GPL, klient Gnutelli i innych sieci P2P
Programy korzystające z sieci GNet ciągle się doskonalą, a ich twórcy wprowadzają nowe rozwiązania, wpływające nie tylko na coraz większą łatwość wyszukiwania plików, ale także na zmniejszenie ruchu w sieci i jej skalowalność. Warto zauważyć, że ogólna zasada działania sieci nie jest skomplikowana, a ilość komunikatów wyspecyfikowanych przez protokół niewielka. Brak też systemu logowania użytkownika do sieci opartego o system autentykacji i autoryzacji. Zauważyć można również zasadnicze zmiany podstawowych założeń systemu, które pierwotnie nie wyróżniały żadnego z węzłów sieci. Zmiana ta została podyktowana przez rzeczywiste warunki, w których każdy z węzłów dysponuje różnymi parametrami łącza, rodzajem adresu czy sprzętem, w jaki jest wyposażony.
Copyright © 2008-2010 EPrace oraz autorzy prac.