Programowanie sieciowe w Javie



Ettiotte Rusty Harold


Java. Programowanie sieciowe


Tytuł oryginału: Java Network Programming, Second Edition ! '

Tłumaczenie: Katarzyna Tryc (rozdz. 1-10), Grzegorz Werner (rozdz. 11-19)

Wydawnictwo RM, Warszawa 2001

Authorized translation of the English edition 2000 0'Reilly and Associates, Inc. This translation
is published and sold by permission of 0'Reilly and Associates, Inc., the owner of all rights
to publish and sell the same.

Wydawnictwo RM, 00-987 Warszawa 4, skr. poczt. 144
rm@rm.com.pl
www.rm.com.pl

Żadna część tej pracy nie może być powielana i rozpowszechniana, w jakiejkolwiek formie i w jakikolwiek sposób (elektro-
niczny, mechaniczny) włącznie z fotokopiowaniem, nagrywaniem na taśmy lub przy użyciu innych urządzeń, bez pisemnej
zgody wydawcy.

Wszystkie nazwy handlowe i towarów występujące w niniejszej publikacji są znakami towarowymi zastrzeżonymi lub na-
zwami zastrzeżonymi odpowiednich firm odnośnych właścicieli.
Nazwy i adresy firm, nazwiska i adresy osób, nazwy towarów i inne dane wykorzystane w przykładach są fikcyjne i jakakol
wiek zbieżność z rzeczywistością jest wyłącznie przypadkowa.

Wydawnictwo RM dołożyło wszelkich starań, aby zapewnić najwyższą jakość tej książce. Jednakże nikomu nie udziela
żadnej rękojmi ani gwarancji. Wydawnictwo RM nie jest w żadnym przypadku odpowiedzialne za jakąkolwiek szkodę (łącz-
nie ze szkodami z tytułu utraty zysków związanych z prowadzeniem przedsiębiorstwa, przerw w działalności przedsiębior-
stwa lub utraty informacji gospodarczej) będącą następstwem korzystania z informacji zawartych w niniejszej publikacji,
nawet jeśli Wydawnictwo RM zostało zawiadomione o możliwości wystąpienia szkód.

ISBN 83-7243-135-3
Redaktor prowadzący: Danuta Cyrul
Redakcja: Irmina Wala-Pegierska
Korekta: Krystyna Knap
Indeks: Katarzyna Tryc
Opracowanie graficzne okładki według oryginału: Grażyna Jedrzejec
Redaktor techniczny: Beata Donner-Soska
Skład: Artur Wólkę
Druk i oprawa: Oficyna Wydawnicza READ ME - Drukarnia w Lodzi
Wydanie l
10987654321
Mojej Babuni, wspanialej babci
Spis treści
Wstęp. ....................................................... XI
Uwagi do wydania drugiego .......................................... XII
Układ książki. .................................................. XIII
Kim jesteś? .................................................... XVI
Wersjejavy ................................................... XVII
Bezpieczeństwo ................................................. XIX
Uwagi na temat przykładów .......................................... XIX
Konwencje zastosowane w tej książce. ..................................... XX
Prośba o komentarze .............................................. XXII
Podziękowania. ........................................ ..... ....... XXIV
Rozdział 1: Dlaczego Java sieciowa?................................ 1
Co potrafi program sieciowy? ........................................... 2
Chwileczkę! Jeszcze coś! ............................ . .V -'.!Vi --j / . v". i(. .... 19
Rozdział 2: Podstawowe pojęcia dotyczące sieci. ........................ 21
Sieci......................................................... 21
Warstwy sieci ................................................... 23
Protokoły IP, TCP oraz UDP ........................................... 29
Internet ....................................................... 32
Model klient-serwcr. .............................. . . ............... 38
Internetowe standardy ............................. , ................ 40
.- ;'.".:.": ' -;r< v&jij
Rozdział 3: Podstawowe pojęcia dotyczące sieci WWW. .................... 51
URI ......................................................... 52
HTML,SGMLiXML ............................................... 58
HTTP ........................................................ 60
MIME. ....................................................... 65
CGI ......................................................... 70
Aplcty i bezpieczeństwo .............................. ;-..vVi'i. ...... 73
Rozdział 4: Wejście i wyjście w Javie ............................... 77
Strumienie wyjściowe............................................... 78
Strumienie wejściowe ............................................... 82
Strumienie filtrujące................................................ 86
KlasyReaderiWriter. .............................................. 102
Rozdział 5: Wątki ......................................... 117
Działające wątki ................................................. 119
Informacje zwracane przez wątki. ....................................... 123
Synchronizacja .................................................. 135
Zakleszczenie. .................................................. 141
Harmonogram wątków ............................................. 142
Pulawątków ................................................... 156
Rozdział 6: Wyszukiwanie adresów internetowych ....................... 163
DNS, adresy IP i cała reszta ........................................... 163
Klasa InetAddress ................................................ 165
Kilka przydatnych programów ......................................... 177
VIII
Spis treści
Rozdział?: Odnajdywanie danych za pomocą adresów URL. ................. 189
Klasa URL. .................................................... 189
Klasy URLEncoder i URLDecoder ....................................... 212
Komunikowanie się z programami CGI i serwletami metodą GET . ....................... 216
Dostęp do witryn zabezpieczonych hasłem .................................. 221
Rozdział 8: HTML w Swingu ................................... 229
HTML w komponentach. ............................................ 230
Klasa JEditorPane ................................................ 232
Parsowanie HTML-a . .............................................. 240
Rozdział 9: Metody sieciowe klasy java.applet.Applet ..................... 257
Wykorzystanie klasy jaya.applet.Applet do ładowania danych ........................ 257
Interfejs ImageObserver ............................................. 265
Klasa MediaTrackcr ............................................... 270
Sieciowe metody interfejsu java.appIct.ApplctContext. ...........,; ...... ."'. ,,.,.. 285
Rozdział 10: Gniazda klientów .................................. 289
Podstawy gniazd................................................. 290
Podglądanie protokołów za pomocą Telnetu ................................. 290
KlasaSocket. ................................................... 292
Wyjątki klasy SocketException ......................................... 314
Przykłady ..................................................... 315
Rozdział 11: Gniazda serwerów ................................. 333
Klasa ScrverSocket................................................ 334
Kilka przydatnych serwerów .......... . , , .... .......................... 346
Rozdział 12: Bezpieczne gniazda. ................................ 367
Bezpieczna komunikacja. ............................................ 368
Tworzenie bezpiecznych gniazd klienta .................................... 371
Metody klasy SSLSocket. ............................................ 375
Tworzenie bezpiecznych gniazd serwera ................................... 381
Metody klasy SSLSeryerSocket ......................................... 385
Rozdział 13: Gniazda i datagramy UDP ............................. 389
Protokół UDP .................................................. 389
Klasa DatagramPacket. ............................................. 391
Klasa DatagramSocket. ............................................. 400
Kilka przydatnych aplikaq'i ........................................... 411
Rozdział 14: Gniazda multicast. ............................... . . 425
Co to jest gniazdo multicast? .......................................... 426
Praca z gniazdami multicast. .......................................... 436
Dwa proste przykłady .............................................. 440
Rozdział 15: Klasa URLConnection ............................... 445
Otwieranie połączeń URLConnection ..................................... 446
Czytanie danych z serwera ........................................... 448
Czytanie nagłówka ............................................... 449
Konfigurowanie połączenia .......................................... 457
Konfigurowanie nagłówka MIME w żądaniu klienta ........................... 465
Wysyłanie danych do serwera ......................................... 467
Spis treści
IX
Programy obsługi treści. ............................................ 472
Metody obiektowe. ............................................... 474
Uwagi o bezpieczeństwie obiektów URLConnection. ........................... 474
Odgadywanie typów MIME. .......................................... 475
HttpURLConnection. .............................................. 478
JarURLConnection................................................ 492
Rozdział 16: Programy obsługi protokołu ............................ 495
Co to jest program obslugi protokołu? ..................................... 496
Klasa URLStreamHandler. ........................................... 499
Pisanie programu obslugi protokołu ...................................... 506
Inne przykłady programów obsługi protokołu ................................ 511
Interfejs URLStreamHandlerFactory . ..................................... 519
Rozdział 17: Programy obsługi treści .............................. 523
Co to jest program obsługi treści? ........................................ 525
Klasa ContentHandler .............................................. 528
Interfejs ContentHandlerFactory ........................................ 539
Program obsługi treści dla formatu graficznego image/x-fits ........................ 542
Rozdział 18: Zdalne wywoływanie metod (RMI). ........................ 555
Co to jest zdalne wywoływanie metod? .................................... 555
Implementacja .................................................. 561
Lądowanie klas w czasie wykonania ...................................... 569
Pakiet java.rmi ................................................. 576
Pakiet java.rmi.registry ............................................. 584
Pakiet java.rmi.server .............................................. 586
Rozdział 19: JavaMail API. .................................... 591
CotojestJavaMailAPI? ............................................. 592
Wysyłanie poczty. ................................................ 594
Odbieranie poczty ................................................ 604
Uwierzytelnianie za pomocą haseł ....................................... 609
Adresy. ...................................................... 613
Klasa URLName ................................................. 617
Klasa Message .................................................. 619
Interfejs Part. ................................................... 630
Wiadomości wieloczęściowe i załączniki plikowe .............................. 640
Wiadomości MIME. ............................................... 644
Foldery ...................................................... 646
Indeks. ............................................... 659


Wstęp

Rozwój Javy w ciągu ostatnich pięciu lat jest zjawiskiem niezwykłym. Trochę za-
dziwia fakt, że Java w krótkim czasie spowodowała wzrost znaczenia sieci i po-
wszechne zainteresowanie nimi, skoro programowanie sieciowe w Javie dla wielu
osób jest nadal czymś bardzo tajemniczym. Ale tak nie musi być. W rzeczywistości
pisanie programów sieciowych w Javie jest dość proste, co ilustruje ta książka. Czy-
telnicy o pewnym doświadczeniu w programowaniu sieciowym w Uniksie, syste-
mie Windows bądź środowisku Macintosha będą mile zaskoczeni tym, o ile łatwiej-
sze w Javie jest napisanie równorzędnych programów. Dzieje się tak dlatego, że klu-
czowe API Javy zawiera dobrze zaprojektowane interfejsy do większości funkcji sie-
ciowych. Tak naprawdę istnieje niewiele oprogramowania sieciowego warstwy
aplikacji, które łatwiej byłoby napisać w języku C lub C++ niż w Javie. fava. Progra-
mowanie sieciowe przedstawia sposoby wykorzystywania możliwości biblioteki klas
sieciowych Javy do szybkiego i łatwego pisania programów, wykonujących wiele
typowych zadań sieciowych. Takimi zadaniami są:
Przeglądanie stron WWW. ' /'' ' ;.
Parsowanie irenderowanie HTML-a. '..,.,'"'''
Wysyłanie poczty elektronicznej za pomocą protokołu SMTP.
Odbieranie poczty elektronicznej za pomocą protokołu POP i IMAP.
Pisanie serwerów wielowątkowych.
Instalowanie w przeglądarce nowego protokołu i programu obsługi treści. '
Kodowanie komunikatów w celu zagwarantowania poufności, autentyczności
i bezpieczeństwa.
Projektowanie klientów graficznego interfejsu użytkownika (GUI) dla usług sie-
ciowych. ,
Przesyłanie danych programom CGI. ^ ,, : ;: J> ,; - r ? ?s.
Wyszukiwanie węzłów sieci za pomocą DNS-u. ; " W1; : ;i .
Ściąganie plików za pomocą anonimowego FTP.
'"ł1*
Łączenie gniazd w komunikacji sieciowej niskiego poziomu.
Rozprowadzanie aplikaq'i wśród wielu systemów za pomocą zdalnego wywo-
ływania metod (RMI).
Java jest pierwszym językiem zapewniającym tak potężną międzyplatformową bi-
bliotekę sieciową, która jest w stanie obsługiwać wszystkie te, tak różnorodne, zada-
nia. Java. Programowanie sieciowe podkreśla możliwości i wyrafinowanie tej bibliote-
ki. Ta książka ma zachęcić cię do poważnego wykorzystywania Javy w roli platfor-
my programowania sieciowego. Dlatego przedstawia ogólne tło podstaw progra-
mowania sieciowego, jak również szczegółowy opis zawartych w Javie ułatwień do
pisania programów sieciowych. Nauczysz się z niej pisania apletów i aplikacji Javy,
które w Internecie dzielą się danymi potrzebnymi w grach, przy współpracy, do
uaktualniania oprogramowania, przesyłania plików i innych zastosowań. Poznasz
także od podszewki protokoły HTTP, CGI, TCP/IP oraz inne, na których opiera się
Internet i sieć WWW. Po przeczytaniu tej książki będziesz posiadał wiedzę i narzę-
dzia potrzebne do tworzenia oprogramowania nowej generacji, w pełni wykorzy-
stującego możliwości oferowane przez Internet. ..-, ;.-
Uwagi do wydania drugiego*
W rozdziale otwierającym pierwsze* wydanie tej książki napisałem sporo o dyna-
micznych, rozproszonych aplikacjach sieciowych, których zaistnienie, jak myślałem,
będzie możliwe dzięki Javie. Jednym z najbardziej ekscytujących aspektów pisania
wydania drugiego była możliwość naocznego przekonania się, że pojawiły się prak-
tycznie wszystkie prognozowane przeze mnie rodzaje aplikacji. Programiści uży-
wają Javy do wysyłania zapytań serwerom baz danych, nadzorowania stron WWW,
sterowania teleskopami, zarządzania grami przeznaczonymi dla wielu użytkowni-
ków i do innych zastosowań, a wszystko to dzięki wykorzystaniu zdolności Javy do
uzyskiwania dostępu do Internetu. Należy zaznaczyć, że Java wyszła znacznie poza
stadium eksperymentalne, w szczególności programowanie sieciowe w Javic wesz-
ło w dziedzinę aplikacji wykonujących prawdziwe zadania. Na razie jeszcze nie całe
oprogramowanie sieciowe zostało napisane'w Javie, lecz bynajmniej nie z powodu
braku takich prób. Trwają starania, aby istniejącą infrastrukturę klientów i serwe-
rów sieci napisaną w języku C zastąpić odpowiednikiem w samej Javie. Jest mało
prawdopodobne, że w najbliższej przyszłości Java zastąpi język C w całym progra-
mowaniu sieciowym. Jednak sam fakt, że wiele osób chętnie używa przeglądarek
sieciowych, serwerów sieciowych i innych programów napisanych w Javie, dowo-
dzi, jak wiele osiągnęliśmy od 1996 roku.
Ta książka również ma za sobą długą drogę. Wydanie drugie zostało praktycznie
napisane od podstaw. Zawiera pięć zupełnie nowych rozdziałów. Niektóre z nich
odzwierciedlają API i możliwości Javy, które pojawiły się od czasu opublikowania
wydania pierwszego (rozdział 8. "HTML w Swingu", rozdział 12. "Bezpieczne
gniazda" oraz rozdział 19. "JavaMail API"), a w pozostałych rozdziałach skorzy-
* Wydanie amerykańskie [przyp. red.].
stałem z mojego doświadczenia wykładowcy i szczególną uwagę zwróciłem na te
zagadnienia, które sprawiają studentom problem (rozdział 4. "Wejście i wyjście w
Javie" i rozdział 5. "Wątki"). Poza tym rozdział o API serwletów Javy został usunię-
ty, ponieważ ten temat zasługuje na własną książkę; taka została zresztą już napisa-
na: Jason Hunter Java Servlet Programming (O'Reilly&Associates, Inc., 1998).
Jednakże ważniejsze od usuniętych lub dodanych rozdziałów są zmiany dokonane
w tych rozdziałach, które pozostały. Najbardziej oczywistą zmianą względem wy-
dania pierwszego było przepisanie wszystkich przykładów dla API wejścia i wyjścia
w Javie 1.1. Komunikaty, które zadręczały czytelników podczas kompilowania
przykładów z pierwszego wydania w Javie 1.1 lub późniejszych, należą już do
przeszłości. Mniej oczywiste, lecz znacznie istotniejsze jest to, że zostały napisane od
nowa w celu zastosowania w nich jasnego, obiektowego modelu, zgodnego z kon-
wencjami nazewniczymi Javy i zasadami projektowania. Tak jak prawie wszyscy
(Sun nie jest wyjątkiem), podczas pisania pierwszego wydania w 1996 roku usi-
łowałem wyobrazić sobie mnóstwo szczegółów dotyczących tego, co i jak można ro-
bić w Javie. Stare przykłady miały poprawny kod sieciowy, ale teraz pod wieloma
względami wydawały mi się zawstydzająco amatorskie. Od tamtej pory sporo na-
uczyłem się na temat programowania w Javie i programowania obiektowego, więc
mam nadzieję, że w tym wydaniu nabyte doświadczenie będzie widoczne. Jako
przykład niech posłuży informacja, że nie używam już samodzielnych aplctów tam,
gdzie wystarczy zwykła aplikacja, oparta na systemie ramek. Mam nadzieję, że
nowe przykłady posłużą nie tylko jako wzorce pisania programów sieciowych, ale
wszelkiego kodu w Javie.
Oczywiście również tekst został wyszlifowany. Napisanie tego drugiego, poprawio-
nego tekstu zajęło mi w zasadzie tyle samo czasu, ile oryginału. Jak już wspo-
mniałem, jest pięć całkiem nowych rozdziałów, a czternaście poprawionych roz-
działów zostało w znacznym stopniu napisanych ponownie i poszerzonych, żeby
były na tyle aktualne co nowe opracowania, a także by stały się przejrzystsze i bar-
dziej zajmujące. Ta wersja książki, powiedzmy sobie szczerze, została napisana
znacznie lepiej niż pierwsze wydanie, nawet jeśli pominiemy wszystkie zmiany do-
konane w przykładach. Mam nadzieję, że to wydanie zostanie uznane za lepszy,
trwalszy, przydatniejszy i ciekawszy informator i podręcznik programowania sie-
ciowego w Javie niż wydanie sprzed czterech lat. v . ;
Układ książki
Książka zaczyna się trzema rozdziałami opisującymi działanie sieci i programów
sieciowych. Rozdział 1. "Dlaczego Java sieciowa?" łagodnie wprowadzi cię w pro-
gramowanie sieciowe w Javie i w aplikacje, które istnieją dzięki niej. Każdy powi-
nien tu znaleźć coś dla siebie. Opisałem tu kilka z wielu unikatowych programów,
które mogły się pojawić dopiero po zastosowaniu Javy w sieci. Rozdział 2. "Podsta-
wowe pojęcia dotyczące sieci" oraz rozdział 3. "Podstawowe pojęcia dotyczące sieci
WWW" szczegółowo wyjaśniają, czego potrzebuje programista, aby zrozumieć
działanie Internetu i sieci WWW. Rozdział 2. opisuje protokoły leżące u podstaw In-
ternetu, takie jak TCP/IP oraz UDP/IP. Rozdział 3. omawia standardy, na których
opiera się sieć WWW, takie jak HTTP, HTML oraz CGI. Jeśli napisałeś dużo prog-
ramów sieciowych w innych językach dla innych platform, możesz sobie pozwolić
na opuszczenie tych dwóch rozdziałów.
Kolejne dwa rozdziały rzucają nieco światła na dwa aspekty Javy, które mają zasad-
nicze znaczenie dla prawie wszystkich programów sieciowych, a zazwyczaj są źle
rozumiane i nieprawidłowo używane: wejście/wyjście oraz wątki. Rozdział 4. doty-
czy wyjątkowego sposobu obsługiwania w Javie wejścia i wyjścia. Zrozumienie ge-
neralnych zasad tego mechanizmu jest warunkiem wstępnym zrozumienia przy-
padku szczególnego, jakim jest w Javie obsługa sieciowego wejścia i wyjścia. Roz-
dział 5. opisuje wielowątkowość i synchronizację, ze szczególnym podkreśleniem
ich zastosowania w przypadku asynchronicznego wejścia i wyjścia oraz serwerów
sieciowych. Biegli programiści Javy mogą pobieżnie przeczytać te dwa rozdziały lub
w ogóle je pominąć. Natomiast rozdział 6. "Wyszukiwanie adresów internetowych"
ma kluczowe znaczenie dla każdego. Pokazuje on, w jaki sposób programy w Javie
oddziałują z DNS-em poprzez klasę InetAddress, jedyną klasę niezbędną prak-
tycznie we wszystkich programach sieciowych. Po przeczytaniu tego rozdziału bę-
dziesz mógł skakać po całej książce według własnych zainteresowań i potrzeb. Jed-
nakże między niektórymi rozdziałami istnieją pewne powiązania. Rysunek 1. po-
może ci wyznaczyć dopuszczalne ścieżki poruszania się po książce.
Rozdział 7. "Odnajdywanie danych za pomocą adresów URL" omawia klasę URL,
potężne narzędzie do ściągania informacji i plików z wielu rodzajów serwerów sie-
ciowych. Klasa URL umożliwia podłączenie się do serwerów sieciowych i ściągnięcie
z nich plików i dokumentów bez kłopotania cię niuansami protokołów, którymi
posługują się serwery. Dzięki tej klasie możesz połączyć się z serwerem FTP, uży-
wając tego samu kodu, za pomocą którego porozumiewałeś się z serwerem HTTP
lub odczytywałeś plik z lokalnego dysku twardego.
Gdy pobierasz z serwera jakiś plik HTML, zapewne masz zamiar coś z nim zrobić.
Parsowanie i renderowanie HTML-a jest jednym z najtrudniejszych wyzwań sto-
jących przed programistą sieciowym. Na przykład projekt Mozilla borykał się właś-
nie z tym zadaniem przez ponad dwa lata. Rozdział 8. "HTML w Swingu" wprowa-
dza niektóre mało znane klasy do parsowania i renderowania dokumentów HTML,
które zdejmują ten ciężar z twoich barków i przerzucają go na Suną.
W rozdziale 9. "Metody sieciowe klasy java.applet.Applet" zajmiemy się prześle-
dzeniem metod sieciowych jednej z pierwszych klas, którą poznają programiści
Javy, klasy Applet. Nauczysz się ściągania z serwerów sieciowych plików z obraz-
kami i plików dźwiękowych oraz śledzenia postępu ładowania. Jeśli nie używa się
nieudokumentowanych klas, jest to jedyna metoda obsługi dźwięku w Javie 1.2
i starszych wersjach.
Rozdziały od 10. do 14. opisują klasy Javy gniazd niskiego poziomu związanych
z dostępem sieciowym. W rozdziale 10. "Gniazda klientów" zostały wprowadzone
API gniazd Javy, a w szczególności klasa Socket. Rozdział ten przedstawia, jak na-
pisać klienty sieci oddziałujące z serwerami TCP wszelkiego rodzaju, w tym whois,
finger i HTTP. Rozdział 11. "Gniazda serwerów" ilustruje, jak wykorzystać klasę
ServerSocket dopisał
Rozdział 12. pokazuje, ja
cure Socket Layer - warsh
Extension - rozszerzenie J
da i datagramy UDP" dc
kół datagramów użytko
DatagramSocket prze2
cię rozdział 14. "Gniazda
UDP do komunikowania
[
E
E
E
E
Rozdział 7 Rozdział 9
.Odnajdywanie "Metody sieciowe
danych klasy
za pomocą java.apple!.Applei"
adresów URL" " """"' T
Rozdział 15 Rozdział B
Klasa "HIML w Swingu"
l IHl ('.onnHdion"
Rysunek 1. Powiązania rozdziało!
Układ książki
XV
ServerSocket do pisania w Javie serwerów dla powyższych i innych protokołów.
Rozdział 12. pokazuje, jak chronić komunikację klient-serwer, stosując SSL (ang. Se-
cure Socket Layer - warstwa bezpiecznych gniazd) oraz JSSE (ang. Java Secure Socket
Extension - rozszerzenie Javy do obsługi bezpiecznych gniazd). Rozdział 13. "Gniaz-
da i datagramy UDP" dotyczy protokołu UDP (ang. User Datagram Protocol - proto-
kół datagramów użytkownika) oraz związanych z nim klas DatagramPacket i
DatagramSocket przeznaczonych do szybkiej i niezawodnej komunikacji. Wresz-
cie rozdział 14. "Gniazda multicast" przedstawia, w jaki sposób można wykorzystać
UDP do komunikowania się jednocześnie z wieloma węzłami sieci.
Rysunek 1. Powiązania rozdziałów
XVI
Wstęp
Wszystkie pozostałe klasy, które z Javy uzyskują dostęp do sieci, opierają się na kla-
sach opisanych w tych pięciu rozdziałach.
Rozdziały od 15. do 17. dogłębniej opisują infrastrukturę wspomagającą klasę URL.
W tych rozdziałach zostały wprowadzone programy obsługi protokołu i obsługi tre-
ści oraz charakterystyczne tylko dla Javy pojęcia umożliwiające pisanie dynamicz-
nie rozszerzalnego oprogramowania, które automatycznie rozpoznaje nowe proto-
koły i rodzaje nośników. Rozdział 15. "Klasa URLConnection" opisuje klasę URL-
Connection, która spełnia rolę napędową dla klasy URL z rozdziału 7. Przedstawia
on, jak można wykorzystać zalety tej klasy poprzez jej publiczne API. Rozdział 16.
"Programy obsługi protokołu" także omawia klasę URLConnection, ale z innego
punktu widzenia. Wyjaśnia, jak zrobić z niej podklasę, aby utworzyć programy
obsługi nowych protokołów i adresów URL. Z kolei rozdział 17. "Programy obsługi
treści" dotyczy pewnego odchodzącego w zapomnienie mechanizmu Javy przezna-
czonego do obsługi nowych rodzajów nośników.
W rozdziałach 18. i 19. zostały wprowadzone dwa unikatowe API wyższego pozio-
mu dla programów sieciowych: RMI oraz JavaMail API. Rozdział 18. "Zdalne
wywoływanie metod (RMI)" przedstawia ten potężny mechanizm służący do pisa-
nia rozproszonych aplikacji Javy, które jednocześnie mogą działać na wielu róż-
norodnych systemach, komunikując się poprzez prostą metodę wywołań, czyli w
sposób właściwy programom nicrozproszonym. Rozdział 19. zapoznaje nas ze stan-
dardowymi rozszerzeniami Javy, które stanowią alternatywne rozwiązanie dla
gniazd niskopoziomowych przy komunikacji z SMTP, POP, IMAP oraz innymi ser-
werami pocztowymi. Oba te API dostarczają aplikacji rozproszonych, stanowiących
wygodniejszy odpowiednik protokołów niższego poziomu.
Kim jesteś?
Zakładam, że czytelnik tej książki zna podstawy języka Ja va i środowiska programi-
stycznego oraz ogólne zasady programowania obiektowego. W moim zamyśle ta
książka nie ma być szczegółowym podręcznikiem Javy. Powinieneś już dokładnie
znać składnię tego języka oraz umieć pisać proste aplikacje i aplety. Dobrze byłoby,
gdybyś czuł się pewnie w AWT. Gdy natrafisz na zagadnienie, które wymaga głęb-
szej znajomości programowania sieciowego - na przykład wątki i strumienie - wte-
dy oczywiście zostanie ono wyjaśnione, przynajmniej pokrótce, i
Powinieneś także być biegłym użytkownikiem Internetu. Zakładam, iż potrafisz od-
wiedzać witryny WWW oraz przesyłać pliki przez f t p. Powinieneś wiedzieć, czym
jest URL i jak go zlokalizować. Spodziewam się, że umiesz napisać prosty dokument
HTML i jesteś w stanie opublikować stronę tytułową zawierającą aplety Javy, a więc
musisz być doskonałym projektantem stron WWW.
Natomiast nie oczekuję, że masz już jakieś doświadczenie w programowaniu siecio-
wym. Ta książka ma stanowić kompletny podręcznik zagadnień sieciowych i pro-
jektowania aplikacji sieciowych. Nie spodziewam się, że w małym palcu masz kilka
tysięcy skrótów dotyczących sieci (TCP, UDP, SMTP... ). Znajdziesz tu wszystkie,
które będą ci potrzebne. W zasadzie możliwe jest, abyś potraktował tę książkę jako
Wersje Javy
XVII
ogólne wprowadzenie do programowania sieciowego z pewnego rodzaju interfej-
sem gniazdowym, a następnie zajął się nauką WSA (ang. Windows Socket Architecture
- architektura gniazd dla systemu Windows) i wyobraził sobie, jak pisać aplikacje
sieciowe w języku C++. Ale nie wiem, dlaczego miałbyś to robić - przecież dzięki
Javie pisanie bardzo skomplikowanych aplikacji staje się łatwe.
Wersje Javy ^
Od wersji l .0 Javy jej klasy sieciowe zmieniają się znacznie wolniej niż inne części
kluczowego API. Można byłoby powiedzieć, że w porównaniu z AWT lub klasami
wejścia i wyjścia prawie się nie zmieniły i wzbogaciły się tylko o kilka dodatków.
Oczywiście wszystkie programy sieciowe w szerokim zakresie korzystają z klas wej-
ścia i wyjścia oraz intensywnie używają interfejsów graficznych użytkownika (GUI).
Pisząc tę książkę, przyjąłem założenie, że ty i twoi klienci stosujecie co najmniej Javę
1.1 (stanie się ono całkiem uzasadnione w roku 2001). Zwykle używam Javy 1.1
z funkcjami takimi jak reader i writer oraz nowego modelu obsługi zdarzeń bez dal-
szych wyjaśnień.
Java 2 idzie nieco dalej. Prawie całą tę książkę napisałem w Javie 2, gdyż w syste-
mach Windows i Solaris jest ona dostępna już od ponad roku; nie ma jeszcze jednak
środowiska programistycznego ani wykonawczego dla Macintoshy. Chociaż Java 2
stopniowo wkracza na większość platform uniksowych, w tym na Linuksa, jest pra-
wie pewne, że ani Apple, ani Sun nie będą przenosić żadnej z wersji Javy 2 na system
MacOS 9.x ani wcześniejsze, co praktycznie dla 100% obecnie zainstalowanych Ma-
cintoshy oznacza brak możliwości dalszego rozwoju. (Prawdopodobnie pojawi się
Java 2 dla systemu MacOS X w 2001 roku.). Dla języka nie jest wcale dobre to, że wy-
maga "pisania raz, uruchamiania gdziekolwiek". Co więcej wirtualna maszyna Javy
firmy Microsoft obsługuje tylko Javę 1.1 i nie zanosi się na to, aby pod tym względem
coś uległo poprawie w najbliższej przyszłości (być może nic dopuszczą do tego roz-
strzygnięcia różnych sporów prawnych). Poza tym prawie wszystkie zainstalowane
obecnie przeglądarki, w tym Internet Explorer 5.5 i jej wcześniejsze wersje oraz
Netscape Navigator 4.7 i jej wcześniejsze wersje, obsługują tylko Javę 1.1. Także au-
torzy apletów w zasadzie są ograniczeni do Javy 1.1 z powodu możliwości swoich
klientów. Dlatego wygląda na to, że przynajmniej w najbliższym czasie Java 2 ogra-
niczy się do pojedynczych aplikacji w systemach Windows i Unix. Nic rezygno-
wałem z korzystania z funkcji typowych dla Javy 2 tam, gd/,ie było to naprawdę
przydatne lub właściwe - na przykład przy kodowaniu ASCII dla inputStre-
amReader oraz w programie keytool- ale wyraźnie to zaznaczyłem. Odnotowałem
przypadki, w których istnieją dla tych funkcji bezpieczne odpowiedniki w Javie l .1.
Jeśli jakaś metoda lub klasa pojawiła się dopiero od Javy l .2 lub jej nowszych wersji,
zostało to zaznaczone za pomocą komentarza umieszczonego po jej deklaracji. Oto
przykład:
public void setTimeToLive (int ttl) throws IOException // Java 1.2
Aby jeszcze bardziej zamącić, powiem, iż istnieje wiele wersji Javy 2. W chwili, w której
została ukończona ta książka, obowiązywała Java 2 SDK, Standard lidition,
XVIII
Wstęp
J i - -
i"T
vi.2.2. Przynajmniej tak była nazywana. Zdaje się, że Sun zmienia nazwy pod
wpływem rad konsultantów od marketingu. W poprzednim wcieleniu była ona zna-
na po prostu jako JDK. Sun udostępnił także J2EE (ang. ]ava 2 Platform, Enterprise
Edition) oraz J2ME (ang. }ava 2 Platform, Micro Edition). J2EE jest zestawem funk-
cji edycji standardowej poszerzonym o funkcje, takie jak interfejs nazw i katalogów
Javy (ang. ]ava Naming and Directory Interface) oraz JavaMail API, które zapewnia
API wysokopoziomowe dla aplikacji rozproszonych. Niektóre z tych dodatkowych
API są także dostępne w postaci rozszerzeń do edycji standardowej Javy i w taki
sposób będą tu traktowane. J2ME jest podzestawem edycji standardowej ukierunko-
wanym na telefony komórkowe, dekodery satelitarne i inne pamięci, procesory oraz
urządzenia do prezentacji grafiki. Usunięto z niej API graficznego interfejsu użyt-
kownika, które programiści tradycyjnie wiązali z Javą, a nieoczekiwanie pozo-
stawiono prawie wszystkie podstawowe klasy sieciowe oraz klasy wejścia i wyjścia,
które zostały omówione w tej książce. Poza tym, kiedy książka była napisana w
połowie, Sun wypuścił wersję beta Javy 2 SDK, Standard Edition, vi .3. Ma ona kil-
ka dodanych elementów sieciowego API, a większość istniejącego API została nie-
tknięta. W ciągu następnych kilku miesięcy Sun opublikował kolejne wersje beta
JDK 1.3. Ostateczne poprawki zostały uwzględnione w tej książce, a cały kod został
przetestowany z końcową wersją JDK 1.3.
Prawdę mówiąc, problem z tymi wszystkimi wersjami i edycjami nie polegał na pi-
saniu od nowa fragmentów, które o nich traktowały. Najtrudniej było określić, jak
należy je identyfikować w tekście. Po prostu nie zgadzam się na pisanie Java 2
SDK, Standard Edition, vi .3 ani nawet Java 2 1.3 za każdym razem, gdy chcę zazna-
czyć nową funkcję z ostatniego wydania Javy. Dlatego więc przyjąłem następującą
konwencję:
Java l .0 oznacza wszystkie wersje Javy, które mniej więcej mają zaimplementowa-
nc API Javy, zdefiniowane w Java Dcvelopment Kit 1.0.2 firmy Sun.
java 1.1 oznacza wszystkie wersje Javy, które mniej więcej mają znimplemcnto-
wane API Javy, zdefiniowane w dowolnej wersji Java Development Kit l .1 .x firmy
Sun. Ta definicja obejmuje produkty innych firm, takie jak MJR (ang. Macintosli
Runtime for Java) 2.0, 2.1 oraz 2.2.
Java l .2 oznacza wszystkie wersje Javy, które mniej więcej mają zaimplemento-
wane API Javy, zdefiniowane w edycji standardowej Java Development Kit l .2.x
firmy Sun. Nic zaliczają się tu uzupełnienia J2EE, które będą traktowane jako roz-
szerzenia standardu. Zazwyczaj należą one do pakietu j,wax, a nie pakietów
java.
Java 1.3 oznacza wszystkie wersje Javy, które mniej więcej mają zaimplemento-
wane API Javy, zdefiniowane w edycji standardowej Java Development Kit l .3 fir-
my Sun.
Krótko mówiąc, ta książka opisuje istniejący stan rzeczy dla programowania siecio-
wego w Javic 2, które tak naprawdę niezbyt różni się od programowania sieciowego
w Javic 1.1. Uaktualnienia i poprawki zamieszczę w mojej witrynie pod adresem
Uwagi na temat przykładów
XIX
http://metalab.unc.edu/javafaci/books/jnp2e/, gdy zostaną udostępnione dalsze informa-
cje. Jednakże sieciowe API wydają się dość niezmienne. ;
Bezpieczeństwo " 4 ;
Nie wiem, czy można wskazać najczęściej zadawane pytanie na temat pierwszego
wydania książki Java, Programowanie sieciowe, ale na pewno istniała najczęściej udzie-
lana odpowiedź, która odnosi się również do tej edycji. Mój błąd w pierwszym wy-
daniu polegał na ukryciu tej odpowiedzi w końcowej części rozdziału, którego więk-
szość nie czytała. A ponieważ w zasadzie to samo stwierdzenie powinno stanowić
odpowiedź na podobną liczbę pytań od czytelników tej książki, to chcę ją podać na
samym początku (a potem wielokrotnie powtarzać w całej książce ze względu na
czytelników, którzy zazwyczaj pomijają wstępy): Zabezpieczenia ]avy nie dopuszczają,
aby prawie wszystkie przykłady i metody omawiane w tej książce działały w aplecie.
Ta książka dotyczy przede wszystkim aplikacji. Niepewnym apletom Javy wolno
komunikować się poprzez Internet tylko z tym węzłem sieci, z którego pochodzą.
Dotyczy to również węzła, na którym działają. Problem nie zawsze jest oczywisty -
nie wszystkie przeglądarki sieciowe prawidłowo informują o wyjątkach w systemie
zabezpieczeń - a mimo to istnieje. W Javie l .2 i jej późniejszych wersjach istnieją spo-
soby poluzowania ograniczeń dla apletów, tak że uzyskują one nieco swobodniejszy
dostęp do sieci. Jednak są to wyjątki, a nie reguła. Jeśli uruchamiając samodzielną
aplikację, spowodujesz uruchomienie apletu i nie będziesz mógł nakłonić aplikacji
do pracy wewnątrz przeglądarki WWW, to prawie pewne jest, że problem polega na
konflikcie z menedżerem zabezpieczeń przeglądarki.
Uwagi na temat przykładów
Większość metod i klas opisanych w tej książce została zilustrowana co najmniej jed-
nym kompletnym i działającym programem, choćby nawet prostym. Z mojego do-
świadczenia wynika, że kompletny, działający program jest niezbędny do zaprezen-
towania właściwego wykorzystania metody. Bez takiego programu zbyt łatwo popa-
da się w żargon lub samemu dopowiada się tam, gdzie sam autor nie do końca zrozu-
miał zagadnienie. Często nawet w dokumentacji API Javy opisy wywołań metod są
zbyt lakoniczne. W tej książce wolałem zgrzeszyć nadmiarem wyjaśnień ni/, ich nie-
dostatkiem. Jeśli jakaś kwestia jest dla ciebie oczywista, po prostu ją pomiń. Nie mu-
sisz wpisywać i uruchamiać każdego przykładu z tej książki, ale jeśli któraś metoda
sprawia ci kłopoty, to wiedz, że znajdziesz tu przynajmniej jeden działający przykład.
Każdy rozdział zawiera co najmniej jeden bardziej złożony program (a często kilka ta-
kich programów), który ilustruje stosowanie klas i metod z tego rozdziału przy bar-
dziej realistycznych ustawieniach. Często opiera się to na funkcjach Javy, które nie zo-
stały opisane w tej książce. Co prawda w wielu programach składniki sieciowe są je-
dynie niewielką częścią kodu źródłowego i to najłatwiejszą, niemniej jednak żaden z
tych programów nie mógłby zostać napisany równie łatwo w językach, które pracy w
sieci nic zapewniają tej centralnej pozycji, jaką daje jej Java. Dająca się zauważyć pro-
XX
Wstęp
J
f[.-- L...\
stota sekcji sieciowych kodu odzwierciedla kluczową pozycję pracy w sieci wśród
funkq'i Javy, natomiast nie stanowi o jakiejkolwiek trywialności samego programu.
Wszystkie zaprezentowane tu przykładowe programy są dostępne w postaci elektro-
nicznej, często też z poprawkami i rozszerzeniami. Możesz ściągnąć kod źródłowy
z http://metalab.unc.edu/javafaq/books/jnp2e oraz http://www.oreUly.com/catalog/javanp2/.
W tej książce założyłem, że posługujesz się JDK firmy Sun. Wszystkie przykłady
przetestowałem w systemie Windows, a znaczną część także w systemie Solaris i na
Macintoshach. Prawie wszystkie podane tu przykłady powinny działać na innych
platformach oraz z innymi kompilatorami i wirtualnymi maszynami obsługującymi
Javę 1.2 (a wiele w Javie 1.1). Nieliczne przykłady, które wymagają Javy 1.3, zostały
wyraźnie oznaczone. W rzeczywistości każda implementacja Javy, którą testo-
wałem, miała niebagatelne błędy w części dotyczącej sieci, więc nie jest możliwe za-
gwarantowanie pełnej wydajności. Starałem się zaznaczyć wszystkie te miejsca,
w których metoda zachowuje się inaczej niż przewidywała to firma Sun.
Konwencje zastosowane w tej książce
Tekst książki został napisany normalną czcionką Times Roman. v
Czcionką Courier zostały napisane: ' 'i v
przykładowy kod (także jeśli prezentowane są jego fragmenty);
słowa kluczowe, operatory, typy danych, nazwy zmiennych, nazwy klas i nazwy
interfejsów, które mogą pojawić się w programie Javy; ,?,,,; - :
wyjście programu; ,; 'r ;
znaczniki, które mogą pojawić się w dokumencie HTML.
Pogrubioną czcionką Courier zostały napisane: '''r".?.'. , V
wiersze poleceń i opcje, które należy wpisać dosłownie.
Pochyloną czcionką Courier zostały napisane: ;
fragmenty kodu, które mogą zostać zastąpione lub zmienione. ' ' '
Pochyloną czcionką Times Roman zostały napisane:
nowe terminy w miejscu, w którym są one definiowane;
nazwy ścieżek, nazwy plików i nazwy programów (jeśli jednak nazwa programu
jest również nazwą klasy w ]avic, to została napisana tą samą czcionką co po/,o-
stałc nazwy klas);
nazwy węzłów sieci i domen (java.orcilly.com); < i..
adresy URL (http://metalab.unc.edu/javafaq/); " ; y ;, , ..
tytuły innych książek (Java Serulet Programming).
Ważne fragmenty kodu i całe programy na ogół zostały umieszczone w oddzielnym
akapicie, jak poniżej: t ;.. .-,-, ,;,r- . : .>(
Socket s- new Socket ("java. oreilly. com", 80); -; . ...-
ii: ( ! s.getTcpNoDelay () ) s . setTcpNoDo l ay (t t m*) ; ,. . ,
Konwencje zastosowane w tej książce
XXI
Jeśli kod został przedstawiony w postaci fragmentów, a nie w całości, to istnienia od-
powiednich instrukcji import należy się domyślić. Na przykład w poprzednim
fragmencie kodu możesz założyć, że j ava. net. Socket zostało zaimportowane.
W niektórych przykładach wejście wprowadzane przez użytkownika przeplata się
z wyjściem programu. Wtedy wejście użytkownika wyróżnione jest pogrubieniem,
jak w tym przykładzie pochodzącym z rozdziału 10.:
% telnet localhost 7 , , . ,,
Trying 127.0.0.1. .. ' " ": ''-"':: ^ ';*'-"f-;".#Connected to localhost. ..' "" /
Escape character is IA] '. -...
To jest test. . ' . * ; *, .
To jest test. ' "i-. '...'' ".' '':'-;" ':"' '-.' . "'.''.?:.
To jest kolejny test. '.:.'' . . ., ,, '.'.-'-.'' .-'-'. .: '!
To jest kolejny test. _ ',-.:',-. . . -, . . .
9876543210 ' ," . "''.'.' V' " ','
9876543210 ' ..,-.,;..; ... : ,-: .: .-, ..v.-, , - ; i-
*] '. . '. -/' r-" -. - -.<-; ;--0;. ^v -.,.,.:-..^
telnet> close . ' ' , ...'.....- : r':-a- *.-. -, > - -'-t
Connection closed. '- '
,-; ; , t ,.,. -,,, .-.- .-...
W Javie wielkość liter ma znaczenie. Java. net. socket nie jest tym samym co
java. net. socket. Języki programowania o takiej właściwości nie zawsze pozwa-
lają autorom na stosowanie reguł standardowej angielskiej gramatyki. Na ogół mo-
żliwe jest zredagowanie zdania w taki sposób, aby nie dochodziło do konfliktu, więc
tam, gdzie się dało, starałem się tak konstruować zdania. Zgodnie z tą zasadą, gdy
w tekście chciałem odwołać się do klasy lub przykładu klasy, używałem wielkiej li-
tery, co można zobaczyć w kodzie źródłowym, zazwyczaj na początku i w środku -
na przykład ServerSocket.
W całej książce, zgodnie z brytyjskimi regułami stosowania znaków przestanko-
wych, umieszczałem znak zapytania wewnątrz tylko wtedy, gdy stanowił on część
cytowanego materiału. Mimo że w szkole uczyłem się reguł amerykańskich, system
brytyjski wydaje mi się logiczniejszy, zazwyczaj nawet wtedy, gdy trzeba umieścić
kod źródłowy w cudzysłowie, a brakujący lub nadmiarowy przecinek, średnik lub
kropka decydują, czy kod da się skompilować, czy nie.
Chociaż zamieszczone tu przykłady mają charakter akademicki, a nie praktyczny, to
kilka z opracowanych przeze mnie klas ma prawdziwą wartość. Swobodnie możesz
je (lub dowolne ich części) wykorzystać w swoim kodzie. Nic potrzebujesz do tego
żadnych specjalnych zezwoleń. Jeśli chodzi o mój kod, to jest on własnością pu-
bliczną (nic dotyczy to jednak opisującego go tekstu!). Takie klasy znajdują się
gdzieś w pakiecie com.macf aq, który w zasadzie odzwierciedla strukturę pakietu
java. Na przykład klasa Saf ePrinterWri ter z rozdziału 4. znajduje się w pakie-
cie com. mac f aq. i o. Kiedy pracujesz na tych klasach, nie zapominaj, że skompilo-
wane pliki .class muszą znajdować się w katalogach odpowiadających strukturze ich
pakietów wewnątrz ścieżki klasy oraz że musisz je zaimportować do swojej klasy,
zanim zaczniesz z nich korzystać. Na stronic WWW tej książki, pod adresem
http://metalabMnc.edu/javafacj/books/jnp2c/ znajdziesz plik-pojemnik, zawierający
wszystkie te klasy, które mogą zostać zainstalowane na twojej ścieżce klasy.
XXII
Wstęp
,--11
..___j___
Prośba o komentarze
Bardzo mnie cieszy, gdy dostaję od czytelników ogólne uwagi, jaka dobra mogłaby
być ta książka, konkretne poprawki, tematy zagadnień, które chcieliby zobaczyć
opisane, lub po prostu historie ich zmagań w pracy nad programowaniem siecio-
wym. Możesz skontaktować się ze mną za pomocą poczty elektronicznej dharo@me-
talab.unc.edu. Proszę, weź jednak pod uwagę, że codziennie dostaję setki listów i dla-
tego nie mogę osobiście odpowiedzieć na każdy z nich. Aby mieć większe szansę na
uzyskanie mojej osobistej odpowiedzi, zaznacz, że jesteś czytelnikiem tej książki. Je-
śli twoje pytanie dotyczy konkretnego programu, który nie działa tak, jak się tego
spodziewałeś, spróbuj sprowadzić zagadnienie do najprostszego przypadku, który
wywołuje błąd, najlepiej do jednej klasy, a następnie wstaw tekst całego programu
do swojego listu. Nieprzemyślana korespondencja będzie kasowana bez otwierania.
I bardzo proszę, abyś wysyłał wiadomość z tego konta, na które chcesz otrzymać od-
powiedź, oraz upewnił się, że masz właściwie ustawiony adres zwrotny! Nie ma nic
bardziej frustrującego niż spędzenie godziny lub więcej na sumiennym przygotowa-
niu odpowiedzi na interesujące pytanie tylko po to, aby trafić w próżnię, gdyż kore-
spondent kontaktował się ze mną z publicznego terminala i zapomniał w ustawie-
niach przeglądarki wstawić swój aktualny adres poczty elektronicznej.
Należę także do zwolenników starego powiedzenia: "Jeśli książka ci się podobała,
powiedz o niej znajomym. Jeśli nie, powiedz to mnie" . Chciałbym usłyszeć zwłasz-
cza o pomyłkach. Jest to moja ósma książka. Nie opublikowałem jeszcze idealnej, ale
wciąż się staram. I chociaż redaktorzy wydawnictwa O'Reilly i ja ciężko pracowaliś-
my nad tą książką, to jestem pewien, że gdzieś przepuściliśmy omyłki i błędy typo-
graficzne. Poza tym jestem przekonany, że przynajmniej jeden z nich jest strasznie
kłopotliwym kłamstwem. Jeśli znajdziesz jakiś błąd lub literówkę, proszę daj mi
znać, abym mógł to poprawić. Zamieszczę to na stronie WWW tej książki pod
adresem http://metalab.unc.edu/javafaq/books/inp2c/ oraz w witrynie wydawnictwa
O'Reilly pod adresem http://www.oreilly.com/catalog/javanp2/errata/. Zanim zgłosisz
błąd, sprawdź proszę na jednej z tych stron, czy przypadkiem nie zostałem już o nim
poinformowany i czy nie zamieściłem tam korekty. Wszystkie zgłoszone błędy zo-
staną skorygowane w następnych wydaniach książki.
Informacje o znalezionych błędach, jak również sugestie co do kolejnych wydań,
możesz także przesłać na adres:
O'Reilly & Associates, Inc. . '
101 Morris Street "'''' ' J;r< '" '" " vv'" -
Sebastopol, CA 95472 """'""' - ' : -
(800) 998-9938 (w USA lub Kanadzie) ' , ?" '
" (707) 829-0515 (międzynarodowy/lokalny) * " <
! (707) 829-0104 (f ax) . -"t;"--i>:- '
Prośba o komentarze
XXIII
Możesz także wysłać korespondencję elektroniczną prosto do wydawnictwa O'Reilly.
Aby znaleźć się na liście adresowej lub poprosić o katalog, wyślij wiadomość elek-
troniczną do:
info@oreilly.com
Pytania techniczne oraz komentarze na temat książki wyślij elektronicznie na adres:
bookcjuestions@oreilly.com ? r > .,,-<<'.;....^ji* l{::~nn.iify^
Więcej informacji o tej książce oraz innych pozycjach znajdziesz w witrynie siecio-
wej wydawnictwa O'Reilly:
http://www.oreilly.com "" ' ' '"'"' "'"" ''-'"'K' ''*
Pozwól, że wyjaśnię parę kwestii, które często niesłusznie są zgłaszane do popra-
wienia. Po pierwsze, nie wszystkie sygnatury metod podane w tej książce dokładnie
odpowiadają sygnaturom z dokumentacji API javadoc firmy Sun. W szczególności,
często zmieniam nazwy argumentów, aby było jasne, co oznaczają. Na przykład Sun
określa w dokumentacji metodę parse() w klasie HTMLEditorKit. Parser
w następujący sposób:
public abstract void parse (Reader r, HTMLEditorKit. ParserCallback cb, L-
boolean ignoreCharSet) throws IOException
Napisałem to w bardziej zrozumiały sposób: ,,,, . , , f , . ,.,.,,.
public abstract void parse(Reader input, HTMLEditorKit.ParserCallback '
callback, boolean ignoreCharSet) throws IOException :
Oba zapisy oznaczają dokładnie to samo. Nazwy argumentów metod są czysto for-
malne i nie mają żadnego wpływu na kod klienta pisany przez programistów, który
wywołuje te metody. Równie dobrze mogłem napisać to po łacinie lub w języku
mieszkańców wysp Fidżi, co tak naprawdę niczego by nie zmieniło. Jedyną różnicę
stanowi zrozumiałość dla czytelnika.
Poza tym, czasami dodawałem do niektórych metod warunki t hrows, które są le-
galne, ale nieobowiązkowe. Na przykład, jeśli metoda jest zadeklarowana jako wy-
rzucająca tylko wyjątki lOException, ale akurat może wyrzucić ConnectExcep-
tion, UnknownHostException oraz SSLException i wszystkie podklasy
IOException, to czasami deklaruję wszystkie cztery możliwe wyjątki. Co więcej,
jeżeli wygląda na to, że w określonych okolicznościach metoda wyrzuca konkretny
wyjątek systemu runtime, taki jak NullPointerExcept i on, Sccuri LyF,xcop-
tion lub 11 Legał Ar (jurnent.F,xception, to również odnotowuję ten fakt w sy-
gnaturze metody. Oto na przykład deklaracja firmy Sun jednego /. konstruktorów
Socket:
public Socket (InetAddress address, int port) throws IOException .. :,,
A oto moja dla tego samego konstruktora:
public Socket(InetAddress address, int port)
throws ConnectException, IOException, SecurityException
Nie sq one zupełnie równoważne - moja jest pełniejsza - ale nn ich podstawie po-
wstanie dokładnie taki sam skompilowany kod bajtowy.
H
1-TT
xx/i/
-i
..4-
J.
Podziękowania
W powstanie tej książki było zaangażowanych wiele osób. Mój redaktor, Mikę Louki-
des, nadał całej sprawie bieg i udzielał mi wielu pomocnych komentarzy w trakcie
udoskonalania przeze mnie książki. Dr Peter "Peppar" Parnes niezmiernie mi pomógł
przy rozdziałach dotyczących przesyłania grupowego. Korektorzy i redaktorzy
techniczni zapewnili nieocenioną pomoc w wyłapywaniu błędów i opustek. Dzięki
bezcennym radom Simona St. Laurenta wiedziałem, które tematy wymagają rozwi-
nięcia. Scott Oaks, użyczając swojej wiedzy o wątkach w rozdziale 5., gdzie odnalazł
ledwo uchwytne błędy, udowodnił, że zagadnienie wielowątkowości wciąż wyma-
ga spojrzenia eksperta. Jim Farley zgłosił wiele przydatnych uwag dotyczących RMI
(rozdział 18.). Nieustające zaangażowanie Timothy F. Rohaly'ego pozwoliło upew-
nić się, że zamknąłem wszystkie gniazda i wyłapałem wszelkie istniejące wyjątki
oraz że napisany kod jest możliwie jasny, bezpieczny i najbardziej odpowiedni. John
Zukowski znalazł liczne opustki, które dzięki niemu zostały uzupełnione. A sokole
oko Avnera Gelba wykazało się zadziwiającą umiejętnością wypatrywania
pomyłek, które w jakiś sposób umknęły mojej uwadze, wszystkim korektorom oraz
dziesiątkom tysięcy czytelników pierwszego wydania książki.
Nie jest przyjęte dziękowanie wydawcy, ale to właśnie on nadaje ton całemu
wydawnictwu, autorom, redaktorom, a także personelowi technicznemu. Myślę, że
Tim O'Rcilly zasługuje na specjalne wyrazy uznania za uczynienie O'Reilly & Asso-
ciates, Inc. jednym z najlepszych wydawnictw, dla których można pisać. Jeżeli ist-
nieje taka osoba, bez której ta książka nigdy by nie powstała, to jest nią właśnie Tim.
I jeśli, drogi czytelniku, uznasz, że książki wydawnictwa O'Reilly są istotnie lepsze
od większości znajdujących się na rynku, to jest to jego bezpośrednią zasługą.
Mój agent, David Rogelberg, przekonał mnie, iż możliwe jest zarabianie na życie pi-
saniem książek takich jak ta, zamiast pracowania w jakimś biur/.e. Cały zespół w mc-
talab.unc.edu przez ostatnie kilka lat naprawdę ulepszył sposoby komunikowania się
z czytelnikami. Każdy czytelnik, który przesłał mi pochwały czy nagany za pierw-
sze wydanie książki, przyczynił się do napisania tej poprawionej wersji. Wszystkim
tym osobom należą się podziękowania i wyrazy uznania. I wreszcie jak zawsze
chciałbym złożyć serdeczne podziękowania mojej żonie, Beth. Bez jej miłości
i wsparcia ta książka nigdy by nie zaistniała. ....*-,<.< : ;..<;.-, s ? v '.'>:r-- .; :-
EllioHc Rusly Uamld
dharo@mctalab.unc.cdu
20 kwietnia 2000 r.
1
Dlaczego Java sieciowa?
W tym rozdziale:
Co potrafi program sieciowy?
Chwileczkę! Jeszcze coś!
Java jest pierwszym jeżykiem programowania od razu zaprojektowanym z myślą
o sieci. Globalny Internet rozrasta się, a Java wyjątkowo dobrze nadaje się do budo-
wania aplikacji sieciowych następnej generacji. Oferuje ona rozwiązania licznych
problemów - najważniejsze to niezależność platformowa, bezpieczeństwo i między-
narodowy zestaw znaków - które decydują o znaczeniu aplikacji internetowych,
a wciąż jeszcze są trudne do wyegzekwowania w innych językach. Te i inne cechy
Javy umożliwiają internautom szybkie ściąganie z witryn sieciowych programów
nieuwiarygodnionych i wykonywanie ich bez obaw, że rozprzestrzenia one wirusa,
ukradną dane lub spowodują załamanie systemu. Faktem jest, że aplct |a vy ma wbu-
dowane znacznie większe zabezpieczenia niż oprogramowanie z półki sklepowej.
Jedną z największych tajemnic Javy jest sposób na łatwe pisanie programów siecio-
wych. Rzeczywiście, znacznie łatwiej jest napisać program sieciowy w Javie niż
praktycznie w jakimkolwiek innym języku. Ta książka przedstawia dziesiątki kom-
pletnych programów wykorzystujących Internet. Niektóre z nich są prostymi,
podręcznikowymi przykładami, a inne w pełni funkcjonalnymi aplikacjami. Z pew-
nością zauważysz w tych aplikacjach, jak niewiele kodu przeznaczono na obsługę
działania w sieci. Nawet w programach intensywnie eksploatujących siec, takich jak
serwery i klienty WWW, prawic cały kod zajmuje się przetwarzaniem danych lub
obsługą interfejsu użytkownika. Ta część programu, która współdziała z siecią, jest
zazwyczaj najkrótsza i najprostsza.
Jednym słowem, dla aplikacji Javy wysyłanie danych poprzez Internet i odbieranie
ich stamtąd jest łatwe. Także aplety mogą komunikować się za pośrednictwem Inter-
netu, ale ograniczają te zabezpieczenia. W tym rozdziale dowiesz się nieco, jak w
Javie pisze się aplety i aplikacje ukierunkowane na działanie sieciowe. W dalszych
rozdziałach poznasz narzędzia potrzebne do tworzenia takich programów.
Co potrafi program sieciowy?
ed Astronomy - stratosferyczne obserwatorium astronomiczne w zakresie pod-
czerwieni).*
Program napisany w Javie może zrobić to wszystko, a nawet jeszcze więcej. Potrafi
wysłać do bazy danych zapytania SQL. Rysunek 1-1 przedstawia fragment progra-
mu, który komunikuje się ze zdalnym serwerem bazy danych, aby przekazać zapy-
tania bazie danych Books in Print.
Bowker Books in Print <199Sto Februaiy 1999>
(^ Display Oocumenis
(JfSnu "-' &nsl
D ?
Amjhor Help
Sy
Maory
. Run Sftyed
iii Stth
Setrttt Htaory : set 4: OT?eillypb
Otattorc [T* -J.-.
51 9 document(s)
Select At:ession Number
09295887
Titie
Java l- O [lllustrated]
Autfiors
Harold, Elliotte
Piiblisher/Distributor
OReilly&Assocs.
Status
Dale ofPublicaiion
199901
Bindin^Price
Trade Paper ($32.95 (Ingram Price), $32.95 (Retail Price))
ISBK
1.56592-485-1
Lanąuage
Er:l!$h
U
ava Appiet Wmdov*
Rysunek 1-1. Dostęp do bazy danych Bowker Books in Print za pomocą programu w Javie pod adresem
http: iclient.ovid.com/
Chociaż podobną rzecz można wykonać za pomocą formularza HTML lub CGI,
klient Javy jest elastyczniejszy, gdyż nie jest ograniczony do jednej strony. Kiedy coś
ulega zmianie, to przez sieć powinny zostać przesłane tylko aktualne dane. Serwer
WWW musiałby wysłać wszystkie dane oraz informacje o ich wyglądzie. Poza tym
żądania klienta, aby zmienić tylko sposób prezentacji danych, a nie wyświetlane
SOFIA będzie dwuipółmetrowym reflektorem, zamontowanym na pokładzie Boeinga 747. Po wypusz-
czeniu w 2001 roku będzie największym na świecie teleskopem przenoszonym drogą powietrzną. Taki
teleskop ma wiele zalet w porównaniu z urządzeniami naziemnymi - jedną z nich jest możliwość ob-
serwaq'i zjawisk przesłanianych przez atmosferę ziemską. Co więcej nie jest on umieszczony pod okre-
śloną długością i szerokością geograficzną i może przemieszczać się za obserwowanym zjawiskiem.
Informaqe na temat zdalnego, opartego na Javie sterowania teleskopami znajdziesz pod adresem
http://pioneer.gsfc.nasa.gov/public/irc/. Dane o projekcie SOFIA znajdują się w witrynie http:/jwww. so-
fa.usra.edu/.
Rozdział 1: Dlaczego Java sieciowa?
Co potrafi program sieciowy?
Zdolność do działania w sieci daje prostym programom potężne możliwości. Dzięki
sieci jeden program może pobierać informacje przechowywane na milionach kompu-
terów rozrzuconych po całym świecie. Jeden program może komunikować się
z dziesiątkami milionów osób. Jeden program może zaprząc moc wielu kom-
puterów do rozwiązywania jakiegoś problemu.
Brzmi to jak reklama firmy Microsoft, a nie początek książki technicznej. Porozma-
wiajmy o szczegółach tego, co mogą robić programy sieciowe. Aplikacje sieciowe ge-
neralnie przybierają jedną z kilku postaci. Rozróżnienie, o którym słyszy się najczęś-
ciej, to podział na klienty i serwery. W najprostszym przypadku klienty pobie-
rają dane z serwera i je wyświetlają. Bardziej złożone programy klienckie filtru-
ją i porządkują dane, stale pobierając zmieniające się informacje, wysyłają dane do
innych osób i komputerów oraz w czasie rzeczywistym oddziałują z ró-
wnorzędnymi programami umożliwiając pogawędki sieciowe, gry dla wielu użyt-
kowników i współpracę. Serwery odpowiadają na żądanie pobrania danych. Zwykły
serwer po prostu wynajduje jakiś plik i przekazuje go klientowi, a bardziej złożone
serwery zazwyczaj wykonują wiele pracy, przetwarzając dane przed udzieleniem od-
powiedzi. Poza klientami i serwerami następną generację aplikacji sieciowych prawie
na pewno będą stanowiły mobilne agenty, które przenoszą się od serwera do serwera,
aby wyszukiwać informaq'e w sieci WWW i zanosić je do swojego protokolarnego
domu. A to dopiero początek. Przyjrzyjmy się uważnie możliwościom, które otwierają
się przed tobą, gdy do swojego programu dodasz współdziałanie z siecią.
Pobieranie i wyświetlanie danych
Na najbardziej podstawowym poziomie klient sieci pobiera dane z serwera i
przedstawia je użytkownikowi. Oczywiście wiele programów robiło to samo, za-
nim pojawiła się Java. Prawdę mówiąc, właśnie tym zajmują się przeglądarki sie-
ciowe. Jednak mają one ograniczenia. Mogą rozmawiać tylko z niektórymi rodza-
jami serwerów (zazwyczaj serwerami WWW, FTP, gopher i ewentualnie serwe-
rami pocztowymi oraz serwerami wiadomości). Są w stanie zrozumieć i wyświe-
tlić niektóre rodzaje danych (generalnie tekst, HTML i kilka standardowych
formatów obrazu). Jeśli chcesz czegoś więcej, to masz problem: przeglądarka sie-
ciowa nie może przesłać bazie danych poleceń SQL, aby zapytać o wszystkie
będące w sprzedaży książki Elliotta Rusty'ego Harolda opublikowane przez wy-
dawnictwo O'Reilly & Associates. Przeglądarka sieciowa nie może też sprawdzić
aktualnego czasu (z dokładnością do setnych części sekundy) na superdokład-
nym zegarze masera tlenowego w obserwatorium amerykańskiej marynarki wo-
jennej (http://tycho.usno.navy.mil/), stosując sieciowy protokół czasu. Przeglądarka
nie potrafi też posługiwać się specyficznym protokołem wykorzystywanym do
zdalnego sterowania urządzeniem HAWC (ang. High Resolution Airborne Wide-
band Camera - szerokopasmowy, powietrzny teleskop wysokiej rozdzielczości)
znajdującym się w obserwatorium SOFIA (ang. Stratospheric Observatory for Infra-
Rozdział 1: Dlaczego Java siedowa?
Co potrafi program sieciowy?
Zdolność do działania w sieci daje prostym programom potężne możliwości. Dzięki
sieci jeden program może pobierać informacje przechowywane na milionach kompu-
terów rozrzuconych po całym świecie. Jeden program może komunikować się
z dziesiątkami milionów osób. Jeden program może zaprząc moc wielu kom-
puterów do rozwiązywania jakiegoś problemu.
Brzmi to jak reklama firmy Microsoft, a nie początek książki technicznej. Porozma-
wiajmy o szczegółach tego, co mogą robić programy sieciowe. Aplikacje sieciowe ge-
neralnie przybierają jedną z kilku postaci. Rozróżnienie, o którym słyszy się najczęś-
ciej, to podział na klienty i serwery. W najprostszym przypadku klienty pobie-
rają dane z serwera i je wyświetlają. Bardziej złożone programy klienckie filtru-
ją i porządkują dane, stale pobierając zmieniające się informacje, wysyłają dane do
innych osób i komputerów oraz w czasie rzeczywistym oddziałują z ró-
wnorzędnymi programami umożliwiając pogawędki sieciowe, gry dla wielu użyt-
kowników i współpracę. Serwery odpowiadają na żądanie pobrania danych. Zwykły
serwer po prostu wynajduje jakiś plik i przekazuje go klientowi, a bardziej złożone
serwery zazwyczaj wykonują wiele pracy, przetwarzając dane przed udzieleniem od-
powiedzi. Poza klientami i serwerami następną generację aplikacji sieciowych prawie
na pewno będą stanowiły mobilne agenty, które przenoszą się od serwera do serwera,
aby wyszukiwać informacje w sieci WWW i zanosić je do swojego protokolarnego
domu. A to dopiero początek. Przyjrzyjmy się uważnie możliwościom, które otwierają
się przed tobą, gdy do swojego programu dodasz współdziałanie z siecią. >...-.
Pobieranie i wyświetlanie danych
Na najbardziej podstawowym poziomie klient sieci pobiera dane z serwera i
przedstawia je użytkownikowi. Oczywiście wiele programów robiło to samo, za-
nim pojawiła się Java. Prawdę mówiąc, właśnie tym zajmują się przeglądarki sie-
ciowe. Jednak mają one ograniczenia. Mogą rozmawiać tylko z niektórymi rodza-
jami serwerów (zazwyczaj serwerami WWW, FTP, gopher i ewentualnie serwe-
rami pocztowymi oraz serwerami wiadomości). Są w stanie zrozumieć i wyświe-
tlić niektóre rodzaje danych (generalnie tekst, HTML i kilka standardowych
formatów obrazu). Jeśli chcesz czegoś więcej, to masz problem: przeglądarka sie-
ciowa nie może przesłać bazie danych poleceń SQL, aby zapytać o wszystkie
będące w sprzedaży książki Elliotta Rusty'ego Harolda opublikowane przez wy-
dawnictwo O'Reilly & Associates. Przeglądarka sieciowa nie może też sprawdzić
aktualnego czasu (z dokładnością do setnych części sekundy) na superdokład-
nym zegarze masera tlenowego w obserwatorium amerykańskiej marynarki wo-
jennej (http://tycho.usno.navy.mil/), stosując sieciowy protokół czasu. Przeglądarka
nie potrafi też posługiwać się specyficznym protokołem wykorzystywanym do
zdalnego sterowania urządzeniem HAWC (ang. High Resolution Airborne Wide-
band Camera - szerokopasmowy, powietrzny teleskop wysokiej rozdzielczości)
znajdującym się w obserwatorium SOFIA (ang. Stratospheric Observatory for Infra-
Co potrafiprogram sieciowy?
d Astronomy - stratosferyczne obserwatorium astronomiczne w zakresie pod-
czerwieni).*
Program napisany w Javie może zrobić to wszystko, a nawet jeszcze więcej. Potrafi
wysłać do bazy danych zapytania SQL. Rysunek 1-1 przedstawia fragment progra-
mu, który komunikuje się ze zdalnym serwerem bazy danych, aby przekazać zapy-
tania bazie danych Books in Print.
f Bowker Boofcs in Print <1995to February 1999>
DisplayDocuments
D ?
Anohor Help
Oispłsy
to Pńn*
S.Y*
Hisloty
Run S*vd
Surch
Srcłit**wy:|set4 OTieilly.pb.
atattore [74 -J "
519 document(s)
l~ Select
AccessionNumber
09295887
TitJe
Javal-0. [lllustrated]
Authors
Harold, Elliotte.
Pubhsrter/DIstributor
OReilly&Assocs.
Status
Datę ofPublication
199901
Bindmg/Price
Trade Paper ($32.95 (Ingram Price). $32.95 (Retail Prtce))
ISBN
1-56592-485-1
Language
English
U
n TOts | i Seteot
" ~-.-.. s: BeWs
; flB jcreen !
avaAppletWindow
Rysunek 1-1. Dostęp do bazy danych Bowker Books in Print za pomocą programu w Javie pod adresem
h ttp;'Iclient. ovid. com/
Chociaż podobną rzecz można wykonać za pomocą formularza HTML lub CGI,
klient Javy jest elastyczniejszy, gdyż nie jest ograniczony do jednej strony. Kiedy coś
ulega zmianie, to przez sieć powinny zostać przesłane tylko aktualne dane. Serwer
WWW musiałby wysłać wszystkie dane oraz informacje o ich wyglądzie. Poza tym
żądania klienta, aby zmienić tylko sposób prezentacji danych, a nie wyświetlane
SOFIA będzie dwuipólmetrowym reflektorem, zamontowanym na pokładzie Boeinga 747. Po wypusz-
czeniu w 2001 roku będzie największym na świecie teleskopem przenoszonym drogą powietrzną. Taki
teleskop ma wiele zalet w porównaniu z urządzeniami naziemnymi - jedną z nich jest możliwość ob-
senvaq'i zjawisk przesłanianych przez atmosferę ziemską. Co więcej nie jest on umieszczony pod okre-
śloną długością i szerokością geograficzną i może przemieszczać się za obserwowanym zjawiskiem.
Informacje na temat zdalnego, opartego na Javie sterowania teleskopami znajdziesz pod adresem
http://pioneer.gsfc.nasa.gov/public/irc/. Dane o projekcie SOFIA znajdują się w witrynie http://www. so-
fia-usra.edu/.
Rozdział 1: Dlaczego Java sieciowa?
dane (na przykład ukryć lub pokazać kolumnę jakiś wyników), nie wymagają nawet
kolejnego połączenia z serwerem bazy danych, ponieważ struktura logiczna sposo-
bu prezentacji danych jest wbudowana w klienta. Interfejsy baz danych oparte na
HTML-u mają tendencję do przeładowywania się zarówno po stronie serwera sieci,
jak i serwera bazy danych. Klienry Javy przerzucają całe przetwarzanie ze strony in-
terfejsu użytkownika na klienta, a bazie danych umożliwiają skoncentrowanie się na
danych.
Program w Javie może połączyć się z sieciowym serwerem czasu, aby zsynchronizo-
wać się z zegarem atomowym. Rysunek 1-2 przedstawia aplet, który właśnie to robi.
Program w Javie może porozumiewać się w dowolnym specyficznym języku, również
w tym, który służy do sterowania urządzeniem HAWC. Rysunek 1-3 przedstawia
wczesny prototyp sterownika HAWC. Jeszcze ciekawsze jest, że program w Javie za-
gnieżdżony w stronie HTML (aplet) może dać przeglądarce WWW zgodnej z Javą
możliwości, których początkowo nie miała.
'3 The officiat U S linie - clock - Miciosoll Inietnet Emlwa
Plik ?dycja &idok Uk&one narzędzia Pomoc
Wstecz Zattzym^ Odśwież Stat Wysaukaj Ulubione Htstora
-O"
Focsa
Drukuj
Adres JIS] http://www.time.gov/!ime2one.cgi?Mountain/d/-7/}ava
Rysunek 1-2. Aplet atomowego zegara sieciowego pod adresem http: www.time.gov/
Poza tym przeglądarka WWW potrafi wyświetlić tylko jedną całą stronę HTML.
Program w Javie może wyświetlić mniejszą lub większość zawartość w zależności
od potrzeb. Potrafi wybrać i wyświetlić konkretną informację, której żąda użytkow-
nik. Na przykład program indeksujący może wybrać tylko tekst strony, odfiltro-
wując znaczniki HTML i łącza nawigacyjne. Albo też program sumujący może zesta-
wić dane z wielu witryn i stron. Na przykład serwlet w Javie może zapytać użytków-
Co potrafi program sieciowy?
nika o tytuł książki, używając do tego formularza HTML, następnie połączyć się
z dziesięcioma księgarniami w sieci, aby sprawdzić jej cenę, a na koniec wysłać
klientowi stronę HTML z informacją, które sklepy mają ją na składzie, posortowaną
według ceny. Rysunek 1-4 przedstawia witrynę sieciową WebMarket sklepu Ama-
zon.com (dawniej Junglee) z rezultatem przeprowadzonego wyszukiwania najniż-
szej ceny powieści Anny Rice. W obu przykładach to, co ukazuje się użytkownikowi,
jest oryginalną stroną (lub stronami) WWW o wyglądzie takim jak w przeglądarce.
Program w Javie może działać jako filtr przekształcający to, co serwer wysyła, w to,
co użytkownik chciałby zobaczyć.
Vteua8zattons
Status:
fóe Commands
HouseKeepinB :
Mit .
60000
HouseKeeping
hte Commands
[Mów Nad HouseKeeping ; Status |
DtC ,
1000:00.00
Fłe Commatids
Move
|'How HouseKecjjsia l Status
JF: Uf. . . . . "" .
: J _ _ _ _
Movo
Rysunek 1-3. Prototyp sterownika HAWC
Oprócz tego program w Javie może w pełni wykorzystywać nowoczesny graficzny
interfejs użytkownika do przedstawiania tych danych i uzyskiwania odpowiedzi.
Chociaż przeglądarki sieciowe potrafią wyświetlać dane w bardzo ładny i ciekawy
sposób, przy pobieraniu wejścia od użytkownika i interakcji z nim nadal są ograni-
czone do formularzy HTML.
Programy w Javie są elastyczne, ponieważ Java, w przeciwieństwie do HTML-a, jest
pełnoprawnym językiem programowania. Programy w Javie postrzegają połączenia
z siecią jako strumienie danych, które mogą zostać zinterpretowane i na które można
odpowiedzieć w dowolny, akurat potrzebny sposób. Przeglądarki sieciowe widzą
tylko niektóre rodzaje strumieni danych i potrafią je interpretować zaledwie na kilka
z góry określonych sposobów. Jeśli przeglądarka WWW napotka strumień danych,
którego nie zna (na przykład odpowiedź na zapytanie SQL), jej zachowanie będzie
nieprzewidywalne. Witryny WWW mogą używać programów CGI w celu zapew-
Rozdział ljDiaczeao java sieciowa?
nienia sobie niektórych takich umiejętności, lecz w interfejsie użytkownika nadal
pozostają ograniczone do HTML-a.
0k
Wstecz
Adres 1^1
Jj^idok Ulubione Marzła Pomos
; Zatfzymaj Odśwież Star! Wyszukaj Ulubione Hiaoria Pcc?a
J
Dyskus>3
hpV/209 135 142.203Aesultsjsp?p=go2netS_d^nr^ ^j
] Fetch
D@GPłLE
GO Shopplng | Flssearch Products
Anna Rice VJttorio the Vampire
:.?U matches, sorted by price
yoursasrch, c.
by:
Pages: l 2'
Merch<3Q|j
yittoriothe yampire $5.99 from Half.com
by Rice, Annę
Condition: Used. Buy for Ha!f, Sel for Half!
Marrow these results to; &p.v^_L_Ł_r.Us;a:io_as = Eoo>_s
yittorio the Vampire $6.50 from Half.com
by RJcej Annę
Condition: Used. Buy for Half, SeH for Half!
yittorio the Vampire: New Tates ot the Vampire
$6.99 from bookcloseouts.com
Rysunek 1-4. Witryna WebMarket o adresie http-J/www.webmarket.com/zos\a!& napisana w Javie
z wykorzystaniem API serwletów
Napisanie w Javie programu, który komunikuje się z serwerami internetowymi, jest
łatwe. Biblioteka kluczowa Javy zawiera klasy do komunikowania się z węzłami In-
ternetu za pomocą protokołów TCP i UDP z rodziny protokołów TCP/IP. Wystar-
czy, że podasz Javie, jaki adres IP i port cię interesuje, a obsłuży ona wszystkie detale
na niższych poziomach. Java nie obsługuje protokołów XetWare IPX, Windows Net-
BEUI, AppleTalk oraz innych protokołów sieciowych niezgodnych z IP. Jednak i to
wkrótce nie będzie stanowiło problemu, gdyż TCP/IP staje się powszechnym języ-
kiem aplikacji sieciowych. Nieco bardziej niewygodne jest to, że }ava nie zapewnia
bezpośredniego dostępu do warstwy IP pomiędzy TCP oraz UDP, i dlatego nie
może być wykorzystywana do pisania programów takich jak ping lub traceroute. Jed-
nak takie potrzeby są dość nietypowe. Java z pewnością doskonale spełnia 909t ocze-
kiwań większości programistów sieciowych.
Gdy program połączy się już z serwerem, program lokalny musi zrozumieć proto-
kół, jakim posługuje się zdalny serwer, by prawidłowo zinterpretować dane zwraca-
ne przez serwer. W prawie wszystkich przypadkach pakowanie danych wysyła-
nych do serwera i odpakowywanie odbieranych jest trudniejsze niż samo ustano-
wienie połączenia. Java zawiera klasy, które pomogą twoim programom komuniko-
wać się z określonymi rodzajami serwerów, przede wszystkim z serwerami WWW.
Zawiera ona także klasy potrzebne do przetwarzania niektórych rodzajów danych,
takich jak tekst, obrazki GIF oraz obrazki JPEG. Jednakże nie wszystkie serwery są
serwerami WWW, a nie wszystkie dane są typu tekstowego, GIF lub JPEG. Dlatego
Iava umożliwia napisanie zarówno sterowników obsługujących protokoły do ko-
munikowania się z różnymi rodzajami serwerów, jak i sterowników obsługujących
treść, które zrozumieją i wyświetlą dane rozmaitych typów. Zgodna z Javą
przeglądarka sieciowa może automatycznie ściągać i instalować oprogramowanie
potrzebne witrynie, którą odwiedza. Aplety Javy mogą wykonywać zadania podobne
do tych, które wykonują wtyczki Netscape'a. Jednak aplety są bezpieczniejsze
i znacznie wygodniejsze niż wtyczki. Nie wymagają bowiem interwencji użytkow-
nika przy ściąganiu czy też instalowaniu oprogramowania, a także nie marnują pa-
mięci lub przestrzeni na dysku, gdy się z nich nie korzysta.
Powtarzalne pobieranie danych i
Przeglądarki sieciowe pobierają dane na żądanie - użytkownik prosi o stronę spod
jakiegoś URL-a, a przeglądarka ją dostarcza. Ten model działania jest odpowiedni,
jeśli użytkownik tylko raz potrzebuje danej informacji, a same informaq'e niezbyt
często ulegają zmianom. Natomiast stały dostęp do informacji, które często się zmie-
niają, nadal sprawia kłopoty. Podjęto kilka prób rozwiązania tego problemu za po-
mocą rozszerzeń HTML-a oraz HTTP. Na przykład popychanie przez serwer
i ciągnięcie przez klienta są dość niezdarnymi sposobami, dzięki którym klient może
mieć uaktualnione dane. Istnieją nawet usługi, które wysyłają wiadomość elektro-
niczną informującą, że interesująca cię strona została zmieniona.*
Natomiast klient w Javie może wielokrotnie łączyć się z serwerem, aby aktualizować
obraz danych. Jeżeli dane zmieniają się bardzo często - na przykład ceny na giełdzie
- aplikacja w Javie może utrzymywać otwarte połączenie z serwerem przez cały czas
i wyświetlać na ekranie zmieniający się wykres cen na giełdzie. Rysunek 1-5 przed-
stawia tylko jeden z wielu takich apletów. Program w Javie może nawet odpowiadać
w czasie rzeczywistym na zmiany danych: aplet giełdowy może zadzwonić, jeśli
cena akcji IBM-a przekroczy 100 dolarów, abyś wiedział, że masz zlecić brokerowi
sprzedaż. Bardziej skomplikowany program mógłby nawet dokonać sprzedaży bez
ludzkiej interwencji. Łatwo sobie wyobrazić znacznie bardziej złożone kombinacje
danych, które mogą być monitorowane przez klienta lub których nie da znaleźć się
na żadnym serwerze WWW. Na przykład mógłbyś dostawać cenę giełdową pewnej
firmy z jednego serwera, wyniki głosowania na kandydatów, którzy wnieśli
udziały, z innego serwera, a następnie powiązać te dane, aby zdecydować, czy nale-
ży kupować, czy też sprzedawać akcje firmy. Broker giełdowy z pewnością nie pole-
ciłby takiego schematu działania typowemu małemu inwestorowi.
Dopóki dane są dostępne w Internecie, dopóty program w Javie może je śledzić,
uane dostępne w Internecie obejmują warunki pogodowe na jednej z wysp archipe-
przykład URL-minder pod adresem http://www.netmind.com/.
Rozdział 1: Dlaczego Java sieciowa?
lagu Fidżi, temperaturę lekkich drinków przygotowywanych przez maszynę
w Pittsburghu, ceny giełdowe akcji firmy Sun Microsystems, jak również pozycję
tego podręcznika na liście książek sprzedawanych w księgarni Amazon.com. Któ-
rakolwiek z tych informacji lub wszystkie mogą być włączane do twojego programu
w czasie rzeczywistym.
* Quole.com LiveChartt - Microsoft Internat ?xploier
:ja &idok UMbione $arzędzia Pomos
Zatrzyma Odśwież Start
EuSEJ
Uiubone Htóoria Foc#a C
Acjres 15} http://www.quote.com/quotecom/livechafts/
Grr40%OFFEVOKEWEBCONF?RENCING
THROUGH LYCOS
Tradma cnlme yet?
Here's $75 to start
WhisperNumber cum
Earninas Exoec:anons
6-0047
e 0009
5-5853
5 58 42
558 10
55745
5 5647
555 17
55353
55305
11 12 13 14 15 10 11 12 13 14 15 10
11-03 Flidąy 11-00
Rysunek 1-5. Program giełdowy i usługa informacyjna, które wykorzystują aplet
Wysyłanie danych
Przeglądarki sieciowe są zoptymalizowane pod względem pobierania danych. Prze-
syłają serwerowi jedynie ustaloną ilość danych, główne za pomocą formularzy. Pro-
gramy w Javie nie mają takich ograniczeń. Gdy między dwoma maszynami zostanie
nawiązane połączenie, program w Javie może przesyłać nim dane z taką samą
łatwością, z jaką je odbiera. Otwiera to wiele nowych możliwości.
Przechowywanie pliku .. -
Aplety często muszą zapamiętywać dane między kolejnymi uruchomieniami, na
przykład zapisują poziom gry, który osiągnął gracz. Apletom nieuwiarygodnionym nie
wolno zapisywać plików na dysku lokalnym, ale mogą przechowywać dane na serwerze,
z którym współpracują. Aplet otwiera po prostu połączenie sieciowe z węzłem, z którego
pochodzi, i wysyła do niego dane. Węzeł może przyjąć dane przez interfejs CGI, ftp,
SOAP, specyficzny serwer lub serwlet bądź też w jakiś inny sposób.
Co potrafi program sieciowy?
Masowe obliczenia równoległe
Aplety Javy S3 bezpieczne, więc poszczególni użytkownicy spokojnie mogą udo-
stępnić niewykorzystane cykle swojego procesora projektom naukowym, które po-
trzebują maszyn o masowym przetwarzaniu równoległym. Kiedy część obliczeń do-
biega końca, program nawiązuje połączenie sieciowe z węzłem, który zlecił oblicze-
nia, i dodaje swoje wyniki do zbieranych danych.
Do tej pory prace badawcze, takie jak poszukiwanie inteligentnych form życia we
wszechświecie w ramach projektu SETI@home* oraz program-włamywacz RC5/DES
projektu distributed.net**, opierały się na oryginalnym kodzie programów napisa-
nych w C. Te programy trzeba było oddzielnie ściągać i instalować, przeważnie dla-
tego, że wirtualna maszyna Javy była zbyt powolna i znacząco przegrywała w tych
obliczeniach mocno obciążających procesory. Natomiast aplety Javy, wykonujące tę
samą pracę, umożliwiają wygodniejsze włączenie się w nią. Mając wersję apletu
Javy, użytkownik musiałby jedynie wskazać przeglądarce stronę zawierającą aplet,
który rozwiązałby zagadnienie.
W projekcie Charlotte, realizowanym przez Uniwersytet w Nowym Jorku i stan Ari-
zona, jest obecnie opracowywana uniwersalna architektura do wykorzystywania ap-
letów Javy przy wspomaganiu obliczeń równoległych. U jej podstaw leży założenie,
że aplety w Javie mają działać na wielu różnych klientach połączonych poprzez Inter-
net. Rysunek 1-6 przedstawia przykładowy aplet projektu Charlotte, który względnie
szybko oblicza zbiór Mandelbrota, wykorzystując wiele różnych procesorów.
(Ł EktMUft hone paw NeUcape
Rysunek 1-6. Równoległe obliczanie zbioru Mandelbrota przez wiele przeglądarek
http://ietiathome.ssl.berkeley.edu/
http://umnv.distributed.net/
10___________________________________Rozdział 1: Dlaczego Java sieciowa?
Inteligentne formularze
AWT Javy posiada wszystkie składniki interfejsu użytkownika dostępne w formula-
rzach HTML, w tym pola tekstowe, pola wyboru, przełączniki, listy rozwijane, przyci-
ski i kilka innych. Zatem w Javie możesz utworzyć formularze o takiej samej funkcjonal-
ności, jaką charakteryzują się typowe formularze HTML. Mogą one wykorzystywać
połączenia sieciowe do odsyłania danych serwerowi tak samo, jak robi to przeglądarka.
Jednak aplety Javy są programami w pełnym tego słowa znaczeniu, a nie zwykłymi
wyświetlaczami danych, więc takie formularze mogą być prawdziwie interaktywne
i natychmiast odpowiadać użytkownikowi. Na przykład formularz zamówienia
może podawać zmieniającą się sumę całkowitą z uwzględnieniem podatku i kosztów
transportu. Za każdym razem, gdy użytkownik zaznacza nową pozycję do kupie-
nia, aplet uaktualnia końcową sumę do zapłacenia. Typowy formularz HTML mu-
siałby wysłać dane z powrotem do serwera, który obliczyłby sumę końcową
i przesłał uaktualnioną wersję formularza - taka procedura jest wolniejsza i wymaga
więcej pracy ze strony serwera.
Co więcej aplet Javy może skontrolować poprawność danych wejściowych. Na
przykład aplet może ostrzegać użytkownika, że nie może on zamówić półtora opa-
kowania żelków, gdyż dostarczane są tylko całe pudełka. Gdy użytkownik wypełni
już formularz, aplet wyśle dane serwerowi poprzez nowe połączenie sieciowe. Może
skontaktować się z tym samym programem CGI, który przetwarza dane wejściowe
formularza HTML lub z wydajniejszym serwerem specjalnym. W obu przypadkach
komunikuje się za pośrednictwem Internetu.
Oddziaływanie typu "każdy z każdym"
Wszystkie poprzednie przykłady były zgodne z modelem klient-serwer. Jednakże
aplikacje Javy mogą także komunikować się nawzajem poprzez Internet, co otwiera
wiele nowych możliwości grupom aplikacji. Również aplety Javy mogą komuniko-
wać się ze sobą, ale ze względów bezpieczeństwa muszą robić to poprzez pośred-
niczący program proxy, działający na serwerze, z którego zostały załadowane. (Java
sprawia, że napisanie takiego programu proxy jest względnie łatwe).
Gry
Połącz łatwość dodawania działania sieciowego do własnych programów z potężną
grafiką Javy, a otrzymasz receptę na rzeczywiście budzące podziw gry dla wielu
użytkowników. Tak właśnie powstały: Backgammon, Battleship, Othello, Go,
Mahjongg, Pong, Charades, Bridge, a nawet rozbierany poker. Rysunek 1-7 przed-
stawia trwające rozdanie gry Hearts (serduszka) dla czterech graczy w Yahoo! Gry
są realizowane za pomocą interfejsu apletów. Gniazda sieciowe wysyłają gry do cen-
tralnego serwera YahoolYahoo!, który przekazuje je wszystkim uczestnikom
11
labie: 2 - Hotl kaiaiaar,
GAMES
:oo? Info! SKoSfimes!
iobol2 Pti O
obot!
Pis 13
i*?! robol3
|Pn| RIGHT
f karajaon Pts: 12
. 1-:U "" robot! has joned Ihe tatfe
f eo 2u* n" robot2 has pned Ihe latne.
"""""li *" 'obot3 has pned Ihe tabre.
H[R|iobot3 'prawią, t!
Rysunek 1-7. Sieciowa gra w serduszka wykorzystuje aplet Javy z witryny http://games.yahoo.com/games/
Pogawędki
Java umożliwia ci zorganizowanie prywatnego lub publicznego pokoju pogawędek.
Tekst, który jest wpisywany w jednym z apletów, może być literalnie przekazywany
do innych apletów na świecie. Rysunek 1-8 prezentuje podstawowy aplet pogawę-
dek, a konkretnie w Yahoo! Co ciekawsze, jeśli dodasz do apletu sztalugę z podsta-
wową umiejętnością rysowania, będziesz mógł przeznaczyć oprogramowanie typu
whiteboard do wspólnego użytkowania w wielu miejscach.
Gdy tylko przeglądarki zaczną obsługiwać wersję 2.0 APIJFM (ang. ]ava Media Frame-
work - struktura nośników Javy), pisanie sieciowych aplikaq'i telefonicznych lub do-
dawanie takiej aplikacji do istniejącego apletu stanie się banalnie łatwe. Do innych
aplikacji tego typu zaliczają się specyficzne klienty dla MUD (ang. MultiUser Dungeons
- wielodostępne gry w lochach) i MOO (ang. MultiUser Object-Oriented - wielodostęp-
ne gry obiektowe). Z powodzeniem mogłyby one wykorzystywać możliwości graficz-
ne Jaw, aby załączyć zdjęcia ludzi, co od lat pozostaje naszym marzeniem.
Rozdział 1: Dlaczego Java sieciowa?
Yahoo! Chał - Netscape
File ?dit View ?o
t Back :>.:.;.--' Reload Home Seatch Netscape !.- SecurJy Shop
:; ^~ Bookmatks .^, Location: jhttp://'chatyahoo.com/?room=Comp^3a+Progfarnming
Whats Related
rę i n pro^rarnm!nq:1(rickyour l a ng u ag e:
bohs204U : \s listening to basket case. mmm
ufophilip : DOES ANYONE HAVE ABODE AFTER EFFECTS? l need someone to answer a
simple question!M Type 123 if you have it or have used tt
erahu!69 buits a niove
truezin : :">
angela_the_whore :viżsyńi, shi-M", ;>;3 : ;.<.: ;. : :
craigotron : User: truezin your nów (gnored, have a nice clay
never Ji: i am listening to dirt
erahu!69 Hey roorn you ca n treate cuslom emolioni ey editiny Ihe 8rnote_usr dat n'e
never_fl : song called dirt
Chatters
_
craig_capel
craigpiron
Q} deskjiy^ze:
erahu!69
iDoctrtentDone
,. __.
ostrcenler-c<,m
Cl...:
Rysunek 1-8. Pogawędka sieciowa wykorzystująca apiet Javy
Oprogramowanie typu whiteboard
Programy w Javie nie są ograniczone jedynie do wysyłania tekstu i danych poprzez
sieć. Mogą także przesyłać grafikę. Wielu programistów opracowało oprogramowa-
nie whiteboard, które umożliwia użytkownikom będącym w różnych miejscach, ryso-
wanie na swoich komputerach. W większości interfejsy użytkownika dla tych prog-
ramów wyglądają jak zwykły program do rysowania z obszarem sztalugi, wyposa-
żony w pióra, narzędzia tekstowe, gumkę, pędzel i inne przybory. Jeśli do zwykłego
programu rysującego dodamy działanie w sieci, to w tym samym czasie nad jednym
rysunkiem będzie mogło pracować kilka osób. Rysunek końcowy nie będzie tak profe-
sjonalny jak wspólne dzieła Warhola i Basquiata, ale za to współtwórcy nie muszą
zbierać się w nowojorskim lofcie. Rysunek 1-9 przedstawia kilka okien z sesji
programu WebCollab z rodziny alphaWorks firmy IBM.* WebCollab pozwala użyt-
kownikom, będącym w różnych miejscach, na wyświetlanie i opisywanie slajdów w
czasie telekonferencji. Jeden z uczestników działa na centralnym serwerze WebCol-
lab, pozostałe komputery są z nim połączone, a uczestnicy konferencji korzystają z
apletu Javy załadowanego do ich przeglądarek WWW.
* http://wunv.alphaWorks.ibm.com/tech/webcollab
Co potrafi program sieciowy?
13
l Enter the fliename forthe Image
esPerLine " 348
ettelnfo " l
OK Osncel
WebCollab
locaihost Bidę
apter 1?)
Mikę. is this a c
l Mikę, is thls a good picture for Chapter 1?
^/airing Apptet Wndow
Rysunek 1-9.WebCollab ' -'"l;..;
Serwery
Aplikacje w Javie mogą oczekiwać na połączenia sieciowe i na nie odpowiadać.
Dzięki temu w Javie jest możliwe zaimplementowanie serwerów. Obie firmy - Sun
i W3C - napisały serwery WWW w Javie, które zostały tak zaprojektowane, aby
funkcjonalnością i szybkością dorównywać serwerom napisanym w C. W Javie po-
wstało także wiele innych rodzajów serwerów, w tym serwery IRC, NFS, plików,
drukowania, pocztowe, katalogów, DNS, FTP, TFTP oraz inne. Niemal każdy stan-
dardowy serwer TCP lub UDP, który przyjdzie ci na myśl, najprawdopodobniej zo-
stał przeniesiony do Javy.
Co ciekawsze, możesz napisać własne serwery, spełniające twoje specyficzne po-
trzeby. Na przykład, możesz napisać serwer, który będzie zapamiętywał stan apletu
twojej gry i posiadał dokładnie takie funkq'e, jakie graczom są potrzebne do zapa-
miętywania i odtwarzania ich partii, i tylko te. Normalnie aplety komunikują się tyl-
ko z węzłem sieci, z którego zostały ściągnięte, więc specjalny serwer mógłby po-
średniczyć między dwoma apletami (lub większą ich liczbą), które muszą porozu-
mieć się w grze sieciowej. Taki serwer mógłby być bardzo prosty, wystarczy, że po-
starzałby wszystkim apletom, z którymi byłby połączony, co jeden aplet chce im
przekazać. Wspomniany już projekt Charlotte wykorzystuje specjalny serwer napi-
sany w Javie do gromadzenia i rozpowszechniania obliczeń wykonanych przez
Poszczególne klienty. Z kolei WebCollab używa specyficznego serwera napisanego
w Javie do zbierania komentarzy, notatek i slajdów od uczestników telekonferencji i
Przekazywania ich wszystkim pozostałym uczestnikom. Zapamiętuje notatki także
na serwerze centralnym. Stosuje kombinację zwykłych protokołów HTTP i FTP
z własnym protokołem WebCollab.
16
Rozdział 1: Dlaczego Java sieciowa?
Aplety mogą zapisywać aktualny stan, w miarę jak użytkownik przechodzi ze stro-
ny na stronę, przez co znacznie ułatwiają budowanie koszyków. Gdy użytkownik
skończy zakupy, aplet wysyła dane do serwera poprzez sieć. Rysunek 1-10 przedsta-
wia jeden z takich koszy, używany w witrynie Wirtualnego sklepu. Aby kupić
zabawkę, użytkownik klika łącze obok wózka na zakupy.
;& Wirtualny Sklep - Netscape
?te ?d* Yiew ?o Eomronicatof Help
i! Back i\,!-.-...;-, Refcwd Home
i ,y " Bookfflarks
Ssarch Neiscape Piint Secuity Shop
, Location:]hltp://www.ws
^5l a9cSO
j-J ^"
' Mif łUSJffl | Jtompjlery I muiykj
iulip i^
Pluszowy Donald
Wielkość 610 mm
cena: 123.00 PLN
--'* zobac
Układanki piankowe Inr
Kubuś Puchatek
_ ______ Gry planszowe i wojenne
Zagubiona Małpka < Chilla Chilla Pojazdy
j Teletubbies
i wesoła gromadka
l cena: 69,00 PLN
Samolot z ludzikiem
cei3' 36.00 PLN
i Zabawne pojazdy
| klocki dla
\ najmłodszych
jcs-iS 74.00 PLN
IWader-Woźniak
l Loader
| ce-ii 16.00 PLN
i Królewna Rosalina -
! zaczyna sią bas' J
Rysunek 1-10. Aplet koszyka na zakupy
Jednak nawet to jest zbyt niewygodne i zbyt kosztowne przy drobnych wydatkach
rzędu kilku dolarów lub mniej. Nikt nie ma ochoty na codzienne wypełnianie for-
mularza, w którym musi podać nazwisko, adres, adres fakturowania, numer karty
kredytowej i datę jej ważności jedynie po to, by zapłacić 50 centów za możliwość
przeczytania codziennej gazety "Daily Planet". Wyobraź sobie, jak łatwe byłoby
przeprowadzenie tego rodzaju transakcji w Javie. Użytkownik klika łącze do jakiejś
informacji. Serwer ściąga mały aplet, który pokazuje okno dialogowe z tekstem "Do-
stęp do informacji pod adresem http://ivww.chciiuy.com/ kosztuje 2 dolary. Czy chcesz
zapłacić?". Wtedy użytkownik może kliknąć przycisk z napisem "Tak" lub "Nie".
Jeśli wybrałby odpowiedź "Nie", to nie wszedłby do witryny. Spróbujmy sobie teraz
wyobrazić, co działoby się, gdyby użytkownik kliknął przycisk "Tak".
Aplet zawiera niewiele informacji: cenę, adres URL i sprzedawcę. Jeśli klient jest za-
interesowany przeprowadzeniem transakcji, to aplet dodaje do transakcji dane o
kupującym, prawdopodobnie nazwisko i numer konta, a następnie podpisuje
Co potrafi program sieciowy? 17
arnówienie kluczem prywatnym klienta. Potem aplet wysyła dane serwerowi po-
zez gjec Serwer przyznaje użytkownikowi dostęp do żądanych informacji, sto-
uiac standardowy model zabezpieczeń HTTP. Później podpisuje on transakcję swo-
im kluczem prywatnym i przesyła zamówienie do centralnego biura rozrachunko-
wego. Sprzedawcy mogą zaoferować gwarancję zwrotu pieniędzy lub odroczone
spłaty (Schowaj pieniądze! Żadnych opłat aż do lipca!), czyli godzą się na nieprze-
syłanie transakcji do biura rozrachunkowego przed upływem określonego czasu.
Biuro rozrachunkowe sprawdza każdą transakcję za pomocą kluczy publicznych
nabywcy i sprzedawcy oraz wprowadza ją do swojej bazy danych. Biuro może uży-
wać kart kredytowych, czeków lub elektronicznych przelewów do przekazywania
pieniędzy od nabywcy do sprzedawcy. Bardziej prawdopodobne jest, że biuro roz-
rachunkowe nie przeleje żadnych pieniędzy, dopóki całkowita suma zgromadzona
przez nabywcę lub sprzedawcę nie osiągnie pewnego minimalnego progu, przy któ-
rym koszty transakcji pozostaną niskie.
Wszystkie elementy potrzebne do takiej transakcji mogą zostać napisane w Javie.
Aplet prosi użytkownika o pozwolenie. Rozszerzenie JCE (ang. Java Cryptography
Extension - szyfrujące rozszerzenie Javy) sprawdza legalność transakcji i ją szyfruje.
Dane wędrują od klienta do sprzedawcy dzięki gniazdom, adresom URL, progra-
mom CGI, serwletom i/lub RMI. Tej metody można także użyć do komunikacji
węzła z centralnym biurem rozrachunkowym. Sam serwer WWW też może być na-
pisany w Javie, jak również baza danych i systemy księgowania w centralnym biu-
rze, albo można wykorzystać JDBC do kontaktowania się z tradycyjną bazą danych,
taką jak Informix lub Oracle.
Najtrudniejsze jest tu skonfigurowanie biura rozrachunkowego oraz pozyskanie
użytkowników i witryn, chcących w tym uczestniczyć. Duże firmy obsługujące kar-
ty kredytowe początek mają już za sobą, niemniej jednak żadna z nich jeszcze nie
wykorzystała opisanego tu schematu. W idealnym świecie nabywca i sprzedawca
mogliby korzystać z różnych banków i biur rozrachunkowych. To jednak jest pro-
blemem społecznym, a nie technicznym, i da się go rozwiązać. Możesz złożyć czek
każdego banku amerykańskiego w dowolnym innym banku amerykańskim, w któ-
rym masz konto. Obie strony transakcji nie muszą korzystać z tego samego banku
w tym samym miejscu. Firma Sun obecnie opracowuje podobny system, stanowiący
część projektu Java Wallet.
Aplikacje przyszłości
Java umożliwia pisanie wielu różnych rodzajów aplikacji, o których marzono od lat,
a które aż do teraz były nieosiągalne. Sporo z nich wymagałoby zbyt wiele mocy ob-
liczeniowej, gdy były w całości oparte na serwerach. W Javie przetwarzanie jest
przerzucone na klienta, na maszynę, z której pochodzi. Inne typy aplikacji (na
przykład mobilne agenty) wymagają maksymalnej przenośności i pewnych gwa-
rancji, że aplikacja nie zrobi niczego, co zaszkodziłoby węzłowi sieci. Choć model
zabezpieczeń w Jayie był krytykowany (i owszem, znaleziono kilka błędów), i tak
Jest o wiele doskonalszy niż wszystko to, co usiłowano zrobić dotychczas, i jest
18 Rozdział 1: Dlaczego Java sieciowa?
absolutnie niezbędny w przypadku mobilnego oprogramowania, które chcemy pi-
sać w przyszłości.
Wszędobylskie komputery
Urządzenia sieciowe nie muszą być przywiązane do konkretnego fizycznego miej-
sca, podsieci lub adresu IP. Jini jest strukturą umieszczoną ponad Javą dla łatwiej-
szego i ciągłego łączenia z siecią wszystkich rodzajów urządzeń. Na przykład, kiedy
współpracownicy spotykają się na zebraniu, to zazwyczaj przynoszą ze sobą dość
przypadkowy dobór osobistych asystentów cyfrowych, laptopów, telefonów ko-
mórkowych, pagerów oraz innych urządzeń elektronicznych. W sali konferencyjnej,
w której się zbierają, może znajdować się jeden lub dwa komputery typu PC, ewen-
tualnie Macintosh, cyfrowy rzutnik, drukarka, ekspres do kawy, głośnik, etherneto-
wy ruter i przeróżne inne przydatne narzędzia. Jeśli te urządzenia posiadają wirtu-
alną maszynę Javy i Jini, to dopóki są włączone i połączone, tworzą zaimprowizo-
waną sieć. (Przy połączeniach bezprzewodowych nawet nie muszą być połączone).
Urządzenia mogą w dowolnym momencie przyłączać się do lokalnej sieci lub opusz-
czać ją bez konieczności zmiany konfiguracji. Mogą używać jednego z telefonów ko-
mórkowych, głośnika lub rutera do połączenia się z węzłami sieci znajdującymi się
poza tą salą.
Uczestnicy konferencji bezproblemowo mogą dzielić się plikami i wymieniać dany-
mi. Ich komputery oraz inne urządzenia mogą być skonfigurowane tak, aby rozpo-
znawać się nawzajem i ufać sobie niezależnie od swojej aktualnej lokalizacji w sieci.
Zaufanie jednakże może być ograniczone tak, aby na przykład wszystkie laptopy
pracowników firmy przebywających w pokoju ufały sobie nawzajem, ale nie ufały
laptopom obecnych na spotkaniu sprzedawców. Niektóre urządzenia, takie jak dru-
karka i rzutnik cyfrowy, mogą być skonfigurowane tak, aby ufać każdemu z sali,
gdy chodzi o korzystanie z ich usług, ale nie zezwalać na wykorzystywanie się w da-
nym momencie przez więcej niż jedną osobę. Najważniejsze ze wszystkiego jest, aby
ekspres do kawy nie ufał nikomu, ale sam mógł stwierdzić, że skończył mu się zapas
kawy, i pocztą elektroniczną powiadomić obecnych w pokoju, że należy go uzu-
pełnić.
Interakcyjna telewizja
Zanim WWW przebojem podbiło świat, planowano przeznaczyć Javę na rynek de-
koderów telewizji kablowej. Pięć lat po publicznym debiucie Javy, Sun powrócił do
swoich wcześniejszych planów, ale tym razem były one bardziej ukierunkowane na
sieć. Personaljava jest okrojoną wersją dość obszernego API Javy, przydatną w deko-
derach i innych urządzeniach o ograniczonej pamięci, mocy procesora i interfejsach
użytkownika, takich jak Palm Pilot. TV API Javy ma dodanych kilka specyficznych
funkcji telewizyjnych, na przykład zmienianie kanałów umożliwia również zapis
i synchronizację obrazu i dźwięku. Chociaż Personaljava nie ma wielu rzeczy, do
których mogłeś się przyzwyczaić w pełnym JDK, ale zawiera cały zestaw klas siecio-
wych. Stacje telewizyjne mogą wstawiać aplety w strumienie danych, aby widzowie
oddziaływali na programy. Reklama farby do włosów mogłaby zawierać aplet,
CMMtecz^eszczecoś^_____________________________________J9
który pozwalałby widzowi wybrać kolor, wpisać numer karty kredytowej i wysłać
mówienie kablem modemowym w tę i z powrotem przez Internet dzięki zdalne-
u sterowaniu. Dzienniki mogłyby przeprowadzać wśród widzów głosowanie
czasie rzeczywistym i informować o jego wynikach po przerwie na reklamę. Ka-
blem modemowym mogłyby być zbierane opinie od każdego widza, a nie zaledwie
od 5000 rodzin Kowalskich.
Współpraca
Dzięki sieciowym programom typu węzeł-węzeł w Javie wiele osób może jednocze-
śnie pracować nad jednym dokumentem. Wyobraź sobie procesor słów w Javie,
który dwie osoby, być może w różnych krajach, mogą równocześnie uruchomić.
Wyobraź sobie taką interakcję, która jest możliwa, gdy podłączysz się do interneto-
wego telefonu. Na przykład dwóch astronomów mogłoby wykonywać pracę na pa-
pierze, jeden w Nowym Meksyku, a drugi w Moskwie. Rosjanin mógłby powie-
dzieć: "Myślę, że zgubiłeś górny indeks w równaniu 3.9", a następnie wpisać po-
prawkę, która równocześnie pojawiłaby się na obu ekranach. Astronom z Nowego
Meksyku mógłby powiedzieć: "Rzeczywiście, ale czy nie oznacza to, że musimy te-
raz odpowiednio zmienić rysunek 3.2?", a potem użyłby narzędzia do rysowania, by
natychmiast to zrobić. Taki rodzaj współpracy nie jest szczególnie trudny do zaim-
plementowania w Javie (procesor słów z przyzwoitym interfejsem użytkownika do
równań matematycznych jest prawdopodobnie najtrudniejszą częścią tego zadania),
ale już na początku trzeba uwzględnić wbudowanie procesora słów. Nie można wy-
korzystać tu procesora słów, który nie był zaprojektowany dla sieci.
Chwileczkę! Jeszcze coś!
Większa cześć tej książki opisuje API względnie niskiego poziomu, potrzebne do pi-
sania takich rodzajów programów, które wymieniliśmy w tym rozdziale. Niektóre
z tych programów już powstały. Inne nadal czekają na realizację. Może to właśnie ty
je napiszesz! Ten rozdział wyznaczył jedynie płaszczyznę działania dla tych, którzy
tworzą w Javie programy dla sieci. Wielką zaletą witryny wykorzystującej oprogra-
mowanie w Javie jest to, że wszystko, co sobie zamarzysz, jest już możliwe. Wysuń
pomysły, które innym nigdy nie przyjdą do głowy. Po raz pierwszy nie jesteś ograni-
czany tym, co inne firmy wbudowują w swoje przeglądarki. Jednocześnie możesz
udostępnić swoim użytkownikom zarówno dane, które chcą zobaczyć, jak i kod,
którego potrzebują do oglądania tych danych. Jeśli potrafisz to sobie wyobrazić, to
potrafisz też napisać taki kod.
V.;! "-. l';tf
. .;. -:--;-.&.
:.:.'. 'Tt... :,
: -. -i;.; ' -'.
:'.,; :.';''.'. ' '':
r,, ,-... :.:: 'f. : ." ;!'.' ''. .-' ': '.:-.
, -:-."< ' .-,,>' 'ik''-
---..*. : ;-'.; - '-:"-
" . :'. -.. :.;. - .;' ;././ , '
. / . i.. ,. .,-. -..... .... ";
.-. ,)"-. '. : ' v "=. ;.-,.,. ' <".:*'->.
. - .$*". '>'^:;X-..:>> ~9& .".' -"



2
Podstawowe pojęcia
dotyczące sieci
W tym rozdziale:
Sieci
Warstwy sieci
Protokoły IP, TCP oraz UDP
Internet
Model klient-serwer
Internetowe standardy
Ten rozdział opisuje podstawowe pojęcia związane z sieciami, które musisz zrozu-
mieć, zanim zaczniesz pisać programy sieciowe w Javie (a w zasadzie w dowolnym ję-
zyku). Przechodząc od generaliów do szczegółów, wyjaśnia, co musisz wiedzieć o sie-
ciach w ogóle, a zwłaszcza o sieciach opartych na protokołach IP i TCP/IP oraz o Inter-
necie. W tym rozdziale nie będę próbował nauczyć cię, jak połączyć komputery w sieć
za pomocą kabli czy też skonfigurować ruter. Zapoznasz się z tym, co będzie ci nie-
zbędne do pisania aplikacji komunikujących się przez Internet. Do poruszanych tu za-
gadnień należą: definicja sieci, warstwowy model TCP/IP, protokoły IP, TCP i UDP,
firewalle i serwery proxy, Internet oraz proces tworzenia internetowych standardów.
Doświadczeni mistrzowie sieciowi spokojnie mogą pominąć ten rozdział.
Sieci
SKĆ jest zbiorem komputerów i innych urządzeń, które mogą wysyłać do siebie dane
i odbierać je, mniej więcej w czasie rzeczywistym. Zazwyczaj sieć jest połączona ka-
blami, którymi wędrują bity informacji zamienione w fale elektromagnetyczne. Po-
jawiają się jednak sieci bezprzewodowe, transmitujące dane w zakresie fal podczer-
wonych lub mikrofal, a wiele transmisji długodystansowych odbywa się światłowo-
ami, które szklanymi włóknami przesyłają światło widzialne. Nie ma nic nadzwy-
czajnego w żadnym konkretnym nośniku fizycznym, który służy do transmisji
anych. Teoretycznie dane mogłyby być przesyłane przez komputery zasilane wę-
8 em, które wysyłałyby sobie sygnały dymne. Jednak w takiej sieci osiągany czas od-
powiedzi (i skutki dla środowiska) byłby dość nędzny.
22 Rozdział 2: Podstawowe pojęcia dotyczące sieci
Każda maszyna znajdująca się w sieci jest nazywana węzłem (ang. node). Większość
węzłów stanowią komputery, ale również mogą nimi być drukarki, rutery, mosty,
gatewaye, terminale i dystrybutory coca-coli. Możesz używać Javy do sprzęgania się
z maszyną do coli (w przyszłości należy się spodziewać, że pewna ważna aplikacja
dla Javy będzie zagnieżdżona w tych systemach), inaczej bowiem będziesz komuni-
kować się głównie z komputerami. Węzły, które są w pełni funkcjonalnymi kompu-
terami, nazywane są także hostami (z ang.). Terminu węzeł używamy w odniesieniu
do urządzenia w sieci, a słowem host określamy węzeł, który jest uniwersalnym
komputerem.
Każdy węzeł sieci ma swój adres, będący szeregiem identyfikujących i niepowtarzal-
nych bajtów. Możesz traktować tę grupę bajtów jako liczbę, ale generalnie nie jest
prawdą, że ta liczba bajtów w adresie oraz ich kolejność (big-endian lub little-en-
dian) odpowiada jakiejś prymitywnej danej liczbowej wpisanej w Javie. Im więcej
jest bajtów w adresie, tym więcej jest dostępnych adresów i tym więcej urządzeń
może zostać podłączonych równocześnie do sieci.
W różnych sieciach adresy są różnie przydzielane. Adresy AppleTalk są losowo
wybierane przez każdy host przy uruchamianiu sieci. Następnie, używając tych
adresów, host sprawdza, gdzie w sieci znajdują się wszelkie inne maszyny. Jeśli ja-
kaś maszyna wykorzystuje już jakiś adres, to host wybiera losowo inny, ponownie
sprawdza, czy nie on już wykorzystany, i powtarza te czynności, aż zostanie mu
przydzielony wolny adres. Adresy Ethernet są przywiązane do fizycznego sprzętu
ethernetowego. Producenci tego sprzętu używają przydzielonych im kodów produ-
cenckich, aby mieć pewność, że nie wystąpią żadne konflikty między adresami ich
sprzętu a adresami innych producentów. Każdy producent ma obowiązek upewnić
się, że nie dostarcza dwóch kart ethernetowych o takim samym adresie. Adresy in-
ternetowe są zazwyczaj przypisywane komputerowi przez odpowiadającą za niego
organizację. Z kolei adresy, które organizacja ma do dyspozycji dla swoich kom-
puterów, są jej przydzielane przez jej dostawcę usług internetowych (ISP). Dostawca
usług internetowych pobiera adresy IP od jednego z trzech regionalnych IR (ang. In-
ternet Registries - rejestry internetowe). Dla Ameryk i Afryki jest to ARIN (ang. Ame-
rican Registry for Internet Numbers - amerykański rejestr adresów internetowych pod
adresem http://wwu>. arin.net/). Natomiast adresy IP są przydzielane rejestrom przez
IANA (ang. Internet Assigned Numbers Authority - zarząd przydzielania adresów in-
ternetowych pod adresem http://www.wna.org/}.
W niektórych rodzajach sieci hosty mają również nazwy, które ułatwiają ludziom
identyfikację maszyn. W określonej chwili konkretna nazwa odnosi się do jednego
tylko adresu. Jednakże nazwy nie są na stałe związane z adresami. Mogą się zmie-
niać, podczas gdy adresy pozostają te same, a także adresy mogą ulegać zmianie
przy ustalonej nazwie. Nie jest niczym niezwykłym, że jeden adres ma kilka nazw.
Jest też możliwe, choć znacznie mniej popularne, aby jedna nazwa odnosiła się do
kilku różnych adresów.
Wszystkie nowoczesne sieci komputerowe są sieciami wymiany (komutacji) pakietów.
To oznacza, że dane podróżujące siecią są podzielone na kawałki zwane pakietami,
a każdy pakiet jest obsługiwany oddzielnie. Taki pakiet zawiera informacje o tym,
yifaiytwysieci___________________________________________23
i dokąd go wysiał. Największą zaletą dzielenia danych na indywidualnie adreso-
ane pakiety jest to, że pakiety z wielu wędrujących przesyłek mogą podróżować
Wj m kablem, co znacznie obniża koszt zbudowania sieci, gdyż komputery mogą
' vspólnie korzystać z tego samego kabla, nie przeszkadzając sobie. (Inaczej jest, gdy
^ rzeprowadzasz lokalną rozmowę telefoniczną w obrębie jednej centrali. Kabel od
twojego aparatu telefonicznego do telefonu twojego rozmówcy jest zarezerwowany
wyłącznie dla waszej rozmowy. Gdy wszystkie kable telefoniczne są obciążone, co
czasami zdarza się w sytuacjach krytycznych lub w czasie wakacji, wtedy po pod-
niesieniu słuchawki nie usłyszy się sygnału gotowości sieci do wybierania numeru.
Jeśli pozostanie się na linii, to być może usłyszy się ten sygnał, gdy linia się zwolni.
W niektórych państwach o sieci telekomunikacyjnej znacznie gorszej niż w Stanach
Zjednoczonych, półgodzinne lub dłuższe oczekiwanie na sygnał gotowości nie jest
niczym niezwykłym). Kolejną zaletą pakietów jest możliwość wykorzystania sumy
kontrolnej do sprawdzania, czy pakiet nie został uszkodzony w czasie przesyłania.
W tym obrazie nadal brakuje nam jednego ważnego elementu: pewnego wyobra-
żenia o tym, co komputery muszą mówić, aby przesyłać dane tam i z powrotem. To
protokół jest zestawem reguł dokładnie określających, jak komputery się komuni-
kują, zawierających format adresu, sposób dzielenia danych na pakiety itp. Istnieje
wiele różnych protokołów, definiujących rozmaite aspekty komunikacji sieciowej.
Na przykład HTTP (ang. Hypertezt Transfer Protocol - protokół przesyłania hipertek-
stu) wyznacza sposób komunikowania się przeglądarek i serwerów sieciowych, a na
drugim końcu tej skali znajduje standard IEEE 802.3, który (między innymi) definiu-
je protokół kodowania bitów w postaci sygnałów elektrycznych dla konkretnego ro-
dzaju kabla. Dzięki standardowi otwartego publicznego protokołu możliwe jest ko-
munikowanie się oprogramowania i sprzętu od różnych sprzedawców, więc twoja
przeglądarka nie musi się martwić, czy dany serwer jest uniksową stacją roboczą,
maszyną z systemem Windows, czy Macintoshem, ponieważ i serwer, i przeglądar-
ka posługują się tym samym protokołem niezależnie od platformy.
Warstwy sieci
Przesyłanie danych przez sieć jest skomplikowaną operacją, która musi zostać pre-
cyzyjnie dopasowana do parametrów fizycznych sieci, a także do logicznej struktu-
ry wysyłanych danych. Oprogramowanie, które przesyła dane siecią, musi wie-
dzieć, jak uniknąć kolizji pakietów, jak przekształcać dane cyfrowe na sygnały ana-
logowe, jak wykrywać i poprawiać błędy, jak przekierowywać pakiety od jednego
węzła do drugiego itd. Cały proces staje się jeszcze bardziej skomplikowany, gdy
weźmie się pod uwagę konieczność obsługiwania wielu systemów operacyjnych
i różnorodnego okablowania sieciowego.
Aby poradzić sobie z tą złożonością i większą jej część ukryć przed twórcami aplika-
cji i użytkownikami końcowymi, rozdzielono różne aspekty komunikacji sieciowej
na kilka warstw. Każda z nich reprezentuje inny poziom abstrakcji: od sprzętu fi-
zycznego (to znaczy kabli i elektryczności) do transmitowanych informacji. Każda
warstwa ma ściśle wyznaczoną funkcję. Na przykład jedna warstwa może być odpo-
24
Rozdział 2: Podstawowe pojęcia dotyczące sieci
wiedzialna za przekierowywanie pakietów, a warstwa powyżej za wykrywanie
uszkodzonych pakietów i żądanie ich ponownej transmisji. Teoretycznie każda war-
stwa komunikuje się tylko z warstwą leżącą bezpośrednio pod i nad nią. Dzięki po-
działowi sieci na warstwy możesz zmodyfikować lub nawet zastąpić jakąś warstwę,
nie wpływając na inne, jeśli tylko interfejs między warstwami pozostanie taki sam.
Istnieje kilka różnych modeli warstwowych, a każdy z nich został skonstruowany
tak, by odpowiadać potrzebom konkretnego typu sieci. W tej książce korzystam ze
standardowego czterowarstwowego modelu TCP/IP, odpowiedniego dla Internetu
(patrz rysunek 2-1). W tym modelu aplikacje, takie jak Netscape Navigator i Eudora,
działają w warstwie aplikacji i komunikują się tylko z warstwą transportową. War-
stwa transportowa porozumiewa się z warstwą aplikacji i warstwą internetową.
Z kolei warstwa internetową komunikuje się tylko z warstwą węzeł-sieć i z warstwą
transportową, a nigdy bezpośrednio z warstwą aplikacji. Warstwa węzeł-sieć prze-
nosi dane kablami, światłowodami lub za pomocą innych nośników do warstwy
węzeł-sieć systemu zdalnego, gdzie następnie te dane są przekazywane do wyż-
szych warstw w tym systemie, aż osiągną poziom aplikacji.
warstwa aplikacji
warstwa transportowa (TCP.UDP)
\vs/c+\vg intpptnw? M1-^
lyiiyiiiyitóiljiiiiiiii^MIs
_^ ścieżka logiczna ^
warstwa aplikacji
warstwa transportowa (TCP.UDP)
warstwa internetową (IP)
lSieć (Ethernet. Locaf^pPDDi M.)
Rysunek 2-1. Warstwy sieci
Na przykład wtedy, gdy przeglądarka wysyła do serwera WWW żądanie otrzyma-
nia strony, komunikuje się jedynie z warstwą transportową lokalnej maszyny klien-
ta. Warstwa transportowa dzieli żądanie na segmenty TCP, dodaje do danych pew-
ne numery sekwencji i sumy kontrolne, a potem przekazuje żądanie lokalnej war-
stwie internetowej. Warstwa internetową dzieli segmenty na datagramy IP o roz-
miarze odpowiednim dla lokalnej sieci i przekazuje warstwie węzeł-sieć, aby
przeprowadziła transmisję kablem. Warstwa węzeł-sieć koduje dane cyfrowe w po-
staci sygnałów analogowych, odpowiednich dla konkretnego nośnika fizycznego,
i wysyła żądanie kablem, z którego zostanie ono odczytane przez warstwę węzeł-sieć
systemu zdalnego, do którego było adresowane.
Warstwa węzeł-sieć systemu zdalnego dekoduje sygnały analogowe, przekształcając
je w dane cyfrowe, następnie tak uzyskane datagramy IP przekazuje warstwie inter-
netowej serwera. Warstwa internetową wykonuje kilka prostych testów, aby spraw-
dzić, czy datagramy IP nie zostały uszkodzone, łączy je, jeśli były podzielone na
fragmenty, i przekazuje je warstwie transportowej serwera. Warstwa transportowa
serwera kontroluje, czy dotarły wszystkie dane i żąda ponownej transmisji bra-
kujących lub uszkodzonych fragmentów. (To żądanie wraca przez warstwy interne-
tową i węzeł-sieć serwera, dociera do systemu klienta, gdzie wspina się do warstwy
s
Warswysied__________________________________________25
nsportowej klienta, która jeszcze raz transmituje brakujące dane przez te war-
Warstwa aplikacji nie ma o tym wszystkim żadnego pojęcia). Gdy datagramy
\ladajace się na całe żądanie lub jego część zostaną odebrane przez warstwę trans-
ortową serwera, ta łączy je w strumień i przekazuje go serwerowi WWW
działającemu w warstwie aplikacji serwera. Serwer odpowiada na żądanie i wysyła
dpowiedź przez warstwy serwera drogą w dół, by została ona odesłana poprzez
Internet i dostarczona klientowi WWW.
lak możesz się domyślić, w rzeczywistości na tę operację składa się jeszcze więcej
szczegółów. Warstwa węzeł-sieć jest, jak do tej pory, najbardziej złożona i rozmyśl-
nie była ukryta. Na przykład jest całkiem możliwe, aby dane przesyłane Internetem,
zanim dotrą do celu, były przekazywane przez rozmaite rutery i ich warstwy. Jed-
nak przez 90% czasu twój kod w Javie będzie działał w warstwie aplikacji i kontakto-
wał się tylko z warstwą transportową. Pozostałe 10% czasu spędzisz w warstwie
transportowej, kontaktując się z warstwą aplikacji oraz internetową. Złożoność war-
stwy węzeł-sieć jest przed tobą ukryta - na rym właśnie polega model warstwowy.
UWAGA Jeśli czytałeś literaturę na temat sieci, to prawdopodobnie zetknąłeś się z alternatyw-
nym modelem siedmiowarstwowym zwanym modelem odniesienia OSI (ang. Open Systems
Interconnection - połączenie systemów otwartych). Dla programów sieciowych w Javie model
OSI jest nadmiarowy. Największa różnica między modelem OSI a modelem TCP/IP prezento-
wanym w tej książce polega na tym, że warstwa węzeł-sieć jest w nim podzielona na warstwę
łączenia danych i fizyczną, a między warstwą aplikacji i transportową występują jeszcze war-
stwy prezentacji i sesji. Model OSI jest ogólniejszy i lepiej odpowiada sieciom innego typu niż
TCP/IP, przeważnie jednak jest zbyt złożony. W każdym razie klasy sieciowe Javy działają tyl-
ko w sieciach TCP/IP, zawsze w warstwie aplikacji i transportowej, tak więc gdybyśmy nawet
zastosowali ru bardziej skomplikowany model OSI, to i tak niczego byśmy nie zyskali.
Warstwie aplikacji wydaje się, że komunikuje się bezpośrednio z warstwą aplikacji
drugiego systemu, gdyż sieć tworzy między nimi ścieżkę logiczną. Łatwiej będzie to
zrozumieć, gdy przyrówna się ścieżkę logiczną do pogawędki IRC. Większość ucze-
stników sesji IRC powiedziałaby, iż rozmawia z inną osobą. Jeśli naprawdę byś ich
przycisnął, przyznaliby, że rozmawiali z komputerem (w rzeczywistości z warstwą
aplikacji), który porozumiewał się z komputerem tej drugiej osoby, a ten dopiero ko-
munikował się z tamtą osobą. Wszystko, co ukrywa się pod jakąś warstwą, jest w re-
zultacie niewidoczne i właśnie tak powinno być. Omówmy każdą z tych warstw
dokładniej.
;.>
Warstwa węzeł-sieć
Jako programista Javy znajdujesz się na dość wysokiej pozycji w sieciowym łańcuchu
pokarmowym. Musi się sporo wydarzyć, abyś został wykryty. W standardowym mo-
delu odniesienia dla internetów opartych na protokole IP (jedynym rodzaju sieci, któ-
ry Java tak naprawdę rozumie) ukryte części sieci należą do warstwy węzeł-sieć (zwa-
nej także warstwą łącza, warstwą łączenia danych lub warstwą interfejsu sieci). Defi-
niuje ona, jak konkretny interfejs sieciowy, taki jak karta ethernetowa czy łącze PPP,
^ysyła datagramy IP fizycznym łączem do sieci lokalnej i w świat.
26 Rozdział 2: Podstawowe pojęcia dotyczące sieci
Część tej warstwy, złożona ze sprzętu zastosowanego do połączenia różnych kom-
puterów (kable, światłowody, przekaźniki mikrofalowe lub sygnały dymne), jest
czasami nazywana fizyczną warstwą sieci. Jako programista Javy nie musisz mar-
twić się o tę warstwę dopóty, dopóki coś się nie zepsuje - wypadną wtyczki z tylnej
części obudowy twojego komputera lub ktoś wbije motykę w linię T-1 między tobą
a resztą świata. Innymi słowy, Java nigdy nie widzi warstwy fizycznej.
Do komunikacji między komputerami nie wystarczy rozciągnięcie między nimi ka-
bli i wysyłanie sygnałów elektrycznych w tę i z powrotem. Komputery muszą
przyjąć wspólny standard interpretowania tych sygnałów. Pierwszym krokiem jest
określenie, jak pakiety elektryczności lub światła albo dymne są odwzorowywane
w bity i bajty danych. Warstwa fizyczna jest analogowa, a bity i bajty są cyfrowe,
więc niezbędna jest konwersja cyfrowo-analogowa po stronie wysyłającej oraz ana-
logowo-cyfrowa po stronie odbierającej.
Wszystkie rzeczywiste sygnały analogowe mają zakłócenia, zatem w metodę zamia-
ny danych na sygnały elektryczne trzeba wbudować jakiś sposób poprawiania
błędów oraz zapewnienie pewną nadmiarowośći danych. Robi się to w warstwie
łączenia danych. Najpopularniejszą warstwą łącza jest Ethernet, do innych należą
TokenRing i LocalTalk. Konkretna warstwa łącza wymaga konkretnego sprzętu. Na
przykład karty eternetowe nie będą się komunikować z siecią TokenRing. Specjalne
urządzenia, zwane gatewayami, przekształcają informację z jednego typu warstwy
łącza, powiedzmy Ethernetu, na inny, taki jak LocalTalk. Ciebie - programisty jawo-
wego - warstwa łącza bezpośrednio nie interesuje. Czasami jednak możesz zopty-
malizować dane wysyłane w warstwie aplikacji tak, aby pasowały do oryginalnego
rozmiaru pakietów konkretnej warstwy łącza, co ma pewien wpływ na wydajność.
Przypomina to dostosowanie zapisów i odczytów dysku do oryginalnego rozmiaru
bloku na dysku. Niezależnie od tego, który rozmiar wybierzesz, program będzie
nadal działał, ale przy niektórych rozmiarach działa on wydajniej niż przy innych,
a to, które rozmiary będą właściwe, zależy od rodzaju komputera.
Warstwa internetowa
Następną warstwą sieci i pierwszą, która dotyczy ciebie bezpośrednio, jest warstwa
internetowa. W modelu OSI przyjęło się stosować ogólniejszy termin - zuarstica sie-
ciowa. Protokół warstwy sieciowej odpowiada za sposób, w jaki sposób bit}' i bajty
danych są porządkowane w większe grupy, zwane pakietami, oraz za schemat adre-
sowania, w którym różne maszyny mogą się odnaleźć. Protokół Internetu (IP) jest
najszerzej na świecie stosowanym protokołem warstwy sieciowej i jedynym proto-
kołem sieciowym rozumianym przez Javę. IP jest praktycznie głównym tematem tej
książki. Drugim co do popularności na świecie jest protokół IPX wykorzystywany
przeważnie na maszynach sieci NetWare. Na Macintoshach najczęściej stosowany
jest protokół AppleTalk. NetBEUI jest protokołem firmy Microsoft używanym
w systemie Windows for Workgroups i w systemie Windows NT. Każdy protokół
warstwy sieciowej jest niezależny od niższych warstw. AppleTalk, IP, IPX oraz Net-
BEUI można zastosować w sieci Ethernet, TokenRing i innych sieciach protokołu
warstwy łącza, z których każda może mieć różne rodzaje warstw fizycznych.
__________________________________ 27
przesyłane warstwą internetową w pakietach zwanych datagramami. Każdy
am IP składa się z nagłówka zawierającego od 20 do 60 bitów i z ładunku za-
aiącego do 65 515 bajtów danych. (W praktyce większość datagramów IP jest
^ nie mniejsza i zawiera od kilku tuzinów bajtów do ośmiu kilobajtów lub nieco
z"3 -j Nagłówek każdego datagramu IP zawiera trzynaście elementów w nastę-
pującej kolejności:
4 bity numeru wersji
Dla aktualnego protokołu IP zawsze jest to 0100 (dziesiętnie 4); zostanie zmienio-
ne na 0110 (dziesiętnie 6) dla IPv6, ale w protokole IPv6 zostanie też zmieniony
cały format nagłówka.
4 bity długości nagłówka
Liczba całkowita bez znaku z zakresu od O do 16, określająca liczbę 4-bajtowych
słów w nagłówku. Maksymalną wartością pola długości nagłówka jest 1111 (dzie-
siętnie 15), więc nagłówek IP może mieć co najwyżej długość 60 bajtów.
1 bajt typu usługi
Trzybitowe pole poprzedzające, które przestało już być używane, 4 bity rodzaju
usługi (minimalne opóźnienie, maksymalna przepustowość, maksymalna nieza-
wodność, minimalny koszt) oraz bit 0. Nie wszystkie typy usług są z tym zgodne.
Wiele komputerów i ruterów po prostu ignoruje te bity.
2 bajty długości datagramu
Liczba całkowita bez znaku, określająca całkowitą długość datagramu, z uwzględ-
nieniem nagłówka i ładunku.
2 bajty numeru identyfikacyjnego
Niepowtarzalny identyfikator każdego datagramu wysyłanego przez węzeł,
umożliwia wykrycie i odrzucenie zdublowanych datagramów.
3 bity flag
Pierwszym bitem jest 0; drugim bitem jest O, jeśli datagram może być podzielony,
a l, jeżeli nie może; trzecim bitem jest O, jeśli jest to ostatni fragment datagramu,
a l, jeżeli są jeszcze jakieś fragmenty.
13 bitów przesunięcia
W przypadku, gdy oryginalny datagram IP zostanie podzielony na wiele frag-
mentów, wyznacza pozycję danego fragmentu w oryginalnym datagramie.
l bajt czasu trwania (TTL)
Liczba węzłów, przez które datagram może przejść, zanim zostanie odrzucony;
stosowany w celu uniknięcia niekończących się pętli.
1 bajt protokołu
Sześć dla TCP, 17 dla UDP, któraś inna z liczb od O do 255 dla każdego z ponad
setki rozmaitych protokołów (niektóre mało znane); pełną listę znajdziesz pod
adresem http://www.isi.edu/in-notes/iana/assignments/protocol-numbers.
2 bajty sumy kontrolnej nagłówka
Suma kontrolna tylko dla nagłówka (nie dla całego datagramu) obliczona na
podstawie 16-bitowej sumy dopełniającej.
28
Rozdział 2: Podstawowe pojęcia dotyczące sieci
4 bajty adresu nadawcy
Adres IP węzła wysyłającego datagram.
4 bajty adresu odbiorcy
Adres IP węzła odbierającego datagram.
Poza tym nagłówek datagramu IP może zawierać od O do 40 bajtów informacji opcjo-
nalnych, wykorzystywanych do zabezpieczania, przekierowywania rekordów, da-
towania i wykonywania innych funkcji, które nie są obsługiwane w Javie. Tutaj nie
będziemy jednak omawiać tego zagadnienia. Zainteresowanych czytelników odsyłam
po szczegóły do pierwszego tomu książki W. Richarda Stevensa Biblia TCP/IP (Wy-
dawnictwo RM, 1998). Rysunek 2-2 przedstawia ilościową strukturę tych różnych
elementów datagramu IP. Wszystkie bity i bajty są typu big-endian, czyli od najbar-
dziej do najmniej znaczącego, od lewej do prawej.
O
8
12
16
31
wersja długość nagłówka typ usługi długość datagramu
identyfikator flagi przesuniecie fragmentu
czas trwania (TTL) protokół suma kontrolna nagłówka
adres nadawcy
adres odbiorcy
opcje
dane
Rysunek 2-2. Struktura datagramu w protokole IPv4
Warstwa transportowa
Datagramy w formie podstawowej mają kilka wad. Przede wszystkim nie ma żadnej
gwarancji, że zostaną dostarczone. Poza tym, jeśli nawet dotrą, mogą zostać po drodze
uszkodzone. Suma kontrolna nagłówka pozwala stwierdzić jedynie uszkodzenia w
obrębie samego nagłówka, a nie w porcji danych zawartej w datagramie. Wreszcie, je-
żeli datagramy dotrą bez uszkodzeń, to niekoniecznie w takiej kolejności, w jakiej zo-
stały wysłane. Poszczególne datagramy mogą poruszać się różnymi drogami od
nadawcy do odbiorcy. Tak więc sam fakt, że datagram A został wysłany przed data-
gramem B, nie gwarantuje jeszcze, że datagram A dotrze przed datagramem B.
p^okotylPj^32^________________________________
twa transportowa odpowiada za to, aby pakiety były odbierane w tej samej ko-
. ' ri w jakiej zostały wysłane, i aby żaden z nich nie został uszkodzony ani zagu-
jeśli pakiet zaginie, warstwa transportowa może poprosić nadawcę o jego po-
na transmisję. W rym celu do każdego datagramu w sieciach IP jest wstawiany
" datkowy nagłówek, zawierający więcej informacji. Dla tego poziomu istnieją dwa
odstawowe protokoły. Pierwszym jest TCP (ang. Transmission Control Protocol - pro-
F kół sterowania transmisją), wysoce uniwersalny protokół umożliwiający ponowną
transmisję zgubionych lub uszkodzonych danych oraz dostarczenie bajtów w kolej-
ości, w jakiej zostały wysłane. Drugi protokół, UDP (ang. User Datagram Protocol -
rotokół datagramów użytkownika), pozwala odbiorcy wykryć uszkodzone pakie-
ty ale nie gwarantuje, że pakiety zostaną dostarczone we właściwej kolejności (ani
że w ogóle zostaną dostarczone). Natomiast UDP jest zazwyczaj znacznie szybszy
niż TCP. TCP jest nazywany niezawodnym protokołem, a UDP zawodnym. Dalej prze-
konasz się, że protokoły zawodne są znacznie przydatniejsze niż początkowo
mogłoby się wydawać.
Warstwa aplikacji
Warstwa, która dostarcza dane użytkownikowi, jest nazywana warstwą aplikacji.
Trzy niższe warstwy pracują wspólnie, aby określić, jak dane będą przekazywane
od jednego komputera do drugiego. Warstwa aplikacji decyduje, co należy zrobić
z danymi, gdy już zostaną przesłane. Na przykład dzięki protokołowi aplikacji, ta-
kiemu jak HTTP (dla sieci WWW), twoja przeglądarka wie, że ma wyświetlić grafik
w postaci obrazków, a nie długich strumieni liczb. Warstwa aplikacji jest miejscem,
w którym spędza czas większość sieciowych części twoich programów. Istnieje cała
literowa zupa z nazwami protokołów warstwy aplikacji. Oprócz HTTP dla sieci
WWW, mamy jeszcze SMTP, POP i IMAP dla poczty elektronicznej, FTP, FSP i TFTP
do przesyłania plików, NFS do dostępu do plików, NNTP do przesyłania wiadomo-
ści oraz wiele innych. Poza tym twój program może w razie potrzeby zdefiniować
własne protokoły warstwy aplikacji.
Protokoły IP, TCP oraz UDP
IP (ang. Interent Protocol - protokół Internetu) ma wiele zalet w porównaniu z innymi
protokołami, takimi jak AppleTalk i IPX. W większości wynikają one z jego historii.
Został opracowany w czasie zimnej wojny pod patronatem wojskowym i wyposa-
żony w wiele funkq'i, którymi była zainteresowana armia. Po pierwsze, musiał być
me do zniszczenia. Nie mogło być tak, że cała sieć przestałaby funkcjonować, gdyby
Sowieci w ataku nuklearnym uszkodzili ruter w Cleveland. Wszystkie komunikaty
musiały nadal dochodzić do punktów przeznaczenia (oczywiście oprócz tych
wysłanych do Cleveland). Dlatego też IP został zaprojektowany tak, by możliwe
byty różne drogi między dwa dowolnymi punktami i by dało się przekierować pa-
lety danych, omijając uszkodzone rutery.
"o drugie, wojskowi mieli różne typy komputerów i chcieli, aby wszystkie mogły się
ze sobą porozumiewać. Dlatego protokół musiał być otwarty i niezależny od platfor-
30 Rozdział 2: Podstawowe pojęcia dotyczące sieci
my. Nie byłoby dobrze, gdyby istniał jeden protokół dla komputerów typu mainfra-
me IBM-a i drugi dla maszyn PDP-11. Trzeba było zapewnić komunikację komputerów
mainframe IBM-a z PDP-11 i z wszelkimi innymi, dziwnymi komputerami, które
mogłyby znajdować się w okolicy.
Ponieważ między dwoma punktami sieci istnieje wiele dróg, a z powodu obciążenia
sieci i innych czynników (na przykład istnienia Cleveland) w funkcji czasu może się
zmieniać to, która ścieżka między dwoma punktami jest najszybsza, nie wszystkie
pakiety, składające się na konkretny strumień danych, wybiorą tę samą drogę. Co
więcej, mogą nie dotrzeć w tej kolejności, w jakiej zostały wysłane, jeśli w ogóle
dotrą. W celu udoskonalenia podstawowego schematu transmisji nad IP dodano
warstwę TCP, aby każda strona połączenia miała możliwość powiadamiania o ode-
braniu pakietów IP i żądania retransmisji tych, które zostały zagubione lub uszko-
dzone. Poza tym TCP umożliwia po stronie odbiorcy ponowne zestawienie pakie-
tów w tej kolejności, w jakiej były wysyłane przez nadawcę.
TCP troszczy się o to, co dzieje się wyżej. Zatem jeśli kolejność danych nie jest istotna
i jeśli zgubienie jednego pakietu nie zniszczy całego strumienia danych, to pakiety są
czasami wysyłane bez gwarancji zapewnianych przez TCP. Realizuje się to za po-
mocą protokołu UDP. UDP jest protokołem zawodnym, który nie gwarantuje, że pa-
kiety dotrą do punktu przeznaczenia ani że zostaną dostarczone w tej samej kolejno-
ści, w jakiej je wysłano. Chociaż w niektórych zastosowaniach, takich jak transfer
plików, może to być problemem, jest akceptowalne w przypadku tych aplikacji, dla
których zagubienie części danych powinno zostać niezauważone przez użytkowni-
ka końcowego. Na przykład zgubienie kilku bitów z sygnału dźwiękowego lub wi-
zyjnego nie spowoduje znacznych szkód, natomiast oczekiwanie na protokół, taki
jak TCP, aby zażądać retransmisji brakujących danych, będzie jednak dużym pro-
blemem. Poza tym kody poprawiające błędy mogą zostać wbudowane w strumienie
danych UDP na poziomie aplikacji, aby ewidenq'onować brakujące dane.
Oprócz TCP i UDP istnieje wiele innych protokołów, które mogą działać ponad pro-
tokołem IP. Najczęściej przydaje się ICMP (ang. Internet Control Message Protocol -
protokół komunikacyjny sterowania Internetem), który wykorzystuje pierwotne da-
tagramy IP do przekazywania komunikatów błędu między węzłami. Najlepiej zna-
nym zastosowaniem tego protokołu jest program ping. W Javie nie jest obsługiwany
protokół ICMP ani nie jest możliwe wysyłanie pierwotnych datagramów IP (w prze-
ciwieństwie do segmentów TCP lub datagramów UDP). Jedynymi protokołami
obsługiwanymi w Javie są TCP i UDP oraz protokoły warstwy aplikacji, zbudowane
ponad nimi. Wszystkie pozostałe protokoły warstwy transportowej, internetowej
i niższych warstw, takie jak ICMP, IGMP, ARP, RARP, RSVP i inne, mogą zostać za-
implementowane w Javie tylko za pomocą oryginalnego kodu.
Adresy IP i nazwy domen
Programując w Javie, nie musisz się martwić o szczegóły działania protokołu IP, ale
powinieneś znać się na adresowaniu. Każdy komputer sieci IP jest identyfikowany
za pomocą 4-bajtowej liczby. Zazwyczaj jest pisana w formacie takim jak ten:
199.1.32.90, gdzie każda z czterech liczb jest jednym bajtem bez znaku o wartości
protokolylPj^^^___________________________________?!
kresu od O do 255. Każdy komputer podłączony do sieci IP ma swój niepowta-
Z inv 4-bajtowy adres. Gdy dane w postaci pakietów są przesyłane siecią, każdy
rZ jówek pakietu zawiera adres maszyny, dla której pakiet jest przeznaczony (ad-
113 odbiorcy) oraz adres maszyny, która go wysłała (adres nadawcy). Po drodze ru-
ry wybierają najlepszą trasę dla danego pakietu, zaglądając do adresu odbiorcy.
Adres nadawcy jest wpisywany po to, by odbiorca wiedział, komu ma odpowie-
dzieć.
Choć liczby są wygodne dla komputerów, ludziom trudno je zapamiętać. Dlatego
opracowano DNS (ang. Domain Name System - system nazw domen), który tłumaczy
zwykłe nazwy hostów, łatwe do zapamiętania dla ludzi (takie jak http://wwiv.oreil-
lycom), na liczbowe adresy internetowe (takie jak 198.112.208.23). Gdy program
w Javie uzyskuje dostęp do sieci, musi przetworzyć adresy liczbowe i odpowiadające
im nazwy hostów. Do tego celu istnieje szereg metod w klasie j ava. net. inetAd-
dress, które są omówione w rozdziale 6. "Wyszukiwanie adresów internetowych".
Porty
Adresy byłyby jedyną rzeczą, której byś potrzebował, gdyby w danym czasie każdy
komputer robił nie więcej niż jedną rzecz. Jednakże nowoczesne komputery robią
wiele różnych rzeczy jednocześnie. Zatem na przykład trzeba oddzielić pocztę elek-
troniczną od żądań FTP, a te od ruchu w sieci WWW. Osiągnięto to dzięki portom.
Każdy komputer posiadający adres IP ma kilka tysięcy portów logicznych (a kon-
kretnie 65 535 dla protokołu warstwy transportowej). Są to byty czysto abstrakcyjne,
istniejące jedynie w pamięci komputera i nie reprezentujące niczego fizycznego, ta-
kiego jak port szeregowy lub równoległy. Każdy port jest identyfikowany za po-
mocą liczby z zakresu od l do 65 535. Każdy port może zostać przydzielony konkret-
nej usłudze.
Na przykład usługa HTTP, która jest wykorzystywana przez sieć WWW, zazwyczaj
działa na porcie 80 (mówimy, że serwer WWW nasłuchuje w porcie 80 nad-
chodzących połączeń). SMTP lub serwer poczty elektronicznej działa w porcie 25.
Gdy dane zostaną wysłane do serwera WWW konkretnej maszyny o konkretnym
adresie IP, to są one także wysyłane do konkretnego portu (zazwyczaj portu 80) tej
maszyny. Odbiornik sprawdza, do którego portu idzie każdy napotkany pakiet,
1 wysyła dane do wszystkich programów, które nasłuchują tego właśnie portu.
W ten sposób są posortowane różne rodzaje ruchu sieciowego.
Porty od l do 1023 są zarezerwowane dla dobrze znanych usług, takich jak finger,
FTP, HTTP i poczta elektroniczna. W systemach uniksowych tylko programy
działające z uprawnieniami użytkownika uprzywilejowanego mogą odbierać dane
2 tych portów, a wysyłać do nich dane mogą wszystkie programy. W systemie Win-
dows i w systemie Macintoshy, a także w systemie Windows NT, z tych portów
może korzystać każdy program, bez żadnych specjalnych przywilejów. Tabela 2-1
przedstawia dobrze znane porty dla protokołów omawianych w tej książce. Te przy-
pisania nie są absolutnie pewne. W szczególności serwery WWW często działają na
innym porcie niż 80, choćby dlatego, że na tej samej maszynie musi działać wiele ser-
Werów, albo dlatego, że osoba, która instalowała serwer, nie miała uprawnień użyt-
32
Rozdział 2: Podstawowe pojęcia dotyczące sieci
kownika uprzywilejowanego, potrzebnych do działania na porcie 80. W systemach
uniksowych prawie kompletny wykaz przydzielonych portów jest przechowywany
w pliku /etc/seruices.
Tabela 2-1. Przj Protokół odziały dób Port ze znanych por Protokół tów Zastosowanie
echo 7 TCP/UDP Protokół testujący, używany do sprawdzania, czy dwie maszyny dadzą się połączyć tak, bv jedna powtarzała wejście drugiej.
discard 9 TCP/UDP Mniej przydatny protokół testujący, w którym wszystkie dane odbierane przez serwer są ignoro-
wane.
daytime 13 TCP/UDP Podaje reprezentaq'ę ASCII aktualnego czasu ser-
wera.
ftp-data 20 TCP FTP korzysta z dwóch dobrze znanych portów. Ten jest używany do przesyłania plików.
FTP 21 TCP Ten port służy do wysyłania poleceń FTP, takich jak put i get.
Telnet 23 TCP Protokół wykorzystywany do interakcyjnych, zdalnych sesji wiersza poleceń.
SMTP 25 TCP Służy do przesyłania poczty elektronicznej między komputerami.
time 37 TCP/UDP Serwer czasu zwraca liczbę sekund, które
upłynęły na serwerze od północy 1 stycznia 1900 roku, w postaci 4-bajtowej liczby całkowitej bez znaku typu big-endian.
whois 43 TCP Prosta usługa katalogowa dla administratorów sieci Internet.
finger 79 TCP Usługa, która zwraca informaq'ę o użytkowniku lub użytkownikach systemu lokalnego.
HTTP 80 TCP Protokół przesyłania hipertekstu jest zasadniczym protokołem sieci WWW.
POP3 110 TCP Protokół poczty w wersji 3. służy do przesyłania zgromadzonej poczty elektronicznej od węzła do sporadycznie łączonych klientów.
NNTP 119 TCP Przesyłanie wiadomości w sieci Usenet jest oficjalnie nazywane NNTP.
RMI Registry 1099 TCP Jest to usługa rejestrowania zdalnych obiektów Javy. Została omówiona w rozdziale 18. "Zdalne wywoływanie metod (RMI)".
Internet
Internet jest największą światową siecią opartą na protokole IP. Tworzy ją gigantycz-
na liczba komputerów w wielu różnych krajach na wszystkich siedmiu kontynen-
tach (w tym w Antarktyce), które porozumiewają się za pomocą protokołu IP. Każdy
33
uter Internetu ma przynajmniej jeden unikatowy adres IP, który służy do jego
v?tvfikacji. Większość z nich posiada co najmniej jedną nazwę, odpowiadającą
1 6 adresowi IP. Internet nie należy do nikogo, ale jego części mają właścicieli.
16 z nikogo nie jest zarządzany, co nie znaczy, że rządy niektórych państw nie
,, tegO robić. Jest po prostu ogromnym zbiorowiskiem komputerów, które
P lify że będą się ze sobą porozumiewać w standardowy sposób.
net nie jest jedyną siecią opartą na protokóle IP, ale jest największą. Inne sieci IP
azywane są internetami przez małe "i", na przykład sieć IP jakiejś korporacji, która
'e została podłączona do Internetu. Intranet to dość nowe słowo, luźno opisujące
korporacyjne praktyki umieszczania mnóstwa danych na wewnętrznych serwerach
WWW. A ponieważ przeglądarki WWW używają protokołu IP, robi to również wię-
kszość intranetów (chociaż kilka z nich przesyła je instalacjami AppleTalk lub IPX).
Prawie pewne jest, że internet, którego używasz, jest Internetem. Aby mieć pewność,
iż komputery różnych sieci w Internecie będą mogły komunikować się ze sobą,
trzeba przestrzegać kilku zasad, które jednak nie dotyczą czysto wewnętrznych in-
ternetów. Najważniejsze reguły mówią o przydzielaniu adresów różnym organiza-
cjom, firmom i prywatnym osobom. Jeśli ktokolwiek wybierze sobie internetowy ad-
res w sposób losowy, prawie natychmiast pojawi się konflikt, gdyż różne komputery
będą widoczne w Internecie pod tym samym adresem.
Klasy adresów internetowych
Aby uniknąć tego problemu, adresy internetowe są przydzielane różnym organiza-
cjom przez IANA (ang. Internet Assigned Numbers Authority - zarząd przydzielania
adresów internetowych)*, przeważnie działający poprzez pośredników nazywa-
nych dostawcami usług internetowych (ISP). Gdy firma lub organizacja chce skonfi-
gurować sieć opartą na protokóle IP i podłączoną do Internetu, wtedy ISP przydziela
jej blok adresów. Obecnie takie bloki są dostępne w dwóch rozmiarach, nazywanych
klasą B i klasą C. Blok adresów klasy C określa trzy pierwsze bajty adresu, na
przykład 199.1.32. Pozostawia to miejsce na 254 indywidualne adresy od 199.1.32.1
do 199.1.32.254.** Blok adresów klasy B wyznacza tylko dwa pierwsze bajty adresu,
którego może używać organizacja, na przykład 167.1. Zatem adres klasy B
dopuszcza 65 024 różne hosty (256 bloków rozmiaru klasy C razy 254 hosty dla blo-
ku klasy C).
Adresy liczbowe przydają się, gdy chcesz ograniczyć dostęp do swojej witryny. Na
przykład mógłbyś uniemożliwić konkurencyjnej firmie dostęp do swojej witryny
WWW. W takim przypadku powinieneś dowiedzieć się, jaki blok adresów ma kon-
kurenq'a i odrzucać wszystkie żądania przychodzące spod tamtych adresów. Bar-
dziej typowe rozwiązanie polega na udostępnieniu serwera WWW tylko osobom
z ^ojej organizacji. W tym przypadku powinieneś odmówić dostępu wszystkim
żądaniom spoza twojego bloku adresów.
Już wkrótce tę funkcję będzie pemić ICANN (ang. Internet Corporation for Assigned Nanieś and Numbers -
wternetowa korporaq'a przydzielonych nazw i numerów).
Adresy z ostatnim bajtem .0 lub .255 są zarezerwowane i nigdy nie powinny być przypisywane hostom.
34 Rozdział 2: Podstawowe pojęcia dotyczące sieci
Nie istnieją bloki o rozmiarach pośrednich pomiędzy rozmiarami klasy B i C. Taka
struktura adresów nie odpowiada potrzebom, ponieważ wiele organizacji chciałoby
mieć więcej niż 254 komputery podłączone do Interneru, ale zdecydowanie mniej
niż 65 024. Jeśli każda z tych organizacji otrzymałaby pełny blok klasy B, to wiele
adresów IP zostałoby zmarnowanych. Jest to problemem, gdyż liczba adresów jest
ograniczona. Jest ich około 4,2 miliarda. Wydaje się, że to dużo, ale szybko ich uby-
wa, gdy łatwo można zaprzepaścić 50 000 lub 60 000 adresów za jednym zamachem.
Co z klasą A adresów internatowych?
Gdy Internet był projektowany, było także miejsce na 126 adresów klasy A, któ-
ra określała tylko pierwszy bajt i pozwalała na posiadanie w organizacji ponad
16 milionów różnych komputerów. Jednak prawie żadna organizacja nie po-
trzebuje aż tylu adresów i dlatego znaczna część adresów klasy A pozostawała
niewykorzystana. Adresy internetowe są dobrem limitowanym, więc już od
dawna IANA przestała przydzielać adresy klasy A i w użyciu jest ich nieco wię-
cej niż trzy tuziny.
Istnieją także klasy adresów D i E. Klasa D jest stosowana przy przesyłaniu na ad-
resy multicast i została obszernie omówiona w rozdziale 14. "Gniazda mulricast".
Wszystkie adresy klasy D zaczynają się czterema bitami 1110. Adresy klasy E za-
czynają się pięcioma bitami 11110 i zostały zarezerwowane dla przyszłych rozsze-
rzeń Interneru.
Istnieje także wiele sieci, takich jak własny obszar sieci autora, które mają od kilku
do kilkudziesięciu komputerów, ale nie aż 255. Aby wydajniej rozdzielać ograni-
czoną przestrzeń adresów, powstał CIDR (ang. Classless Inter-Domain Routing - mię-
dzydomenowe przekierowania pozaklasowe). CIDR prawie całkowicie zastępuje
cały schemat adresowania A, B, C adresowaniem opartym na wybranych liczbach
bitów przedrostka. Zazwyczaj jest to zapisywane w postaci /24 lub /19. Liczba po
ukośniku wskazuje liczbę ustalonych bitów przedrostka. Zatem /24 ma ustalone
pierwsze 24 bity adresu, a 8 bitów można wykorzystać do rozróżniania poszczegól-
nych węzłów. Pozwala to na zaadresowanie 256 węzłów i jest równoważne klasie C
starego typu. Z kolei /19 oznacza ustalone 19 bitów, z 13 bitami pozostawionymi dla
poszczególnych węzłów wewnątrz sieci. Odpowiada to 32 oddzielnym sieciom kla-
sy C lub jednej ósmej klasy B. Natomiast /28 jest najmniejszym adresowaniem, które
napotkasz w praktyce, i dysponuje tylko 4 bitami do identyfikowania węzłów lo-
kalnych. Wystarcza sieciom, które mają do 16 węzłów. CIDR dokładnie określa, z któ-
rymi dostawcami usług internetowych związane są poszczególne bloki adresów.
Dzięki temu internetowe tablice rutingu mogą być mniejsze i łatwiej nimi zarządzać
niż w starym systemie.
Kilka bloków adresu i wzorców ma specjalny charakter. Wszystkie adresy interneto-
we zaczynające się od 10., adresy od 172.16. do 172.31. oraz 192.168. celowo nie są
przydzielane. Mogą być stosowane w sieciach wewnętrznych, ale żaden komputer
o adresie z takiego bloku nie może znaleźć się w sieci globalnej. Te nieprzekierowywd-
35
A sy przydają się do budowania prywatnych sieci, które nie są widoczne w po-
n? 3 ł i części Internetu, lub do budowania dużej sieci w przypadku, gdy został jej
ZS dzielony tylko blok adresów klasy C. Adresy zaczynające się od 127 (najczęściej
Pf^O g |) Zawsze oznaczają adres lokalnej pętli zwrotnej, to znaczy, że zawsze wska-
.' komputer lokalny, niezależnie od tego, na jakim komputerze pracujesz. Nazwą
ła dla tego adresu jest na ogół localhost. Adres 0.0.0.0 zawsze odnosi się do orygi-
W Ineeo węzła, ale może być używany tylko jako adres nadawcy, nie odbiorcy. Po-
dobnie zakłada się, iż każdy adres zaczynający się od 0.0. wskazuje węzeł tej samej
sieci lokalnej.
Firewalle
W Internecie trafiają się też osoby złośliwe. Aby nie dopuścić ich do siebie, zazwy-
czaj najlepiej jest wyznaczyć tylko jeden punkt, przez który można dostać się do sieci
lokalnej, i kontrolować cały ruch wchodzący i wychodzący przez ten punkt. Zestaw
składający się ze sprzętu i oprogramowania umieszczony między Internetem a sie-
cią lokalną, i kontrolujący wszystkie wchodzące i wychodzące dane, aby upewnić
się, że są koszerne, jest nazywany firewallem.
Najprostszym firewallem jest filtr pakietów, który sprawdza każdy pakiet wcho-
dzący do sieci i wychodzący z niej, wykorzystując zestaw reguł określających, które
transmisje są dozwolone. Filtrowanie zazwyczaj bazuje na sieciowych adresach
i portach. Na przykład cały ruch przychodzący z sieci 193.28.25 klasy C może zostać
zatrzymany z powodu twoich złych doświadczeń w przeszłości z hakerami z tej czę-
ści sieci. Wychodzące połączenia telnetowe mogą być dozwolone, a wchodzące za-
bronione. Wchodzące połączenia z portem 80 (sieć WWW) mogą być wpuszczane,
ale tylko na firmowy serwer WWW. Konkretna konfiguracja firewalla - to znaczy,
które pakiety danych zostaną przepuszczone, a które nie - zależy od indywidual-
nych wymagań bezpieczeństwa danej witryny. Java nie ma zbyt wiele wspólnego
z firewallami poza tym, że często stają ci na drodze.
Serwery proxy
Serwery proxy są pokrewne firewallom. Jeśli firewall chroni węzły sieci przed pew-
nymi połączeniami ze światem zewnętrznym, to serwer proxy może działać jako po-
średnik. Wtedy maszyna, której firewall uniemożliwia kontakty z siecią zewnętrzną,
może zażądać strony WWW od lokalnego serwera proxy zamiast bezpośrednio od
zdalnego serwera WWW. Serwer proxy zażąda strony od serwera WWW i przekaże
odpowiedź maszynie, która wystąpiła z żądaniem. Serwerów proxy można także
używać do usług FTP oraz do innych połączeń. Używanie serwera proxy sprzyja
bezpieczeństwu. Hosty na zewnątrz wiedzą tylko o serwerze proxy. Nie poznają
nazw ani adresów IP, co znacznie utrudnia włamania do systemu wewnętrznego.
rirewalle zazwyczaj działają w warstwie transportowej lub internetowej, natomiast
serwery proxy w warstwie aplikacji. Serwer proxy rozumie niektóre protokoły war-
stwy aplikacji, takie jak HTTP i FTP. Pakiety, które przechodzą przez serwer proxy,
można przebadać, aby upewnić się, czy zawierają dane zgodne z ich typem. Na
36
Rozdział 2: Podstawowe pojęcia dotyczące sieci
przykład jeśli wygląda na to, że pakiet FTP zawiera dane Telnetu, może zostać od-
rzucony. Rysunek 2-3 przedstawia, w jaki sposób serwery proxy włączają się w mo-
del warstwowy.
klient
warstwa aplikacji
warstwa transportowa
(TCP, UDP)
warstwa
warstwa aplikacji
warstwa transportowa
(TCP.UDP)
warstwa
internatowa (IP)
serwer
warstwa aplikacji
warstwa transportowa
(TCP, UDP)
warstwa
intemełowa (IP)
Rysunek 2-3. Łączenie się warstw poprzez serwer proxy
Dopóki cały dostęp do Internetu jest kierowany przez serwer proxy, dopóty może
być ściśle kontrolowany. Na przykład firma może zablokować dostęp do adresu
http:llwww.playboy.com, ale pozwalać na łączenie się z adresem http://imvw.microsoft.com.
Niektóre firmy dopuszczają wchodzące połączenia FTP, ale nie zezwalają na wy-
chodzące FTP, aby nie ułatwiać kradzieży poufnych danych firmy. Niektóre firmy
zaczęły stosować serwery proxy, aby śledzić, jak ich pracownicy korzystają z sieci
WWW. Można się przekonać, kto używa Internetu do uzyskania pomocy technicz-
nej, a kto ogląda plakaty Miss miesiąca. Takie kontrolowanie zachowań pracowników
jest kontrowersyjne i niekoniecznie stanowi wyznacznik światłych metod zarządzania.
Serwery proxy można również wykorzystywać do zaimplementowania lokalnego
buforowania. Gdy pojawia się żądanie pobrania jakiegoś pliku z serwera WWW,
serwer proxy najpierw sprawdza, czy plik nie znajduje się w jego buforze. Jeśli znaj-
dzie plik w buforze, to przekaże go stamtąd, zamiast ściągać z Internetu. Jeżeli pliku
tam nie będzie, serwer proxy go ściągnie, przekaże do komputera, który go zażądał,
i zapamięta w swoim buforze, aby móc go wykorzystać w przyszłości. Ta metoda
istotnie redukuje obciążenie łączy Internetu i znacznie poprawia czas odpowiedzi.
AOL (America Online) posiada jedno z największych na świecie gospodarstw z ser-
werami proxy w celu przyspieszania transferu danych do swoich użytkowników.
Jeśli zajrzałbyś do pliku rejestracyjnego serwera WWW, prawdopodobnie zna-
lazłbyś trochę odwołań od klientów o nazwach takich jak http://www.-dl.proxy.
aol.com, ale nie aż tyle, jak należałoby się spodziewać przy ponad 20 milionach
subskrybentów AOL. A to dlatego, że AOL żądało tylko tych stron, których jeszcze
nie miało w swoich buforach. Wielu innych dużych dostawców usług internetouych
robi podobnie.
Intern^
37
'ekszy problem z serwerami proxy polega na tym, że współpracują jedynie
ik ma protokołami, a nie ze wszystkimi. Powszechnie wprowadzone protokoły,
Z ^- 'k HTTP, FTP i SMTP, są przez nie przepuszczane, lecz nowsze protokoły, jak
T ^ ter już nie. (Niektórzy administratorzy sieci będą sobie cenić tę cechę). W szyb-
^aPjnjeńiającym się świecie Internetu jest to istotną wadą. Jest to niebagatelna prze-
, ta rovvnież dla programistów Javy, ponieważ ta własność nie pozwala wyko-
52 tac specyficznych protokołów. Często w Javie i łatwiej, i wygodniej jest utwo-
rZyć nowy protokół, dostosowany do własnej aplikacji. Jednakże żaden serwer
proxy nigdy nie zrozumie takiego protokołu.
Anlety, które działają w przeglądarkach sieciowych, zazwyczaj używają ustawień
serwera proxy samej przeglądarki. Na ogół określa się to w oknie dialogowym (któ-
re może się kryć o kilka poziomów niżej w ustawieniach), takim jak na rysunku 2-4.
2d
*J
- Appearance
Fonłs
Cołołs
~- Navigatoł
Languages
Applications
Smait Browing
3tr Mai&Newsgroups
+: Roaming Access
+; Composer
$ Offine
H- Advanced
Cache
Pioaes
SmaitUpdate
Servws
Type Addtess of proxy servet to use
HTTP: web. ptoxy. cloud9. net
Secu%
Port
' :!8000
FTP: | ftp.proxy.cloud9.net
Socks: socks.cloud9.net
;|1000
' ;[1080
Gopheł: gopher. proxy. cloud9. net
WAIS: jwais.pfoxy.cloud9 net
Exceptbns ----------- ..................... -- ............... -
Dc rot use proxy servers tor domarss begrinsig with:
l
Use commas [,] to separate entries.
OK
Cancel
OK
Cancel
Help
Rysunek 2-4. Ustawienia serwera proxy dla Netscape Navigatora
Samodzielna aplikacja Javy może wskazywać serwer proxy, który ma być używany,
za pomocą właściwości socksProxyHost oraz socksProxyPort (jeśli używasz
serwera proxy SOCKS) lub właściwości systemowych http.proxySet,
nttp.proxyHost, http.proxyPort, https.proxySet, https.proxyHost,
https.proxyPort, ftpProxySet,ftpProxyHost, ftpProxyPort, gopher-
roxySet, gopherProxyHost, oraz gopherProxyPort (jeżeli używasz ser-
Werow proxy dla poszczególnych protokołów). Właściwości systemowe możesz
ustawiać z wiersza poleceń za pomocą flagi -D w następujący sposób:
Va ~DscksProxyHost=socis.cload9.net -DsocksProxyPort=1080 MojaKlasa
38
Rozdział 2: Podstawowe pojęcia dotyczące sieci
Można również to zrealizować za pomocą dowolnego innego wygodnego sposobu
ustawiania właściwości systemowych, na przykład wstawiając je do pliku appletvie~
wer.properties jak poniżej:
ftpProxySet=true
ftpProxyHost=ftp. proxy.cloud9.net .'.':
ftpProxyPort=1000 . ..
gopherProxySet=true
gopherProxyHost=gopher .proxy. cloud9 . net "" '
gopherProxyPort=9800 -"'f - '
http.proxySet=true .,, , .
http.proxyHost=web.proxy.cloud9.net
http.proxyPort=8000 .,= .
https.proxySet=true
https.proxyHost=web.proxy.cloud9.net
https .proxyPort=8001 ' Ł .-.-
Model klient-serwer
Większość nowoczesnego programowania sieciowego bazuje na modelu klient-ser-
wer. Aplikacje typu klient-serwer zazwyczaj przechowują duże ilości danych na
drogim, dobrze wyposażonym serwerze, podczas gdy większość logiki programu
i interfejs użytkownika są obsługiwane przez oprogramowanie klienckie, działające
na względnie tanim komputerze osobistym. W większości przypadków serwer
głównie wysyła dane, a klient je odbiera, ale rzadko się zdarza, aby jakiś program
wyłącznie wysyłał lub wyłącznie odbierał dane. Właściwsze byłoby takie rozróżnie-
nie, w którym klient inicjuje komunikację, a serwer czeka na klienta, by rozpocząć
z nim rozmowę. Rysunek 2-5 ilustruje obie te możliwości. W niektórych przypad-
kach ten sam program może być zarówno klientem, jak i serwerem.
4-
Klient inicjuje połączenie od dowolnego portu
dostępnego po stronie klienta do znanego polu selera.
klient
port 41 232
port 80
(strumień wejściowy)
port 80
(strumień wyjściowy)
m+-
\
-*i port 41 232
(strumień wejściowy)
Serwer akceptuje połączenie. Strumienie wejściowy i wyjściowy
są łączone z gniazdkami określonego portu.
port 41 232
(strumień wyjściowy)
Rysunek 2-5. Połączenie klient-serwer
Modelktient^L
39
rwerów przetwarza i analizuje dane, zanim wyśle klientowi wyniki. Takie
CZ3S często określane mianem "serwerów aplikacji" w celu odróżnienia ich od
Ser/A 'ei popularnych serwerów plików i serwerów baz danych.
r plików lub bazy danych pobiera informacje i wysyła je klientowi, ale nie bę-
'h przetwarzał. Serwer aplikacji, przeciwnie, może obejrzeć wpis zamówień
h ie danych i zdać klientowi raport o profilu wydatków w danym miesiącu. Ser-
W Aplikacji nie jest natomiast serwerem podającym pliki, które - tak się składa - są
aplikacjami-
wiele przykładów systemów typu klient-serwer. W roku 2000 najpopularniej-
si systemem typu klient-serwer w Internecie była sieć WWW. Serwery WWW,
tkie jak Apache, odpowiadają na żądania klientów WWW, takich jak Netscape.
Dane są przechowywane na serwerach WWW i wysyłane klientom, na żądanie.
Poza przypadkiem początkowego żądania strony prawie wszystkie dane są prze-
syłane z serwera do klienta, nie od klienta do serwera. Serwery WWW, które uży-
wają programów CGI, działają w podwójnej roli - jako serwery aplikacji i plików.
Starszą usługą działającą w modelu klient-serwer jest FTP. Używa ona innych proto-
kołów aplikacji i innego oprogramowania, ale nadal jest rozdzielona na serwery
FTP, które wysyłają pliki, i na klienty FTP, odbierające pliki. Często wykorzystuje się
FTP do przeładowywania plików od klienta do serwera, więc trudno byłoby powie-
dzieć, że transfer danych odbywa się w jednym zasadniczym kierunku, ale nadal
prawdą jest, że klient FTP inicjuje połączenie, a serwer FTP na nie odpowiada.
Java jest potężnym środowiskiem do pisania programów graficznego interfejsu
użytkownika (GUI), które mają dostęp do wielu różnych rodzajów serwerów. Wy-
bitnym przykładem programu klienckiego napisanego w Javie jest Hotjava,
przeglądarka WWW firmy Sun, która jest uniwersalnym klientem WWW. Java
ułatwia pisanie klientów wszystkich typów, lecz naprawdę zabłyśnie, gdy zaczniesz
pisać serwery. Java ma pewne ograniczenia wydajności, głównie dotyczące graficz-
nych interfejsów użytkownika oraz wejścia i wyjścia dysku. Jednak żaden z nich nie
jest czynnikiem ograniczającym programy serwerów, gdzie o wiele ważniejsze są
szerokość pasma przenoszenia sieci i odporność na błędy.
NTie wszystkie aplikacje dają się łatwo wpasować w model klient-serwer. Na
przykład w grach sieciowych wygląda to tak, że obaj gracze przesyłają dane w tę i z
powrotem w przybliżeniu równomiernie (przynajmniej w uczciwej grze). Takie ro-
dzaje połączeń są nazywane równorzędnymi bądź "każdy z każdym" (ang. pe-
er-to-peer). System telefoniczny jest klasycznym przykładem sieci równorzędnej. Ka-
żdy aparat telefoniczny może zadzwonić do innego lub odebrać od niego połącze-
nie. Nie musisz kupować jednego telefonu do dzwonienia i drugiego do odbierania
rozmów.
Java nie posiada w swoim sieciowym API w jawny sposób komunikacji równorzę-
nej- Jednak łatwo można zaimplementować ten typ komunikacji i to na kilka spo-
sobów, przede wszystkim przez jednoczesne działanie zarówno w roli klienta, jak
serwera. Równoprawne strony mogłyby też komunikować się ze sobą poprzez po-
średniczący program serwera, który przesyłałby dane od jednej strony do pozo-
Rozdział 2: Podstawowe pojęcia dotyczące s/ec,
stałych. Jest to szczególnie przydatne dla apletów, którym menedżer zabezpieczeń
nie zezwala na bezpośrednie komunikowanie się między sobą.
Internetowe standardy
Ta książka omawia kilka protokołów internetowych warstwy aplikaq'i, przede
wszystkim HTTP. Jednak nie jest to podręcznik protokołów i nie ma tu nic poza tym
co rzeczywiście musisz wiedzieć. Jeśli potrzebujesz szczegółowych informaq'i o ja-
kimkolwiek protokole, wiarygodnym źródłem zawsze będzie dokumentacja stan-
dardów dla protokołu.
Na świecie istnieje wiele organizacji normalizacyjnych. Dwoma najważniejszymi
sporządzającymi większość standardów dotyczących programowania sieciowego
i protokołów, są IETF (ang. Internet Engineering Task f orce - Grupa Robocza ds. Tech-
nicznych sieci Internet) i W3C (ang. World Wide Web Consortium - Konsorcjum
WWW). IETF jest dosyć nieformalnym, demokratycznym ciałem otwartym dla
wszystkich zainteresowanych. Standardy IETF opierają się na "ramowych ustale-
niach i działającym kodzie" i raczej starają się podpowiadać niż narzucać implemen-
tacje. Dotyczą TCP/IP, MIME i SMTP. Z kolei W3C jest organizacją sprzedawców,
zarządzaną przez zespoły płacących składki członków, co od razu wyklucza udział
osób indywidualnych. Przeważnie W3C stara się definiować standardy przed poja-
wieniem się implementacji. Ich standardy dotyczą HTTP, HTML-a i XML-a.
RFC grupy IETF
Standardy IETF i pokrewne są publikowane w postaci szkiców internetowych i do-
kumentacji RFC (ang. Recjuestsfor Comments - żądania odpowiedzi). Publikacje RFC
oraz szkice internetowe mogą mieć różną postać: od informacyjnych dokumentów o
tematyce ogólnej do szczegółowych specyfikacji standardowych protokołów inter-
netowych, takich jak FTP. RFC, które dokumentują standard lub proponowany stan-
dard, są publikowane tylko po akceptacji przez grupę 1ESG (ang. Internet Engineering
Steering Group-Grupa Kierownicza ds. Technicznych sieci Internet), będącą podze-
społem IETF. Wszystkie zatwierdzone przez IETF standardy są dokumentami typu
RFC, lecz nie wszystkie RFC są standardami IETF. Dokumenty RFC są dostępne
w wielu miejscach w Internecie, na przykład pod adresem http://wrviv.faqs.org/rfc/
oraz http://www.ietf.org/rfc.html.
W większości publikacje RFC, a w szczególności te dotyczące standardów, są napi-
sane bardzo technicznym, górnolotnym i mało zrozumiałym językiem. Niemniej
często są jedynym kompletnym i pewnym źródłem informacji na temat konkretnego
protokołu.
Większość propozycji standardów pojawia się, gdy jakaś osoba lub grupa ma pe-
wien pomysł i utworzy prototyp. Prototyp jest niezmiernie ważny. Zanim coś stanie
się standardem IETF, musi zaistnieć i zadziałać. Dzięki temu wymaganiu standardy
IETF są przynajmniej wykonalne, w przeciwieństwie do standardów ogłaszanych
przez niektóre inne ciała standaryzacyjne.
41
^^^^
tVP przyjmie się nie tylko wśród jego autorów, a inne organizacje zaczną
Gdy Pro , w}asne wersje tego protokołu, wtedy pod auspicjami IETF może zostać
wprwa^ana grupa robocza, która postara się udokumentować protokół w szkicu in-
^OTTnirum (ang. Internet-Draft). Szkice są dokumentami roboczymi i często są mo-
ternelwane, aby odzwierciedlać doświadczenia gromadzone przy korzystaniu
dyfik ^ Eksperymentajna implementacja i szkic internatowy ewoluują mniej
Z ?T' równolegle do momentu, w którym grupa robocza stwierdzi, że protokół jest
vvięcej otowany/ aby stać się formalnym standardem. Wtedy proponowaną
Specyfikację przedkłada się IESG.
Każdy proces standaryzacji składa się z sześciu kolejnych etapów:
eksperymentalny, f.
proponowany standard, .
Szkic standardu, ,_.,,.. , ^
standard, >.*.i>V'V -*;-:,:;,' :<;.i -.i,'.
informacyjny, :- " ' ' ,:
historyczny.
Po jakimś czasie od przedłożenia propozyq'i, zaczyna się stadium eksperymentalne.
Poziom eksperymentalny nie oznacza wcale, że protokół nie jest solidny lub że nie
jest powszechnie stosowany. Niestety proces standaryzacji de facto przedłuża akcep-
tację standardu. Jeżeli IESG pochwala eksperymentalny standard lub jest on w po-
wszechnym zastosowaniu, to przydziela mu numer RFC i publikuje go jako ekspe-
rymentalny RFC, zazwyczaj po różnych poprawkach.
Jeśli eksperymentalny standard dobrze sobie radzi podczas testów w rzeczywistym
świecie, IESG może awansować go do stadium proponowanego standardu. Jest on jesz-
cze dość niezobowiązujący i poparty wynikami niewielu prac eksperymentalnych,
powiedzmy doświadczeniami jakiejś organizaq'i. Na tym etapie nadal mogą być
wprowadzane zmiany.
Gdy będzie się wydawało, że błędy w proponowanym standardzie zostały już roz-
pracowane, i będą istniały co najmniej dwie jego niezależne implementacje, IESG
może zacząć go polecać jako szkic standardu. Szkic standardu prawdopodobnie nie
będzie się znacznie zmieniał przed ewentualną standaryzacją, chyba że zostaną wy-
kryte poważne usterki. Podstawowym celem istnienia tego stadium jest uporządko-
wanie dokumentacji RFC, która opisuje protokół, i upewnienie się, że odpowiada
ona stanowi faktycznemu. Zmiany w samym protokole nie są już wprowadzane.
Gdy protokół już przejdzie ten etap, stanie się oficjalnym internetowym standardem.
^ostanie mu przydzielony numer STD, który będzie opublikowany jako uzupełnie-
nie dokumentacji RFC. Absolutnie minimalny czas zatwierdzania takiego standar-
du to 10 miesięcy, ale w praktyce zawsze trwa to znacznie dłużej. Komercyjny suk-
ces Internetu wcale w tym nie pomaga, gdyż standardy muszą teraz być opracowy-
vvane w obecności handlowców, drapieżnych kapitalistów, prawników, rzeczników
NSA oraz innych stron żywotnie zainteresowanych sukcesem lub klęską danej tech-
nologii. Dlatego wiele "standardów", do których odwołuję się w tej książce, jest jesz-
^___________________________^Rozdział 2: Podstawowe pojęoadotyczącesieti
cze na etapie eksperymentalnym, proponowanego standardu bądź szkicu standar-
du. Jeśli chodzi o publikacje, to istnieje prawie 3000 dokumentacji RFC. Około IOQ
z nich stało się standardami STD, a część z nich obecnie jest już przestarzała. Doku-
menty RFC związane z tematyką tej książki zostały wyszczególnione w tabeli 2-2.
Te dokumenty RFC, które nie stały się standardami, są traktowane jako dokumenty
informacyjne. Dotyczy to RFC opisujących powszechnie stosowane standardy, które
powstały poza normalną internetową ścieżką standaryzacyjną i nie przeszły formal-
nego procesu standaryzacji. Na przykład NFS, opracowany przez firmę Sun, jest
opisany w informacyjnym RFC 1813. Inne tego typu RFC dostarczają przydatnych
informacji (takich jak podręcznik użytkownika), lecz nie dokumentują protokołu.
Na przykład RFC 1635 How to Use Anonymous FTP (Jak korzystać z anonimowego FTP)
jest dokumentem informacyjnym.
Wreszcie zmiany w technologii i gromadzone doświadczenie powodują, że niektóre
protokoły i dotyczące ich dokumenty RFC stają się nieaktualne. Klasyfikuje się je
jako historyczne. Historycznymi protokołami są miedzy innymi IMAP3 (zastąpiony
przez IMAP4), POP2 (zastąpiony przez POP3) oraz RPĆ (ang. Remote Procedurę Cali-
zdalne wywołanie procedur) w wersji 1. (zastąpione przez RPC w wersji 2.).
Poza etapami rozwoju protokoły mają poziomy wymagań. Możliwymi poziomami
wymagań są:
Obowiązujący (Recjuired)
Musi być zaimplementowany na wszystkich węzłach Internetu. Takich proto-
kołów jest bardzo mało. Jednym z nich jest IP (RFC 791), ale nawet tak ważne pro-
tokoły jak TCP czy UDP są jedynie zalecane. Standard jest obowiązujący, jeśli
jego istnienie jest niezbędne do właściwego funkq'onowania komputera w węźle
internetowym.
Zalecany (Recommended)
Powinien zostać zaimplementowany na internetowych węzłach, jeśli nie istnieją
specjalne powody, dla których nie miałby zostać zaimplementowany. Większość
protokołów, które znasz (na przykład TCP i UCP, SMTP dla poczty elektronicz-
nej, Telnet do zdalnego rejestrowania itd.), jest protokołami zalecanymi.
Opcjonalny (Electwe)
Może zostać zaimplementowany przez każdego, kto chce go używać. Na przykład
RFC 2045 Multipurpose Internet Mail Extensions (Uniwersalne rozszerzenie poczty
elektronicznej sieci Internet) jest opcjonalnym szkicem standardu. Ze względu na
obecne jego znaczenie protokół MIME powinien zostać podniesiony do rangi za-
lecanego.
O ograniczonym zastosowaniu (Limited Use)
Może zostać zaimplementowany w niektórych nietypowych sytuacjach, ale nie
będzie potrzebny w większości węzłów. Głównie są to protokoły eksperymentalne.
Nie polecany (Not Recommended)
Nie powinien być stosowany.
mtemeto^standardy^
43
la 2-2. Wybrane internetowe dokumenty RFC
RFC Tytuł Poziom rozwoju Poziom wymagań
RFC 2600 STDJL- Internet Official Protocol Standards Standard Obowiązujący
,-, -c,iip oroces standaryzacji i obecny status różnych protokołów internetowych.
RFC 1700 STDJL Assigned Numbers Standard Obowiązujący
T n monumentalny dokument zawiera wszystkie informacje opracowane przez IANA,
eh,m typy j podtypy MIME, numery portów dla różnych usług, znaczenie poszczególnych
H^zb w nagłówkach IP i inne. Jak na dokumentację RFC, ta jest raczej nietypowa, ale absolut-
nie niezbędna.
RFC 1122 RFC 1123 STD3 Host Reąuirements Standard Obowiązujący
Dokumentują, które protokoły muszą być obsługiwane przez wszystkie węzły Internetu w różnych warstwach (w warstwie łącza, internetowe], transportowej i aplikacji).
RFC 791 RFC 919 RFC 922 RFC 950 STD5 Internet Protocol Standard rrtor:'. ^i-ii')! Obowiązujący
Protokół IP warstwy internetowej.
RFC 768 STDJL__J User Datagram Protocol Standard Zalecany
Zawodny, bezpołączeniowy protokół warstwy transportowej.
RFC 792 STO 5 Internet Control Message Protocol (ICMF) Standard Obowiązujący
Protokół warstwy internetowej, który wykorzystuje pierwotne datagramy IP, ale nie jest obsługiwany przez Javę. Jego najbardziej znanym zastosowaniem jest program pinRFC 793 STOJ7____ Niezawodny Transmission Control Protocol Standard Zalecany
połączeniowy, strumieniowy protokół warstwy transportowej.
RFC 821 STpJO__^ Simple Maił Transfer Protocol Standard Zalecany
Str0t jkó} warstwy aplikaq'i, za pomocą którego jeden host przesyła pocztę drugiemu. Ten ndard nie określa interfejsów użytkownika dla poczty elektronicznej, opisuje jedynie me- ruzm Przekazywania korespondenci z jednego komputera do drugiego.
Ciąg dalszy tabeli na str. 44
44
Rozdział 2: Podstawowe pojęcia dotyczące s;ec
Cw?g dalszy tabeli ze str. 43
Tabela 2-2. Wybrane internetowe dokumenty RFC
RFC Tytuł Poziom rozwoju Poziom wymagań
RFC 822 STD11 Format of Electronic Maił Messages Standard Zalecany
Podstawy składni tekstowych wiadomości e-mail w kodzie ASCII. MIME ma stanowić roz-
szerzenie tego standardu w zakresie danych binarnych i zapewniać zgodność przekazy-
wanych wiadomości z tym standardem.
RFC 854 RFC 855 STD8 Telnet Protocol Standard Zalecany
Zdalna usługa rejestracyjna warstwy aplikacji, przeznaczona dla środowiska wiersza pole-
ceń i oparta na wirtualnym terminalu sieci (NVT) i TCP.
RFC 862 STD20 Echo Protocol Standard Zalecany
Protokół warstwy aplikacji, który powtarza i zwraca wszystkie dane, które otrzyma za po-
mocą TCP i UDP. Przydatny jako narzędzie do usuwania błędów.
RFC 863 STD21 Discard Protocol j j Standard Opcjonalny 1
Protokół warstwy aplikacji, który odbiera pakiety danych otrzymywane za pomocą TCP
i UDP, nie wysyłając przy tym żadnej odpowiedzi klientowi. Przydatny jako narzędzie do
usuwania błędów.
RFC 864
STD22
Character Generator Protocol
Standard
Opcjonalny
Protokół warstwy aplikacji, który wysyła nieskończoną sekwencję znaków ASCII do każde-
go klienta, z którym łączy się poprzez TCP albo UDP. Także przydatny jako narzędzie do
usuwania błędów.
RFC 865
STD23
Quote of the Day
Standard
Opcjonalny
Protokół warstwy aplikacji, który zwraca cytat każdemu użytkownikowi, który połączy się
poprzez TCP albo UDP, a potem zamknie połączenie. ___________
RFC 867
STD25
Daytime Protocol
Standard
] Opcjonalny
Protokół warstwy aplikacji, który do każdego klienta, łączącego się poprzez TCP albo UDP,
wysyła zrozumiały dla ludzi ciąg ASCII, zawierający aktualną datę i godzinę na serwerze.
Inne protokoły serwerów czasu i NTP podają datę w formacie mało czytelnym dla ludzi. __
mt^etcwesiandar^
45
RFC
_-
RFC 868
STD26
Tytuł Poziom rozwoju Poziom wymagań
__ Time Protocol Standard Opcjonalny
STD 26_____L-"";
-TlT^arstwy aplikacji, podający klientowi łączącemu się poprzez TCP albo UDP czas
Protokół wd sek^ndrach/ ktore upłynęły od l stycznia 1900 roku. Ten czas jest wysyłany w
określony . iiczby całkowitej ze znakiem, czytelnej dla maszyn. Standard jest niekom
postaci ^' ł precyzuje, jak 32-bitowa liczba ma być zakodowana, ale przyjęło się sto-
' ^2 bitowe] iicziL'^ uw.i.r*.v.TT *-; ~*- -*--/ j i - - -j
P bowiem nie precyzuje, jak 32-bitowa liczba ma być zakodowana, a
pleWy'e liczby całkowitej typu big-endian stanowiącej dopełnienie dwójk
ł
ale przyjęło się sto-
kowe.
RFC 959
STD9
File Transfer Protocol
Standard
Zalecany
si^i_Z_J
O cionalnie uwierzytelniany, dwugniazdowy protokół warstwy aplikacji do przesyłania
-v. - _ l,LA^it nriiriAra TT"* "P.
plików, który używa TU .
RFC 977 Network News Transfer Protocol Proponowany standard Opcjonalny
Protokół warstwy aplikacji, za pomocą którego wiadomości sieci Usenet są przesyłane mię-
dzy komputerami poprzez TCP. Używany zarówno przez klientów komunikujących się z
serwerami wiadomości, jak i przez serwery wiadomości porozumiewające się między sobą.
RFC 1034 RFC 1035 STD 13 Domain Name System L .. Standard Zalecany
Zbiór oprogramowania rozproszonego, za pomocą którego łatwe do zapamiętania dla ludzi
nazwy węzłów, takie jak www.oreilly.com, są tłumaczone na liczby, które są zrozumiałe dla
komputerów, na przykład 198.112.208.11. Standard definiuje, jak serwery nazw domen w ró-
żnych węzłach sieci komunikują się ze sobą, używając UDP.
RFC 1112 Host Extension for IP Multicasting Standard Zalecany
Metody warstwy internetowej, za pomocą których zgodne systemy mogą przesłać jeden
pakiet do wielu węzłów. Jest to nazywane multicastingiem. Rozdział 14. wyjaśnia, w jaki
sposób Jayą obsługuje multicasting.
RFC 1153 Digest Message Format for Maił Eksperymentalny Ograniczone zastosowanie
Format do łączenia w jedną wiadomość wielu korespondencji skierowanych na jedną listę
pocztową.
RFC 1288 Finger Protocol Szkic standardu Opcjonalny
nie t0khiWarStWy aPlikacii do żądania informacji o użytkowniku zdalnej witryny. Potencjal-
^^J1:5133 Network Time Protocol (Yersion 3)
kt. ^niejszy protokół warstwy aplikacji do synchronizowania zegarów między sysb
e starają się uwzględnić opóźnienie sieciowe.
Szkic standardu j Opcjonalny
:emami,
Dokończenie tabeli na str. 46
46
Rozdział 2: Podstawowe pojęcia dotyczące s/eC(
Dokończenie tabeli ze str. 45
Tabela 2-2. Wybrane internetowe dokumenty RFC
RFC Tytuł Poziom rozwoju Poziom wymagań
RFC 1350 STD33 Trivial File Transfer Protocol Standard Opq'onalny
Nieuwierzytelniany protokół warstwy aplikacji do przesyłania plików w oparciu o UDP. Za-
zwyczaj wykorzystywany na staq'ach roboczych, które nie mają dysku do pobierania plików
potrzebnych do inicjalizagi serwera.____________________
RFC 1738
Uniform Resource Locators
! Proponowany Opcjonalny
standard
Pełne adresy URL, takie jak http://wwwamnesty.org/ orazftp://ftp.dnaicom/users/c/cityjava/javaio.htm.
RFC 1808
Relative Uniform Resource Locators
' Proponowany
standard
Opcjonalny
Względne adresy URL, takie jak Ijayafaąjbooksj oraz ../exumples/07/index.html, używane jako
wartości atrybutu HREF elementu A w języku HTML.
RFC 1939
STD53
Post Office Protocol, Yersion 3
Standard
Opq'onalny
Protokół warstwy aplikaq'i używany przez tymczasowo podłączone klienty poczty elektro-
nicznej, takie jak Eudora, do pobierania korespondenci z serwera poprzez TCP.
RFC 1945 | HyperText Transfer Protocol (HTTP 1.0) Informacyjny
Wersja 1.0 protokołu warstwy aplikaq'i wykorzystywanego przez przeglądarki komuni-
kujące się z serwerami WWW poprzez TCP. Rozwijany przez W3C, a nie przez IETF.
RFC 2045 RFC 2046 RFC 2047 Multipurpose Internet Maił Extensions Szkic Opcjonalny standardu
Opisuje znaczenie zakodowanych danych binarnych i tekstu innego typu niż ASCH w transmisjach
pocztą elektroniczną Internetu oraz znaczenie innych protokołów zorientowanych na kod ASCII- __
RFC 2068
Hypertext Transfer Protocol (HTTP 1.1)
Proponowany
standard
Opq'onalny
Wersja 1.1 protokołu warstwy aplikacji wykorzystywanego przez przeglądarki komuni-
kujące się z serwerami WWW poprzez TCP.____________________________
RFC 2141
Uniform Resource Names (URN) Syntax Proponowany ; Opq'onalny
standard
Podobny do adresu URL, ale przeznaczony do odwoływania się do aktualnych zasobów
w sposób stały, a nie do tymczasowej lokalizacji tych zasobów._________
RFC 2396
Uniform Resource Identifiers (URI):
Generic Syntax
Proponowany
standard
Opcjonalny
Podobny do adresu URL, ale skraca ścieżkę. Na przykład numery ISBN mogą być adresami
URI, nawet jeśli książki nie można pobrać przez Internet.__________________^_____
47
Pomimo
l^t^standardy
jziała poza areną publiczną, kodyfikując stan istniejący w praktyce.
IE* . iania IETF są zupełnie jawne, zazwyczaj nie towarzyszy im rozgłos. Po pro-
że "^ mało osób interesuje się arkanami sieci, takimi jak IGMP (ang. Internet Gate-
SW ZMessaee Protocol - protokół przesyłania wiadomości gatewayami Internetu).
V3^ ażnie w pracach IETF uczestniczą inżynierowie i naukowcy-informatycy,
Z- ni zarówno z ośrodkami akademickimi, jak i dużymi światowymi firmami
zvvią wionymi na zysk. Dlatego, pomimo wielu głośnych dyskusji na temat ideal-
113 h implementacji, większość poważnych prac IETF zaowocowała rozsądnymi
standardami.
M' stery nie można powiedzieć, że wysiłki IETF przyniosły jakieś rezultaty w dzie-
j -nie WWW (w przeciwieństwie do prac w dziedzinie Internetu). W szczególności
ątkowe starania IETF, aby dokonać standaryzacji HTML-a, zupełnie się nie po-
vviodłv- Głównie dlatego, że Netscape i inni kluczowi sprzedawcy nie chcieli uczest-
niczyć' w tym procesie lub choćby respektować jego rezultatów. HTML był na tyle
prosty i dopracowany, by przyciągać uwagę różnego rodzaju gigantów rynkowych,
a przypadkowi zapaleńcy wcale by tu nie pomogli. Dlatego w październiku 1994
roku powstała kontrolowana przez handlowców organizacja W3C i być może jej uda
się uniknąć trudności, które uniemożliwiły IETF standaryzację HTML-a.
Rekomendacje W3C
Proces standaryzacji przeprowadzany przez W3C jest podobny do metody IETF
(szereg roboczych opracowań jest publikowanych na listach pocztowych, które
owocują ewentualnymi standardami). Pomimo tych podobieństw W3C jest całkowi-
cie odmienną organizacją. Podczas gdy IETF jest otwarte dla wszystkich, członkami
W3C mogą być jedynie korporacje i organizaq'e. Uczestnictwo osób indywidualnych
jest wykluczone. Co więcej, choć organizacje, takie jak WWWAC (ang. WWW Artists
Consortium - stowarzyszenie artystów WWW), mogą należeć do W3C, to jedynie sta-
li pracownicy tych organizacji mogą uczestniczyć w działaniach W3C. Ich członko-
wie-ochotnicy nie są tam mile widziani. Do pracy w niektórych grupach roboczych
są czasami zapraszani eksperci w jakiejś dziedzinie, nawet nie będący etatowymi
pracownikami firmy stowarzyszonej w W3C. Jednak jest ich niewielu w porównaniu
z liczbą zainteresowanych specjalistów z grona pozostałej społeczności. Członko-
stwo w W3C kosztuje 50 000 dolarów rocznie (5000 rocznie dla organizacji nieko-
mercyjnych) i minimalnie trwa trzy lata. Przynależność do IETF jest bezpłatna i nie
narzuca żadnych zobowiązań. I chociaż w opracowywaniu standardów W3C
uczestniczy wiele osób, ostateczna decyzja o zatwierdzeniu lub odrzuceniu należy
d jednego człowieka, do dyrektora W3C Tima Bernersa-Lee. Standardy IETF są
Przyjmowane większością głosów opracowujących je osób. Jak widać, IETF jest or-
ganizacją znacznie bardziej demokratyczną (niektórzy powiedzieliby anarchi-
styczną) i otwartą niż W3C.
^/ wbrew silnie nieprzychylnemu nastawieniu swoich członków-korporacji, któ-
y płacą jej rachunki, jak na razie radzi sobie lepiej niż IETF na politycznie mętnych
aach standaryzacji WWW. Wypracowała kilka standardów HTML-a, a także in-
"y*, na przykład HTTP, PICS, XML, CSS, MathML itd. Znacznie mniej sukcesów
#___________________________^Rozdzial_2^Podstawowe pojęcia dotycząceg^
odniosła w nakłanianiu sprzedawców, takich jak Netscape i Microsoft, do pełne?
i konsekwentnego respektowania jej standardów.
W3C ma pięć podstawowych poziomów standardów:
Rekomendacja
Jest to najwyższy poziom standardów W3C. Jednak W3C bardzo pilnuje się, aby
nie nazywać tego "standardem" z obawy przed popadnięciem w konfljU
z prawem antymonopolowym. Opisuje rekomendację jako "pracę reprezentująca
wspólne stanowisko W3C, opatrzone zatwierdzającym stemplem dyrektora
W3C uważa, że pomysły i technologie opisywane przez rekomendację nadają sie
do rozpowszechniania i promowania przez W3C".
Proponowana rekomendacja
Proponowana rekomendaq'a jest w zasadzie kompletna i ewentualnie może wy-
magać tylko niewielkich zmian. Podstawowym zadaniem na tym etapie jest po-
prawienie błędów w dokumentacji, a nie w samej technologii.
Kandydatura na rekomendację
Ten poziom oznacza, że grupa robocza porozumiała się we wszystkich zasadni-
czych kwestiach i jest gotowa na przyjęcie zgłaszanych komentarzy i implemen-
tacji od osób trzecich. Jeśli nie zostaną odkryte żadne poważne przeszkody,
specyfikacja będzie mogła awansować na poziom proponowanej rekomendacji.
Szkic roboczy
Szkic roboczy jest odzwierciedleniem aktualnego stanowiska członków grupy
roboczej (wszystkich lub niektórych). Może z czasem osiągnąć poziom propono-
wanej rekomendacji, ale zanim do tego dojdzie, zwykle wymaga poważnych
zmian.
Notatka
Notatka jest jedną z dwóch rzeczy - spontanicznym pomysłem członka W3C (po-
dobna do szkicu internetowego IETF) albo zaimprowizowaną propozycją perso-
nelu W3C lub stowarzyszonych grup, która na razie nie opisuje pełnej koncepcji
(podobna do informacyjnego RFC grupy IETF). Notatki nie zawsze prowadzą do
zawiązania grupy roboczej lub opracowania rekomendacji W3C.
W3C jeszcze nie istnieje na tyle długo, aby pojawiła się potrzeba zdefiniowania po-
ziomu informacyjnego lub historycznego dla standardów. Od IETF różni się ponad-
to tym, że jeśli rozpocznie proces standaryzaq'i (to znaczy uformuje grupę roboczą),
to zazwyczaj doprowadza go do etapu pełnej rekomendacji. Natomiast IETF zgroma-
dziła już na swoim koncie ponad tysiąc zaproponowanych standardów i szkiców, ale
tylko kilka tuzinów obowiązujących.
HHIfi&Z*!*^-
49
Standardy rzeczników prasowych
'mi czasy procesy standaryzacyjne zarówno W3C, jak i IETF, były naduży-
3 nrzez firmy szukające łatwej reklamy w prasie lub starające się zwiększyć
wanef "a swoje akcje giełdowe. Wiadomo, że IETF przyjmie propozyq'e od wszyst-
PPy W3C od wszystkich swoich członków. IETF sklasyfikuje je jako szkice inter-
we i będzie publikować przez sześć miesięcy, zanim je wyrzuci. W3C będzie je
"kreśląc jako "propozyq'e przyjęte do wiadomości" i publikować na takich samych
sadach jak IETF. Jednak żadna z tych organizaqi nie obiecuje, że poza przyję-
ciem tych dokumentacji zrobi coś więcej. W szczególności nie obiecują sformowa-
nia grup roboczych ani rozpoczęcia procesu standaryzacji. Pomimo tego
w doniesieniach prasowych o produktach jakichś firm niezmiennie przecenia się
znaczenie przedłożenia takich dokumentacji. Rzecznicy prasowi mogą jedynie li-
czyć na pozyskanie przynajmniej kilku mniej ważnych reporterów, którzy nie
znają się na szczegółach przebiegu procesu standaryzaqi. Ty jednak powinieneś
już być w stanie rozpoznać takie manipulacje.
3
Podstawowe pojęcia
dotyczące sieci WWW
W tym rozdziale:
Identyfikatory URI
HTML, SGML i XML H
HTTP
MIME
CGI
Aplety i bezpieczeństwo
Mam nadzieję, że kiedy przeczytasz tę książkę, zrozumiesz, iż w Javie można zrobić
znacznie więcej niż tworzyć błyskotliwe strony WWW. Nie zmienia to faktu, że jed-
nak wiele twoich programów będą stanowiły aplety zagnieżdżone w stronach
WWW lub programy komunikujące się z serwerami WWW w celu pobrania plików
lub przekazania danych. Dlatego tak ważne jest, abyś dobrze rozumiał, jak przebie-
ga oddziaływanie między serwerami WWW a przeglądarkami.
HTrp (ang- Hypertext Transfer Protocol - protokół przesyłania hipertekstu) jest stan-
dardem, który definiuje, jak klienty WWW porozumiewają się z serwerami i w jaki
sposób odsyła się dane klientowi. Podstawą HTTP są dwa inne standardy: MIME
ang. Multipurpose Internet Mail Extensions - uniwersalne rozszerzenie internetowej
poczty elektronicznej) i HTML (ang. Hypertext Markup Language - hipertekstowy ję-
zyk znakowania informacji).
w c , '6St metoda. kodowania różnych rodzajów danych, takich jak dźwięk i tekst,
kiee U P',zes*ania icn 7-bitowym łączem ASCII. Pozwala też odbiorcy stwierdzić, ja-
Vv żarn ,Z3'U dane zostaty przesłane, dzięki czemu można je właściwie wyświetlić.
Poczty^ ^autorow MIME, jak wskazuje nazwa, ma ułatwić obsługę multimedialnej
Pchnąć^6 cznei oraz dostarczyć takiego kodowania, które pozwalałoby prze-
acJach w!?"6 blnarne Przez programy do transferu poczty elektronicznej w sytu-
Znalazfo^ma8a'ących naiwi?kszeg wysiłku umysłowego. Obecnie jednak MIME
mantycznCZe inne zastosowariia- HTML jest prostym standardem opisującym se-
^główek" Strnę danycn tekstowych, co oznacza, że można wskazać "to jest
' //to jest lista", "a to należałoby wyróżnić" itp., ale nie można określić, jak
52_________________________Rozdział 3: Podstawowe pojęcia dotyczące s/eg i/y^
nagłówki, listy i wyróżnienia mają zostać sformatowane, gdyż formatowaniem ?
muje się przeglądarka. HTML jest "hipertekstowym językiem znakowania inform'"
cji", ponieważ daje nam możliwość określenia łączy do innych dokumentó
identyfikowanych poprzez adresy URL. Adres URL jest jednoznacznym sposobe '
wskazania lokalizacji zasobów w Internecie. Aby zrozumieć programowanie sietiow
musisz najpierw poznać adresy URL, HTML, MIME i HTTP nieco głębiej niż pr? '
ciętny projektant stron WWW.
URI
URI (ang. Uniform Resources Identifier- jednolity identyfikator zasobów) jest ciągien.
znaków o określonej składni, który identyfikuje zasoby. Identyfikowane zasoby
mogą być plikiem na serwerze, ale także adresem e-mail, wiadomością grup dys-
kusyjnych, książką, czyimś nazwiskiem, internetowym hostem, aktualną ceną giełdowa
akcji firmy Sun Microsystem itp. Bezwzględny identyfikator URI składa się z dwóch
części: jedna określa system dla URI, druga to część specyficzna dla systemu. Od-
dzielone są dwukropkiem w następujący sposób:
system: część- specyf'iczna-dl a- systemu
Składnia części specyficznej dla systemu zależy od stosowanego systemu. Możliwe
jest jeszcze zdefiniowanie wielu różnych systemów, a do istniejących zaliczamy:
data
Dane zakodowane w formacie Base64 zawarte bezpośrednio w łączu; zobacz
RFC 2397.
file
Plik na dysku lokalnym.
3 y -Si. V',- ?< . ' .i-.- ; -.
FTP ',^'^-, '. -., .. ,'---
Serwer FTP.
HTTP |,,,.:-^ ' ./;:,>,'.=.-.:
Serwer WWW wykorzystujący HTTP. te ; ,.-,;'
gopher ; .-<-w '-. -.-' -..\-- ,
Serwer Gopher. "),.>!'.H ... - '.'.' ',' '. . .
mailto
Adres poczty elektronicznej. t,.~^.':~. i-: . ;
news '^-'.'''- ><: ;r ".^ - ,~
Grupa dyskusyjna sieci Usenet. J*-" ' - *?; -:
Telnet '',
t' | VJ*Ł 'f'-.'*' j, ' ', ' -"- : '
Połączenie z usługą opartą na Telneoe.,
*-* l j< ^ -, f* j^ '":.' ' ':''-'.
urn :,.,i.x .,,. .... ......
Jednolita nazwa zasobów.
Poza tym Java intensywnie wykorzystuje do różnych celów niestandardowe, spe^
ficzne systemy, takie jak rmi,jndi oraz doc. Stojący za t\'m mechanizm poznamy w ro
Ufll
^-
Klasa URLConnection", w którym zostały omówione programy obsługi
dziale 15- **
Prot tk'ch identyfikatorów URI nie istnieje żadna typowa składnia części specy-
pla vfS^S vstemu. Natomiast wiele z nich jest zgodnych z następującym formatem:
ficznej C"a sy
/w-Kona^/ścietka?zaPytanie
konawca identyfikatora URI wskazuje, kto odpowiada za rozwiązanie po-
Cz?śc *^zęści adresu. Na przykład w identyfikatorze URI http://www.ieft.org/rfc/
ZOSn96txt systemem jest http, a wykonawcą www.ieft.org. To oznacza, że serwer
rfc2 .uor" jest odpowiedzialny za odwzorowanie ścieżki /rfc/rfc2396.txt na ist-
urriW 2asc,by. Ten identyfikator URI nie ma części dotyczącej zapytań. Z kolei w iden-
nifikatorze URI http://wwwl.fatbrain.com/asp/bookinfofbookinfo.asp?theisbn=1565924851 syste-
^' >st http, wykonawcą wwwl.fatbrain.com, ścieżką /asp/bookinfo/bookinfo.asp, a za-
' . , -f r-/- r-t-fl A nn M~j...innl. ,.-, i .4nJ^T&1^~.l.n.r~ A T TT?T * ,*. .~V,L.~. . "ł C^CnO /f OET1
me:
taniem theisbn=1565924851. Natomiast w identyfikatorze URI urn:isbn: 1565924851
temem jest urn, ale pozostała część nie jest zgodna z formatem //wykonawca/
ścieżka ?zapytanie części specyficznej dla systemu.
Chociaż w obecnie używanych egzemplifikacjach identyfikatorów URI wykonawcą
jest host Internetu, nie musi tak być we wszystkich przyszłych systemach. Jeśli jed-
nak wykonawcą jest host internetowy, możliwe jest podanie opcjonalnych nazw
użytkownika i portów w celu uściślenia wykonawcy. Na przykład w adresie
ftv://mp3:mp3@ci43198-a.ashvill.nc.home.com:33/VanHalen-Jump.mp3 wykonawcą jest
mp3:mp3@ci43198-a.ashvill.nc.home.com:33. Nazwą użytkownika dla tego wykonaw-
cy jest mp3, hasłem mp3, hostem ci43198-a.ashvill.nc.home.com, a portem 33. Syste-
mem jest tu ftp, a ścieżką/'VanHalen-Jump.mp3. (W większości przypadków wstawia-
nie hasła do identyfikatora URI, jak tutaj, poważnie narusza zasady bezpieczeństwa,
chyba że naprawdę chcesz, aby wszyscy we wszechświecie poznali to hasło).
Ścieżka (otwierana ukośnikiem) jest ciągiem znaków, na podstawie którego wyko-
nawca może stwierdzić, o jakie zasoby chodzi. Różni wykonawcy, interpretując tę
samą ścieżkę, mogą wskazywać różne zasoby. Na przykład ścieżka /index.html ozna-
cza coś innego, gdy wykonawcą jest www.georgewbush.com niż wtedy, gdy jest nim
części są oddzielone ukośnikami, a operatory . oraz . . służą do poruszania się po
tej hierarchii. Taka składnia ścieżki pochodzi z uniksowych systemów operacyj-
nych, na których opracowano WWW i adresy URL. Odwzorowywała ona system
plików uniksowego serwera WWW. Jednak nie ma żadnej gwarancji, że także obec-
nie elementy którejś ścieżki odpowiadają plikom lub katalogom jakiegoś konkretne-
go systemu plików. Na przykład w identyfikatorze URI http://www.amazon.com/
e^c/bidos/ISBN%3D1565924851/cafeaulaitA/002-3777605-3043449 wszystkie elementy
arcnn służą jedynie do wyciągnięcia informacji z bazy danych, która nigdy nie jest
^Pisywana w systemie plików. ISBN%3D1565924851 wybiera z bazy danych kon-
ną książkę poprzez wskazanie jej numeru ISBN. cafeaulaitA określa, kto będzie
002 r?C szty zamówienia, jeśli poprzez to łącze zostanie dokonany zakup.
i^ ., 6^5-3043449 iest kluczem sesji, który służy do prześledzenia w witrynie
^^odwiedzającego.
# __________________Rozdział 3^^^^ęp^^do^c^^eci^JW^
Oczii^cie niektóre identyfikatory URI wcale nie są hierarchiczne, przynajmniej
w t% sensie, w jakim hierarchiczny jest system plików. Na przykład identyfikator
sneu>jfcnews.netscape.com/netscape.devs-java ma ścieżkę /netscape.devs-java. l chociaż
w %'ach grup dyskusyjnych istnieje pewien rodzaj hierarchii, oznaczony kropką
mię^netscape a devs-java, to nie jest ona postrzegana jako część identyfikatora URI.
Częśj/stemowa identyfikatora składa się z małych liter, cyfr oraz znaku plus,
króli łącznika. Musi się zaczynać małą literą. Pozostałe trzy części typowego ad-
resm|tf (wykonawca, ścieżka i zapytanie) powinny składać się z alfanumerycz-
nyćlZjiaków ASCII, to znaczy liter A-Z, a-z oraz cyfr 0-9. Poza tym znaki przestan-
ko\uzyli - _ . ! ~ *' (oraz ) także mogą być używane. Wszystkie pozostałe znaki,
w ti^naki alfanumeryczne, ale nie ASCII (takie jak a oraz n), powinny być wsta-
wiają pomocą szesnastkowego kodu znaku poprzedzonego znakiem procenta
(%),kl> przykład a powinno zostać zakodowane jako %E1, a n jako %3CO. Drugi
przodek zakłada, że zestawem znaków, o który chodzi, jest 2-bajtowy Unikod.
Akijjlfly szkic specyfikacji URI nie podaje jeszcze sposobów określania, którego ze-
sta\u znaków należy użyć. To niedociągnięcie zostanie zapewne poprawione
w lipnym szkicu. Mówi się, że tak przekształcony adres URL ma format typu
"x-ww-form-url-encoded".
Zn|j( takie jak / oraz @, także muszą zostać zakodowane w notacji procentowej, je-
śli jjfiią inną funkcję niż ta, którą im przydzielono w specyficznej dla systemu czę-
ści(0]ikretnego adresu URL. Na przykład ukośniki w identyfikatorze URI http://me-
taliitflc.edu/javafacj/books/javaio/ nie muszą zostać zakodowane w postaci Tc2F, po-
nityjj służą do rozgraniczania elementów hierarchii, tak jak zostało to określone
w śremie http identyfikatorów URI. Jeśli natomiast nazwa pliku zawierałaby uko-
śni^na przykład gdyby ostatni katalog został nazwany Java I/O zamiast javaio, aby
le}ej odzwierciedlać tytuł książki - to adres URI powinien zostać zapisany nastę-
piw) http://metalab.unc.edu/javafaa/bookslJava%20I%2FO/. Nie jest to takie wyszuka-
neliby mogło się wydawać użytkownikom Uniksa lub systemu Windows. Nazwy
pli^v w komputerach Macintosh często zawierają ukośnik. Na wielu platformach
r%/ plików często zawierają inne znaki, które muszą zostać zakodowane, w tym
@t j-, = i wiele innych. , -
UIN :'';?','
Isjjeją dwa rodzaje identyfikatora URI: URL (ang. Uniform Resources Locator - jednoli-
tjijializator zasobów) oraz URN (ang. Uniform Resources Name - jednolita nazwa za-
s^)- URL wskazuje konkretne zasoby Interneru o konkretnej lokalizacji. Na
pzłr(J;ad http://wunv.oreilly.com/catalog/iavanp2/ jest jednym z kilku identyfikatorów
L'jj,ila książki Java. Programowanie sieciowe, wydanie drugie (dotyczy wydawnictwa
a^ykańskiego). URN jest nazwą konkretnego zasobu, ale bez odwołania do jego
kjjiretnej lokalizacji. Na przykład urn:isbn:1565928709 jest nazwą URN odnoszącą
sUi> tej samej książki. Jak widać na podstawie tego przykładu, nazwy URN, w prze-
cj^ństwie do adresów URL, nie są ograniczone do zasobów internetowych.
tyfty URN wprowadzono w celu oznaczenia zasobów, które mogą powtarzać się
^,((ielu różnych lokalizacjach lub które zostały przeniesione z jednej witryny do
URI 55
drugiej. Nazwa ta identyfikuje same zasoby, a nie miejsce, w którym występują. Na
przykład program FTP, mając podaną nazwę URN konkretnego oprogramowania,
powinien pobrać plik z najbliższej witryny lustrzanej. Gdy podasz przeglądarce na-
zw? URN książki, może ona zarezerwować dla ciebie ten tytuł w miejscowej biblio-
tece lub zamówić jej egzemplarz w księgarni.
Nazwa URN ma następującą postać:
urn:przestrzeń_nazw:nazwa_zasobów
przestrzeń_nazw]est nazwą zbioru pewnego rodzaju zasobów przez kogoś gro-
madzonych i utrzymywanych, a nazwa_zasobów jest nazwą zasobu w tym zbio-
rze. Na przykład nazwa URN urn:isbn:1565924851 wskazuje na zasób o identyfikato-
rze 1565924851 w przestrzeni isbn. Ten identyfikator ze wszystkich opublikowanych
książek wybiera pierwszą edycję Jana I/O.
Dokładna składnia nazw zasobów zależy od przestrzeni nazw. Przestrzeń nazw
ISBN spodziewa się zobaczyć ciąg złożony z dziesięciu znaków będących wyłącznie
cyframi z jednym wyjątkiem: ostatnim znakiem może również być wielka litera X.
Za przydzielanie przestrzeni nazw różnym organizacjom jest odpowiedzialna
IANA, ale procedura nie jest jeszcze w toku. Nazwy URN są wciąż obszarem inten-
sywnych badań i w małym stopniu są wykorzystywane przez współczesne oprogra-
mowanie. Jak na razie numery ISBN są niemal jedynym opracowanym przykładem
i nawet one nie zostały oficjalnie wystandaryzowane jako nazwy URN. Dlatego
w pozostałej części tej książki będą wykorzystywane jedynie adresy URL. ,,
URL ii
Adres URL wskazuje lokalizację zasobu w Internecie. Określa on protokół używany
do uzyskania dostępu do serwera (na przykład FTP, HTTP), nazwę serwera oraz lo-
kalizację pliku na tym serwerze. Typowy adres URL wygląda następująco http://me-
talab.unc.edu/javafaq/javatutorial.html. Oznacza to, że na serwerze metalab.unc.edu
w katalogu javafaq istnieje plik o r\azvnejavatutorial.html, do którego można uzyskać
dostęp poprzez protokół HTTP. Składnia adresu URL jest następująca:
protokół://nazwa_użytkownika@nazwa_węzia:port/ścieżka/nazwa_pliku#fragment?zapytanie
Tutaj protokół (określenie z dokumentacji Javy) jest tym samym co system (okre-
ślenie z RFC identyfikatora URI) w identyfikatorze URL W adresie URL protokołem
może być file, ftp, http, https, gopher, news, Telnet, wais lub różne inne ciągi znaków
(lecz nie urn).
Na z wa_ we zła w adresie URL jest nazwą serwera, który dostarcza żądanych zasobów,
taką jak www.oreilly.com lub utopia.poly.edu. Może ona mieć postać adresu IP serwera,
taką jak 204.148.40.9 lub 128.238.3.21. Z kolei nazwa_użytkownika jest opcjonalną
nazwą użytkownika serwera. Numer portu też jest opcjonalny. Nie jest konieczny, jeśli
usługa działa na swoim domyślnym porcie (porcie 80 dla serwerów HTTP).
Ścieżka wskazuje konkretny katalog na wybranym serwerze. Jest względna w sto-
sunku do głównego drzewa dokumentów serwera, ale niekoniecznie w stosunku do
głównej gałęzi systemu plików serwera. Regułą jest, że w ogólnie dostępnych serwe-
rach niecały system plików jest widoczny dla klienta. Raczej ukazują tylko zawar-
tość wybranego katalogu. Ten katalog jest nazywany głównym drzewem doku-
mentów, a wszystkie ścieżki i pliki są określone względem niego. Tak więc na unik-
sowych stacjach roboczych wszystkie pliki, które są dostępne publicznie, mogą znaj-
dować się w katalogu /var/public/html, ale dla kogoś łączącego się ze zdalnej
maszyny ten katalog wygląda jak główna gałąź systemu plików.
Nazwa_pliku wskazuje konkretny plik w katalogu określonym za pomocą ścieżki.
Często jest ona pomijana, a wtedy serwer sam decyduje, który plik, jeśli w ogóle jaki-
kolwiek, ma wysłać. Wiele serwerów wysyła plik indeksu dla tego katalogu, często
nazywany index.html lub Welcome.html. Inne serwery wysyłają listę plików i folderów
w katalogu, jak pokazuje rysunek 3-1. Jeszcze inne serwery mogą wysłać komunikat
błędu 403, jak na rysunku 3-2.
jK|ndex of /xml/books - Netscape
File Etiit View BO Communicata H_elp
M Back : Reload Home Seatch Netscape Print
:; ,!* Bookmatks J^ Location: |hltp://picasso.pi.com.pl/xml/bccks/

Security Shop
~T] (F^* Whafs Relaled
Index of/xml/books
Haine
Last modified Size Description
J
^^ Pairent Directory
LJ bibie/
IwJ xtnl/
16-Dec-2000 19:57
16-Dec-2000 19:56
16-Dec-2000 19:56
'i=ĆtR
ipocimenFDone
d
*?. ms& ,-:
Rysunek 3-1. Serwer WWW skonfigurowany do wysyłania listy katalogów, gdy nie istnieje p ik z indeksem
I&403 Foibidden - Netscape [^TfnrKl
File Edil View Go Communicatoi Help p Back ': .:: Reload Home Seach Netscape Print Secuiity Stop ^|
;: ,^0 Bookmarks ^. Location: jhttp://picasso.pi. com.pl/xml/bcck2/ _^j (f^'What'sRelaled
___, ,"" ",
Forbidden You don'thave permission to access /xml/books/ onthis ser?er. d
bfP :=^ft= :Docunrr*: Done j?;^t. ^. iiś> eg ^
Rysunek 3-2. Serwer WWW skonfigurowany do wysyłania komunikatu błędu 403, gdy nie is:nie;e plik z indeksem
fragment służy do odwoływania się do nazwanego punktu zakotwiczenia w do-
kumencie HTML. Niektóre dokumentacje określają tę część adresu URL jako sekcję.
W dokumentacji Javy dość nieoczekiwanie sekcje są nazywane Ref. Nazwany punkt
zakotwiczenia powstaje w dokumencie HTML, gdy wstawimy znacznik taki jak ten:
Komentarze
Ten znacznik definiuje konkretny punkt dokumentu. Aby odwołać się do tego miej-
sca, adres URL musi zawierać nie tylko nazwę pliku z dokumentem, ale także na-
zwany punkt zakotwiczenia, oddzielony od reszty adresu znakiem hasha (#):
http://etalab.unc.edu/javafaq/javafaq.html#xtocidl902914
Wreszcie, ciąg znaków zapytanie podaje serwerowi dodatkowe argumenty. Na
ogół jest on stosowany w adresach 'http; zawiera dane formularza dla programów
CGI. To zagadnienie zostało szerzej omówione w dalszej części książki.
Względny URL
Adres URL dostarcza przeglądarce wielu informacji o dokumencie. Dzięki niemu
przeglądarka zna protokół zastosowany do pobrania dokumentu, nazwę hosta, z którego
pochodzi dokument, oraz ścieżkę prowadzącą do dokumentu w hoście. Większość
tych informacji jest prawie taka sama jak w innych adresach URL, do których
odwołujemy się w tym dokumencie. Zatem nie każdy adres URL musi zostać okre-
ślony w całości, gdyż może odziedziczyć informację o protokole, nazwie hosta i ście-
żce po swoim dokumencie macierzystym (to znaczy dokumencie, w którym się poja-
wia).
Adresy URL, które nie są kompletne, ale dziedziczą fragmenty po dokumencie ma-
cierzystym, są nazywane adresami względnymi. Natomiast kompletnie określony
URL nazywamy adresem bezwzględnym. W adresie względnym zakłada się, że
wszelkie brakujące fragmenty są takie same jak odpowiadające im części adresu
URL dokumentu, w którym występuje adres względny. Na przykład przypuśćmy,
że przeglądając stronę http://metalab.unc.edu/javafaq/javatutorial.html, klikniesz nastę-
pujące łącze:

Twoja przeglądarka odetnie nazwę pliku javatutorial.html z adresu http://meta-
lab.unc.edu/javafaq/javatutoruil.html, uzyskując w ten sposób człon http://meta-
lab.unc.edu/javafaq/. Następnie na końcu tego ciągu dołączy ljavafaq.html, uzyskując
http://metalab.unc.edu/javafaq/javafaq.html. Potem załaduje ten dokument.
Jeśli łącze względne zaczyna się znakiem /, to jest ono określone względem głównego
drzewa dokumentów zamiast względem bieżącego pliku. Zatem, jeżeli przeglądając
plik http://metalab.unc.edu/javafaq/javatutorial.html, klikniesz następujące łącze:

to twoja przeglądarka odrzuci człon /javafaq/javatutorial.html i doda na końcu /boutell/
faq/www_faq.html, w rezultacie powstanie adres http://metalab.unc.edu/boutell/faq/
www_faq.html.
58__________________________Rozdział 3: Podstawowe pojęcia dotyczące s/eg H^%
Adresy względne mają wiele zalet. Pierwszą, choć może nie najistotniejszą, jest to, że
masz trochę mniej do wpisywania. Ważniejszą zaletą jest fakt, że względne adresy
URL umożliwiają wielu protokołom, na przykład FTP i HTTP, posługiwanie się hie-
rarchiczną strukturą pojedynczego dokumentu. Protokół HTTP może zostać \wko-
rzystany do bezpośredniego nawigowania, a FTP do stworzenia lustrzanego odbicia
witryny. Jednak najistotniejsze jest to, że adresy względne pozwalają na przenosze-
nie lub kopiowanie całej drzewiastej struktury dokumentów HTML z jednej witryny
do drugiej bez naruszania przy tym wszystkich wewnętrznych łączy.
HTML, SGML i XML
HTML jest podstawowym formatem stosowanym w dokumentach sieci WWW. Jak
napisałem już wcześniej, jest on prostym standardem opisywania semantycznej za-
wartości danych tekstowych. Pomysł opisywania semantyki tekstu zamiast jego
wyglądu wziął się ze starszego standardu zwanego SGML-em (ang. Standard Genera-
lized Markup Language - standardowy uogólniony język znaczników). Standardowy
HTML jest przypadkiem SGML-a. W połowie lat siedemdziesiątych Charles Gold-
farb z firmy IBM zaczął pracować nad SGML-em. Teraz SGML jest standardem ISO
(ang. International Standard Organization -Międzynarodowa Organizacja Normaliza-
cyjna), określonym jako ISO 8879:1986.
Podstawowym założeniem SGML-a, w konsekwencji i HTML-a, jest przedstawienie
znaczenia, a nie wyglądu informacji. Nie stwierdzasz, że chcesz jakiś tekst napisać
czcionką 18-punktową, tylko że ma to być nagłówek najwyższego poziomu (


w HTML-u). Podobnie nie wskazujesz, że słowo ma zostać napisane czcionką po-
chyloną, lecz że ma zostać wyróżnione ( w HTML-u). To, jak najlepiej wyświe-
tlić nagłówki lub wyróżnić tekst, pozostaje w gestii przeglądarki.
W znacznikach stosowanych do oznaczania tekstu istotna jest wielkość liter. Zatem
znacznik nie jest tym samym co ani . Niektóre
znaczniki posiadają do pary znacznik zamykający, aby można było zaznaczać frag-
menty tekstu. Znacznik zamykający jest taki sam jak znacznik otwierający oprócz
tego, że po otwierającym nawiasie ostrokątnym występuje ukośnik. Na przykład
to jest tekst pogrubiony; to jest: tekst
wyróżniony
. Cały tekst pomiędzy znacznikiem początkowym a znaczni-
kiem końcowym jest nazywany elementem. Zatem to jest tekst
pogrubiony
jest elementem STRONG.
Elementy HTML mogą być zagnieżdżane, ale nie powinny się przeplatać. Pierwsza
z poniższych linii jest zgodna ze standardem, a druga nie, niemniej jednak wiele
przeglądarek może ją zaakceptować:
Tańcowały dwa Michały
jeden duży, drugi rnaiy
Niektóre elementy mają dodatkowe atrybuty, zakodowane w znaczniku początko-
wym w postaci pary nazwa-wartość. Znacznik

i większość znaczników okre-
ślających poziom akapitu może posiadać atrybut ALIGN, który mówi, czy tekst ma
zostać wyśrodkowany, wyrównany do lewej lub do prawej.
59
Naprzykład:
=CENTER> Ten tekst jest wyśrodkowanym nagłówkiem Hl
- trybutu może zostać umieszczona w pojedynczym lub podwójnym cu-
^słowie jak poniżej:
i="CENTER"> Ten tekst jest wyśrodkowanym nagłówkiem Hl
<:Hl AL" i='LEFT'> Ten tekst jest wyrównanym do lewej nagłówkiem H2


słowy są potrzebne tylko wtedy, kiedy wartość zawiera spacje. Gdy przetwa-
CU Zdokurnenty HTML, musisz liczyć się z tym, że istnieją wartości atrybutów, któ-
'Trnają cudzysłowy, i takie, które ich nie mają.
z lata pojawiło się wiele wersji HTML-a. Obecnie obowiązującym standardem
t HTML 4.0, prawie w całości obsługiwany przez dzisiejsze przeglądarki WWW
^nielicznymi wyjątkami. Co więcej kilka firm, w szczególności Netscape, Microsoft
. gun dodały do HTML-a niestandardowe rozszerzenia. Może to być migający tekst,
filmiki w dokumencie, ramki i, co dla nas najważniejsze, aplety. Niektóre z tych roz-
szerzeń - na przykład znacznik - są dopuszczalne w HTML-u 4.0, ale nie
zalecane. Inne, takie jak powszechnie znany firmy Netscape, wykraczają
poza dopuszczalne granice i nie ma dla nich miejsca w znaczeniowo zorientowanym
języku, jakim jest HTML.
Być może HTML 4.0 jest już słowem ostatecznym, ewentualnie z niewielkimi po-
prawkami. Organizacja W3C uznała, że HTML tak się rozrósł, że nie można posze-
rzać go o dodatkowe funkcje. Zaś nowe projekty skupią się na XML-u, seman-
tycznym języku, który umożliwia projektantom stron tworzenie potrzebnych im
elementów, a nie tylko korzystanie z kilku ustalonych, takich jak P oraz LI. Na
przykład jeśli piszesz stronę WWW z listą cen, powinieneś mieć element
SYGNATURA, element CENA, element PRODUCENT, element PRODUKT itd. Mogłoby to
wyglądać następująco:

l-2-3
5 . CK/WERS JA>
Windows
299,95
D05WGM!X/SYGNATURA>

Wyglądem przypomina to HTML, podobnie jak Java przypomina język C. Istnieją tu
eernenty i atrybuty. Znaczniki są ograniczane znakami < oraz >. Atrybuty są
'"nieszczone w cudzysłowach itd. Natomiast nie ma tu ograniczenia do skończone-
f ,2estawu znacznikow- Możesz utworzyć takie znaczniki, jakich potrzebujesz
ki h6' Potrzebujesz. Ponieważ żadna przeglądarka nie może z góry znać wszyst-
w' , mentów' które mogą się pojawić, stosowany jest arkusz stylu opisujący,
)aki sposób należy wyświetlić każdy z elementów.
^Lma
w tak ]eszcze Jedna przewagę nad HTML-em, która być może nie ujawnia się
nie s PrStym P^ykładzie. HTML jest dość niechlujny. Elementy są otwierane, ale
dzv ? Zamykane- Wartości atrybutów mogą być w cudzysłowach lub bez nich. Cu-
ysiowy można Zamknać albo nie.
60______________ Rozdział 3: Podstawowe pojęcia dotyczące sieci WWW
W XML-u o wszystko zostało uporządkowane. Ma on bardzo dokładnie określone
zasady budowy poprawnych składniowo dokumentów XML i wymaga, aby
wszystkie niepoprawne dokumenty zostały odrzucone przez przeglądarkę. Prze-
glądarka nie może próbować rozwiązać problemu i w najlepszej wierze wyświetlać
tego, co jej się wydaje, że autor miał na myśli. Po prostu musi zgłosić błąd. Oprócz
tego dokument XML może zawierać DTD (ang. Document Type Definitwn - definicja
typu dokumentu), która narzuca dodatkowe ograniczenia poprawnym struktural-
nie dokumentom XML. Na przykład DTD może stanowić, że każdy element
PRODUKT będzie zawierać dokładnie jeden element NAZWA. Ma to wiele zalet, ale
kluczową jest fakt, że dokumenty XML są znacznie łatwiejsze do parsowania niż do-
kumenty HTML. Jako programista z pewnością stwierdzisz, że praca w XML-u jest
znacznie łatwiejsza niż w HTML-u.
XML może być wykorzystywany zarówno do stron w czystym XML-u, jak i do za-
gnieżdżania nowych rodzajów zawartości w HTML-u. Na przykład MathML (ang.
Mathematical Markup Language - język znakowania danych matematycznych) jest
aplikacją XML, która służy do zamieszczania równań matematycznych na stronach
WWW. SMIL (ang. Synchronized Multimedia Integration Language - zintegrowany ję-
zyk synchronizowanych multimediów) jest aplikacją XML przeznaczoną do wsta-
wiania na stronach WWW trwających w czasie przekazów multimedialnych, takich
jak pokazy slajdów i filmiki wideo z podtytułami. Więcej informacji na temat XML-a
znajdziesz w mojej książce The XML Bibie, IDG Books, 1999.
HTTP
HTTP (ang. Hypertext Transfer Protocol - protokół przesyłania hipertekstu) jest stan-
dardowym protokołem komunikacji między przeglądarkami i serwerami WWW.
Określa on, w jaki sposób klient i serwer ustanawiają połączenie, w jaki sposób
klient żąda danych od serwera, jak serwer odpowiada na to żądanie i wreszcie w jaki
sposób połączenie jest zamykane. Do transmisji danych połączenia HTTP wykorzy-
stują protokół TCP/IP.
Aktualnie akceptowaną wersją protokołu jest HTTP 1.0. Do kodowania danych wy-
korzystuje on MIME. Podstawowy protokół definiuje sekwencję czterech kroków
dla każdego żądania klienta od serwera:
1. Nawiązanie połączenia. Klient ustanawia połączenie TCP z ser%verem, domyśl-
nie w porcie 80. Inne porty mogą zostać określone w adresie URL.
2. Żądanie. Klient wysyła serwerowi komunikat z żądaniem strony o określonym
adresie URL. Zazwyczaj format tego żądania jest następujący:
GET Xindex.html HTTP 1.0
GET jest słowem kluczowym. /index.html jest względnym adresem URL
wskazującym plik na serwerze. Przyjmuje się założenie, że plik znajduje się na
maszynie, do której skierowano żądanie. Dlatego też nie trzeba poprzedzać jego
nazwy ciągiem http://www.tamaszyna.com/. HTTP 1.0 jest wersją protokołu rozu-
mianego przez klienta. Żądanie jest zakończone dwoma parami znaków powrót
HTTP_______________________________________________61
karetki/przesuw o wiersz (\r\n\r\nw terminologii Javy), niezależnie od tegOi
jaki jest znak końca linii na platformach klienta i serwera.
Chociaż wiersz typu GET jest wszystkim, co jest potrzebne, żądanie klienta moż(
również zawierać inne informacje. Mają one następujący format:
Słowokluczowe: Wartość
Najbardziej popularnym słowem kluczowym jest w tym kontekście Ac cep t, któ-
re informuje serwer, jakiego rodzaju dane klient może obsłużyć (jednak serwer)
często to ignorują). Na przykład poniższy wiersz mówi, że klient może obsłużyć
cztery typy MIME, odpowiadające dokumentom HTML, zwykłemu tekstów
oraz obrazkom JPEG i GIF:
Accept: text/html, text/plain, image/gif, image/jpeg
Innym popularnym słowem kluczowym jest User-Agent, dzięki któremu ser-
wer wie, jaka przeglądarka zostanie użyta. Pozwala to serwerowi wysłać pliki,
zoptymalizowane dla konkretnego rodzaju przeglądarki. Poniższy wiersz ozna-
cza, że żądanie pochodzi z przeglądarki Lynx w wersji 2.4:
User-Agent: Lynx/2.4 libwww/2.1.4
Wreszcie żądanie zakończone jest pustą linią, to znaczy dwoma parami znaków
powrót karetki/przesuw o wiersz, \r\n\r\n. Całe żądanie może wyglądać na-
stępująco:
GET Xindex.html HTTP 1.0
Accept: text/html ' ;
Accept: text/plain
User-Agent: Lynx/2.4 libwww/2.1.4
Oprócz żądania typu GET, istnieje kilka innych rodzajów żądań. HEAD pobiera je-i
dynie nagłówek pliku, bez żadnych danych. Zazwyczaj jest ono wykorzystywa-
ne do sprawdzania, czy dane lub plik uległy modyfikacjom, aby przekonać się,
czy kopia zapisana w schowku lokalnej maszyny jest nadal aktualna. POST
wysyła dane serwerowi, a PUT ładuje plik na serwer.
3. Odpowiedź. Serwer wysyła odpowiedź klientowi. Zaczyna się ona kodem odpo-
wiedzi, po którym występuje informacja nagłówkowa MIME, potem pusta linia,
a następnie żądany dokument lub komunikat błędu. Załóżmy, że żądany plik zo-
stał znaleziony, wtedy typowa odpowiedź będzie wyglądała podobnie do poniż-
szej:
HTTP 1.0 200 OK "' , : ;' :"< ' -
Server: NCSA/1.4.2 , . .... ', Ł
MIME-version: 1.0 . .
Content-type: text/html
Content-length: 107 ;''; '" ' -"
: :'
7"..,.. . <
' " ',.,.<br>Przykładowy plik HTML<br>nututiat j. roasiawowe pojęcia dotyczące sieci www<br>


Tutaj pojawia się reszta dokumentu


Pierwsza linia mówi, że protokołem, którego używa serwer, jest HTTP l. 0. Po
nim występuje kod odpowiedzi. 2 O O OK jest najbardziej typowym kodem odpo-
wiedzi, informującym, że żądanie zostało spełnione. Tabela 3-1 przedstawia
kompletną listę kodów odpowiedzi stosowanych w protokole HTTP 1.0. Lista dla
HTTP 1.1 zawiera dodatkowe pozycje. Pozostałe linie nagłówka identyfikują
oprogramowanie serwera (serwer NCSA wersja 1.4.2), wersję stosowanego
MIME, typ treści MIME oraz długość dostarczanego dokumentu (nie wliczając w
to długości samego nagłówka) - w tym przypadku jest to 107 bajtów.
4. Zamknięcie połączenia. Połączenie zamykają klient lub serwer albo obaj. Stąd
wynika, że dla każdego żądania wykorzystywane jest oddzielne połączenie sie-
ciowe. Jeżeli klient połączy się ponownie, serwer nie ma pojęcia o poprzednim
połączeniu lub jego rezultacie. Protokół, w którym nie są zapamiętywane po-
przednie żądania, jest nazywany protokołem bez pamięci stanu, natomiast proto-
koły z pamięcią stanu, takie jak FTP, mogą cofnąć się o wiele żądań sprzed
zamknięcia połączenia. Brak pamięci stanu jest zarówno wadą, jak i zaletą HTTP.
Tabela 3-1. Kody odpowiedzi protokołu HTTP 1.0
Kod odpowiedzi Znaczenie
2xx Successful
200 OK
201 Created
202 Accepted ,,,
204NoContent
Kody odpowiedzi o numerach od 200 do 299 oznaczają, że żądanie
zostało odebrane, zrozumiane i przyjęte.
Jest najczęściej występującym kodem odpowiedzi. Jeśli w żądaniu
użyto słowa kluczowego GET lub POST, to żądane dane zostały za-
mieszczone w odpowiedzi wraz z typowymi nagłówkami. Jeśli w
żądaniu użyto słowa kluczowego KEAD, to dołączone zostały tylko
informacje z nagłówka.
Serwer utworzył plik danych pod adresem URL, podanym w treści
odpowiedzi. Przeglądarka WIVW powinna teraz spróbować zaiado-
wać go z tego adresu. Taki kod jest wysyłany tylko w odpowiedzi na
żądanie typu POST.
Ta raczej mało popularna odpo\viedź oznacza, że żądanie (zazwyczaj
typu POST) jest przetwarzane, ale proces nie dobiegł końca i dlatego
odpowiedź nie może jeszcze zostać zwrócona. Serwer powinien
przekazać użytkownikowi stronę WWW wyjaśniającą zaistniałą sy-
tuację oraz podającą przewidywany czas spełnienia żądania i najle-
piej łącze do jakiegoś wskaźnika stanu systemu.
Serwerowi udało się przetworzyć żądanie, ale nie ma żadnych da-
nych do przesłania klientowi. Taka odpowiedź zazwyczaj jest rezul-
tatem źle napisanego programu CGI do przetwarzania formularzy,
który pobiera dane, ale nie zwraca użytkownikowi odpowiedzi, któ-
ra potwierdzałaby koniec pracy programu.
HTTP
63
Kod odpowiedzi^
3xx Rgdirection
300 Multiple
Choices
301 Moved
Permanently
302 Moved
Temporarily
304 Not Modified
4xx Client Error
400 Bad Reąuest
401 Unauthorized
403 Forbidden
404 Not Found
5xx Server Error
500 Internal
Server Error
Znaczenie
Kody odpowiedzi o numerach od 300 do 399 oznaczają, że
przeglądarka WWW musi przejść na inną stronę.
Żądana strona jest dostępna w jednym lub kilku miejscach. Treść od-
powiedzi zawiera listę lokalizacji, z których użytkownik lub
przeglądarka mogą pobrać najodpowiedniejszą stronę. Jeśli serwer
wybierze jedną z możliwych stron, to jej adres URL zostanie podany
w nagłówku Location, którego przeglądarka może użyć do załado-
wania wybranej strony.
Strona została przeniesiona pod inny adres URL. Przeglądarka po-
winna automatycznie ściągnąć stronę spod tego adresu i uaktualnić
wszelkie zakładki, które wskazują stary adres URL.
Ta nietypowa odpowiedź oznacza, że strona została tymczasowo
przeniesiona pod nowy adres URL, ale lokalizacja dokumentu po-
nownie zmieni się w najbliższej przyszłości, więc zakładki nie po-
winny być uaktualniane.
Klient przesłał żądanie typu GET, ale użył nagłówka If-Modi-
f ied-Since wskazującego, że chce dostać dokument tylko wtedy,
jeśli został on ostatnio uaktualniony. Ten kod został zwrócony, po-
nieważ dokument nie został zaktualizowany. Teraz przeglądarka
załaduje stronę ze schowka.
Kody odpowiedzi o numerach od 400 do 499 oznaczają, że klient
popełnił jakiś błąd, ale równie dobrze mogą pojawić się w wyniku
zawodnego połączenia sieciowego lub błędu bądź niezgodności
przeglądarki. Przeglądarka powinna przerwać wysyłanie danych
serwerowi natychmiast po otrzymaniu odpowiedzi typu 4xx. Serwer
powinien wyjaśnić błąd w treści odpowiedzi, o ile nie odpowiadał na
żądanie typu HEAD.
W żądaniu klienta skierowanym do serwera została użyta niepra-
widłowa składnia. Ta odpowiedź jest raczę] nietypowa, ale może się
pojawić, gdy piszesz i poprawiasz oprogramowanie klienta.
Do uzyskania dostępu do tej strony potrzebne jest upoważnienie, za-
zwyczaj nazwa użytkownika i weryfikowane hasło. Taka odpowiedź
pojawia się, gdy nazwa użytkownika lub hasło nie zostały podane
lub są niepoprawne.
Serwer zrozumiał żądanie, ale rozmyślnie odmawia jego przetworze-
nia. Upoważnienie nic tu nie pomoże. Jedną z przyczyn może być to,
że klient poprosił o listing katalogu, ale serwer nie został skonfiguro-
wany tak jak na rysunku 3-1, by móc go udostępnić.
Ta najbardziej typowa odpowiedź błędu informuje, że serwerowi nie
udało się znaleźć żądanej strony. Może to oznaczać błędne łącze,
stronę przeniesioną bez podania następnego adresu, źle wpisany ad-
res URL itp.
Kody odpowiedzi o numerach od 500 do 599 oznaczają, że coś złego
dzieje się z serwerem i nie może on temu zaradzić.
Wystąpił nieoczekiwany warunek i serwer nie wie, jak ma go
obsłużyć.
Dokończenie tabeli na str. 64
64 ___ ____Rozdział 3: Podstawowe pojęcia dotyczące sieci W/Wty
Dokończenie tabeli ze str. 63
Tabela 3-1. Kody odpowiedzi protokołu HTTP 1.0
Kod odpowiedzi Znaczenie
501 Not Implemented
502 Bad Gateway
503 Service
Unavailable
Serwer nie został wyposażony w funkcję potrzebną do spełnienia
tego żądania. Serwer, który nie umie obsłużyć żądań POST, może
wysłać taką odpowiedź klientowi usiłującemu przesłać mu dane for-
mularza.
Odpowiedź stosowana tylko przez serwery, które działają jako ser-
wery proxy lub gatewaye. Oznacza ona, że serwer proxy otrzymał
niedopuszczalną odpowiedź od serwera, z którym łączył się w celu
spełnienia żądania.
Serwer tymczasowo nie jest w stanie obsłużyć żądania, być może
z powodu przeciążenia lub prac konserwacyjnych.
Dla protokołu HTTP l .1 istnieje ponad dwa razy więcej odpowiedzi. Jednakże kody
o numerach od 200 do 299 zawsze oznaczają sukces, od 300 do 399 - przekierowania,
od 400 do 499 - błąd klienta, a kody od 500 do 599 - błąd serwera.
Protokół HTTP 1.0 został opisany w informacyjnym dokumencie RFC 1945. Nie jest
oficjalnym standardem internetowym, ponieważ został opracowany głównie poza
IETF, przez pierwszych dostawców przeglądarek i serwerów. HTTP 1.1 jest propo-
nowanym standardem opracowywanym przez W3C oraz przez grupę roboczą do
spraw HTTP w IETF. Zapewnia on znacznie elastyczniejszą i lepszą komunikację
między klientem i serwerem. Jest także w większym zakresie skalowalny.
Podstawowe ulepszenie wprowadzone w HTPP 1.1 ma fundamentalne znaczenie.
HTTP 1.0 dla każdego żądania otwiera nowe połączenie. W praktyce może to ozna-
czać, że w trakcie typowej sesji sieciowej czas zużyty na otwieranie i zamykanie
wszystkich otwartych połączeń może przekroczyć czas poświęcony na przesyłanie
danych, szczególnie przy sesjach z wieloma małymi dokumentami. HTTP 1.1 umo-
żliwia przeglądarce wysłanie wielu różnych żądań przez jedno połączenie, które po-
zostaje otwarte tak długo, aż nie zostanie w jawny sposób zamknięte. Wszystkie
żądania i odpowiedzi są asynchroniczne. Przeglądarka nie musi czekać na odpowiedź
na swoje pierwsze żądanie, by móc wysłać drugie lub trzecie. Jednak zostaje zacho-
wany podstawowy model żądania klienta, po którym następuje odpowiedź złożona
z szeregu nagłówków, dalej pustej linii, a następnie danych zakodowanych
w MIME.
W HTTP 1.1 jest też dużo innych, drobnych ulepszeń. Żądanie zawiera nagłówek
Ho s t typu MIME, aby jeden serwer WWW mógł łatwo służyć różnym witrynom
pod różnymi adresami URL. Serwery i przeglądarki mogą się wymieniać skompre-
sowanymi plikami oraz konkretnymi zakresami bajtów w dokumencie, co w obu
przypadkach zmniejsza ruch w sieci. W protokole HTTP 1.1 znacznie lepiej została
rozwiązana współpraca z serwerami proxy. I choć HTTP 1.1 nie został jeszcze
ukończony, to jest względnie stabilny i na większości ważnych serwerów WWW zo-
stała zaimplementowana przynajmniej jego część. Klienty WWW (to znaczy
przeglądarki) pozostały trochę w tyle, ale nieco nowsze modele także mają zaimple-
65
UHIE
część tego protokołu. HTTP l .1 jest nadbudową HTTP l .0, wiec serwery
Itient/tf ykorzystujące protokół HTTP l .1 nie mają żadnych problemów z komuni-
yfW^ {__"",rrnł nr^e^ladarkami. które oorozumiewaia się tylko w HTTP l.0.
kacją
MIME
TME iest otwartym standardem do przesyłania pocztą internetową wieloczęścio-
h danych multimedialnych.* Dane mogą być w postaci binarnej lub wykorzysty-
W^ liczne zestawy znaków ASCII i nie-ASCII. Choć oryginalnie MIME był przezna-
Wa nv dla poczty elektronicznej, stał się szeroko stosowaną techniką opisu treści pli-
v - dzięki czemu oprogramowanie klienckie może rozróżniać rozmaite rodzaje
danych. Na przykład przeglądarka WWW wykorzystuje MIME do stwierdzenia,
plik jest obrazkiem GIF, czy też przeznaczonym do wydrukowania plikiem post-
scriptowym.
MIME obsługuje prawie setkę zdefiniowanych wcześniej rodzajów zawartości. Po-
śród rodzajów treści zostały wyodrębnione dwa poziomy: typy i pod typy. Typ ogól-
nie określa, jaki jest to rodzaj danych: rysunek, tekst czy filmik? Podtyp precyzuje
konkretny typ danych: obrazek GIF, obrazek JPEG, obrazek TIFF. Na przykład
HTML jest rodzajem treści text/html, gdzie typem jest text, a podtypem html.
Dla obrazka GIF rodzajem treści jest image/gif, gdzie typem jest image, a podty-
pem gif. Tabela 3-2 zawiera listę najpopularniejszych zdefiniowanych rodzajów
treści. W większości systemów odwzorowywaniem między typami MIME a aplika-
cją wykorzystywaną do przetwarzania tego rodzaju danych zajmuje się zwykły plik
tekstowy. W Uniksie ten plik jest nazywany mime.types. Najbardziej aktualną listę
zarejestrowanych typów MIME znajdziesz pod adresem ftp://ftp.isi.edu/in-no-
tes/ianalassignments/media-types/media-types.**
Dane zwracane przez serwer WWW posługujący się protokołem HTTP l .0 lub l .1 są
wysyłane w formacie MIME. Większość serwerów WWW i klientów rozpoznaje co
najmniej dwa typy treści tekstowej MIME, text/html oraz text/plain, a także
dwa formaty obrazków, image/gif oraz image/jpeg. MIME jest także wykorzy-
stywane w sieci WWW do przesyłania serwerom formularzy, będących typową me-
todą komunikowania się apletu z serwerem. Java wykorzystuje typy MIME do wy-
bierania odpowiednich programów obsługujących zawartość konkretnych strumie-
ni danych.
ncjalnie MIME jest skrótem od Multipurpose Internet Maił Extensions (uniwersalne rozszerzenie in-
CTnetowej poczty elektronicznej), zgodnie z dokumentem RFC 2045. Spotkasz się jednak z innymi roz-
nięciami tego akronimu - najczęściej z Multipart Internet Maił Extensions (wieloczęściowe
diafZ6rZenie internetowe) poczty elektronicznej) oraz Multimedia Internet Maił Extensions (multime-
ne rzszerzenie internetowej poczty elektronicznej).
i Tb? ^lfomiac)i na temat MIME znajdziesz w następujących publikacjach: Jerry Sweet, Ed Yielmetti
"icfe /)T00dWin' comP-maii-ie (FAQ), pod adresem http://ivvnv.cs.ruu.nl/wais/html/na-dir/mail/mi-
Sinv ^ r- N'' Borenstem (Bellcore), Multimedia Mail From the Bottom Up or Teaching Dumb Mailers to
Extń" nneXions"< listopad 1991, s. 10-16; G. Yaudreuil (CNRI), MIME: Multi-Media, Multi-Lingual
ensions for Rfc 822 Based Electronic Maił, "ConneXions", wrzesień 1992, s. 36-39.
66
Rozdział ^Podstawowe pojęcia dotyczące sieci WWW
Tabela 3-2. Predefiniowane typy treści MIME
Typ Podtyp Opis
text Dokument zawiera tekst nadający się do druku.
calendar Informaq'e kalendarzowe i harmonogramy w formacie iCalendar; zobacz RFC 2445.
css Kaskadowe arkusze stylu używane w HTML-u i XML-u.
directory Informaq'e z książki adresowej, takie jak nazwisko, numer telefonu i adres e-mail; stosowany przez Netscape vCards; zdefiniowany w RFC 2425 oraz 2426.
enriched Bardzo prosty język, przypominający HTML i przeznaczony do wprowadzania w poczcie elektronicznej podstawow-ch czcionek i formatowania akapitów (np. pogrubienie i kursywa); wykorzystywany przez Eudorę; zdefiniowany w RFC 1896.
html Język znakowania hipertekstu \vykorzystywanv przez przeglądarki WWW.
plain Przeznaczony dla zwykłego tekstu ASCII. Jednak niektóre serwery WWW wkorzystują text/plain jako domyślny typ MIME dla każdego pliku, którego nie mogą rozpoznać. Zatem wszystko i nic, w szczególności pliki .class z kod~em bajtowym mogą zostać uznane za pliki typu -ext /plain.
richtext Podobny do HTML-a jęzvk znaczników do kodowania formatowania w czystym tekście ASCII. W rzeczywistości nigdy nie "chwycił", w znaczne'' mierze z powodu popularności HTML-a. ''
rtf Nie do końca zdefiniowany format firmy Microsoft dla "' plików zawierających tekst przetworzony procesorem sttw.
sgml Standardowy uogólniony jęzvk znaczników; ISO ;. standard 8879:1986.
tab-separated -values Format wymiany wykorzystywany w wielu arkuszami kalkulacyjnych i bazach danych; rekordy są oddzielone znakami łamania linii, a pola znakami tabulacji.
xml Rozszerzalny język znaczników; standard W3C.
multipart Wieloczęściowe wiadomości MIME mają kilka różnydl plików zakodowanych w jednej wiadomości.
mixed Kilka części wiadomości przeznaczonych do przeglądania sekwencyjnego.
alternative Ta sama wiadomość w kilku formatach, aby klient mógł wybrać dla siebie najodpowiedniejszy.
digest Popularny format do dostarczania wielu wiadomości e-mail w jednym streszczeniu; wykorzystywany przez wiele list pocztowych i niektóre listy FAQ.
parallel byteranges Kilka części przeznaczonych do przeglądania równoległego. Kilka rozdzielnych, ciągłych zakresów bajtów; wykorzystywany w protokole HTTP 1.1.
ME
67
IP
ssage
agę
iio
leo
Podtyp ^^
encrypted
signed
related
form-data
external-body
http
news
partial
rfc822 *"<'-
cgm
g3fax
gif
JPeg
Png
tiff
basie
Opis____________________________
Jedna część przeznaczona na treść wiadomości i jedna
dla informaq'i niezbędnych do odkodowania wiadomości.
Jedna część przeznaczona na treść wiadomości i jedna
dla cyfrowego podpisu.
Złożone dokumenty powstające z połączenia kilku
mniejszych części.
Odpowiedzi formularza.
Wiadomość e-mail.
Tylko nagłówek wiadomości e-mail; treść wiadomości
nie jest dołączana, ale istnieje w jakimś innym miejscu
i można do niej sięgnąć, na przykład przez adres URL.
Żądanie w protokole HTTP 1.1 od klienta WWW
do serwera WWW.
Artykuł grup dyskusyjnych.
Część dłuższej wiadomości e-mail, która została
podzielona na wiele fragmentów, aby dało się ją przesłać
gatewayami poczty elektronicznej.
Standardowa wiadomość e-mail zawierająca nagłówki.
Dwuwymiarowe obrazki.
Format CGM (ang. Computer Graphics Metafile - metaplik
grafiki komputerowej) dla obrazków. CGM jest
standardem ISO 8632:1992 dla niezależnej od urządzenia
grafiki wektorowej i obrazów bitmapowych.
Standard dla faksowych obrazków bitmapowych.
Format wymiany graficznej, czyli GIF (ang. Graphics
Interchange Format). Został opracowany przez
CompuServe. Wykorzystuje pewne algorytmy kompresji
danych, do których patent posiada Unisys.
Format JPEG (ang. Joint Photographic Experts Group
- Stowarzyszenie Ekspertów Fotografii) dla
bitmapowych obrazów o kompresji ze stratami.
Obraz w formacie PNGF (ang. Portabk Network Graphics
Format - przenośny sieciowy format graficzny). Format
opracowany w W3C jako nowocześniejszy odpowiednik
formatu GIF, obsługuje 24-bitowy kolor i nie jest
chroniony patentami.
Format TIFF (ang. Tagged Image FUe Format - format
pliku z cechowaną grafiką) firmy Adobe.
Dźwięk.
Dźwięk 8-bitowy, kodowany algorytmem ISDN p-law
z jednym kanałem i próbkowaniem 8 kHz. Format
wykorzystywany w plikach .au oraz .snd i obsługiwany
przez klasę j ava . applet. AudioClip.
Wideo.
Dokończenie tabeli na str. 68
ba
'wiviy
Dokończenie tabeli ze str. 67
Tabela 3-2. Predefiniowane typy treści MIME
Typ Podtyp Opis
mpeg Format MPEG (ang. Mottem Picture Experts Group -
Grupa Ekspertów Filmowych) dla danych wideo
o kompresji ze stratami.
ąuicktime Specyficzny format filmowy QuickTime firmy Apple
Pliki QuickTime muszą zostać "spłaszczone" przed
włączeniem w wiadomości MIME.
model Obrazy trójwymiarowe.
vrml Plik VRML (ang.Yirtual Reality Modeling Language - język
modelowania wirtualnej rzeczywistości); rozwijany
w sieci WWW standard danych trójwymiarowych."
iges IGES (ang. Initial Graphics Exchange Specification -
wstępna specyfikacja wymiany plików graficznych)
opisuje wymianę dokumentów między różnymi
programami typu C AD.
mesh Struktura siatkowa stosowana w metodach skończonych
elementów i skończonych różnic.
application Dane binarne, specyficzne dla niektórych aplikacji.
octet-stream Niezdefiniowane dane binarne, które zazwyczaj są
zapisywane w pliku dla użytkownika. Ten typ MIME
jest czasami wykorzystywany do obsługi plików
.class z kodem bajtowym.
java ; Jeszcze niewystandaryzowany podtyp, czasami
stosowany do obsługi plików .class z kodem bajtowym.
postscript j PostScript firmy Adobe.
dca-rft DCA-RFT (ang. Document Content Architecture-Richly
Formatted Text - architektura zawartości dokumentu
ze wzbogaconym formatowaniem tekstu) firmy IBM.
mac-BinHex40 Sposób kodowania podwójnego dokumentu Macintosha
j w jeden plik ASCII.
pdf Plik w formacie Adobe Acrobat.
zip l Plik skompresowany w formacie zip.
macwriteii ! Dokument procesora tekstu MacWrite II.
msword Dokument programu Microsoft Word.
xml j Dokument XML (ang. Extensible Markup Language -
rozszerzalny język znaczników).
Nie wymaga się, aby programy obsługujące MIME rozumiały te wszystkie typy "a"
nych. Wystarczy, że da się rozpoznać, które typy te programy mogą obsłużyć, a któ-
rych nie. Wiele programów - na przykład Netscape Navigator - wykorzystuje różne
programy pomocnicze do wyświetlania typów danych, których same nie znają.
&*
możliwia zdefiniowanie dodatkowych niestandardowych podtypów po-
tflwb tosowanie przedrostka x-. Na przykład typ treści application/x-tex
przez2 ^JJ^Ę application i niestandardowy podtyp x-tex dla dokumentów
0ia ty? gjow TeX. Nie ma gwarancji, że x-typy zostaną zrozumiane przez jakikol-
proceso Ograrn niż ten, w którym powstały. Tak naprawdę dwa programy mogą
vńe l . . ego samego x-typu do oznaczenia zupełnie różnych rzeczy albo mogą opi-
używac ^^ rzecz różnymi x-typami. Mimo to wiele niestandardowych typów
sywac pOWSzechnego użytku. Najpopularniejsze z nich zostały wymienione
weszfo r
w tabeli 3-3.
Tabela 3-3. X-typy
|QWW X-podtyp Opis
ryp.- application Podtypy aplikacji; nazwa podtypu jest zazwyczaj nazwą formatu pliku lub nazwą aplikacji.
x-aiff Format AIFF danych dźwiękowych firmy SGI.
x-bitmap Bitmapowy obrazek systemu graficznego X Window. ;
x-gzip Dane skompresowane w formacie GNU gzip.
x-dvi Dokument DVI (z ang. devke independent - niezależny od urządzenia) procesora słów TeX.
x-framemaker Dokument programu FrameMaker.
x-latex Dokument procesora słów LaTeX.
x-macBinHex40 Identyczny z podtypem application/ mac-BinHex40,ale starsze oprogramowanie może używać tego x-typu.
x-mif Dokument MIF programu FrameMaker.
x-sd Komunikat sesji protokołu usług katalogowych stosowany do powiadamiania o zdarzeniach MBONE.
x-shar Archiwum powłoki; uniksowy odpowiednik samoodtwarzającego się archiwum w systemie Windows lub Macintosh. Konfiguracja oprogramowania nie powinna umożliwiać automatycznego odpakowywania archiwum powłoki, ponieważ archiwum powłoki jest zdolne wywołać dowolny program, do którego prawo wywołania posiada użytkownik uruchamiający archiwum.
x-tar Archiwum tar.
x-gtar Archiwum GNU tar.
x-tcl Program TCL (ang. Tool Command Language - język >/ poleceń narzędziowych). Nigdy nie powinieneś konfigurować przeglądarki WWW lub programu ' pocztowego tak, aby automatycznie uruchamiały ''' programy ściągane z sieci lub otrzymywane pocztą elektroniczną.
x-tex Dokument procesora słów TeX. s <;;.;;' ' f>\' '}, -.;,
x-texinfo Dokument typu GNU texinfo. ;j - '^fi 'i : , ' " . ;,
x-troff Dokument programu troff. : '" ' ; "
Dokończenie tabeli na str. 70
70
Rozdzial&Podstawwepojęcia Myczącesieci WWW
Dokończenie tabeli ze str. 69
Tabela 3-3. X-typy
Typ X-podtyp Opis
x-troff-man Dokument programu troff zapisany za pomocą
makrodefinicji mań.
x-troff-me Dokument programu troff, który powinien być
przetwarzany z wykorzystaniem makrodefinicji me.
x-troff-ms Dokument programu troff, który powinien być
przetwarzany z wykorzystaniem makrodefinicji ms.
x-wais-source Zasoby WAIS (ang. Wide Area Information
Seruice - usługa informacyjna w sieciach rozległych).
x-www-form Ciąg zapytania CGI, który został zakodowany w sposób
-urlencoded przypominający adres URL, gdzie znak + zastępuje
spacje, a znak % służy do wpisywania znaków
niealfanumerycznych, nie będących separatorami.
audio
x-aiff Taki sam jak typ application/x-aif f; plik
dźwiękowy AIFF.
x-mpeg Format dźwięku MP3.
x-mpeg.mp3 Format dźwięku MP3. , ,
x-wav Format dźwięku WAV Windows.
image
x-fits Format obrazu FTTS stosowany przede wszystkim
przez astronomów.
x-macpict Obraz PICT komputera Macintosh. .>*,
x-pict Obraz PICT komputera Macintosh, f ' '
x-macpaint Format obrazu programu MacPaint. \
x-pbm Przenośny obraz bitmapowy. ''
x-portable-bitmapj Przenośny obraz birmapowy. r.,,, ' ,
x-pgm Obraz PGM. ... ' , .''.<:! ' ' w ' -
video
x-msvideo Format Microsoft A VI pakietu Video for Windows.
x-sgi-movie Format filmowy firmy Silicon Graphics.
CGI
CGI (ang. Common Gateway Interface - wspólny interfejs bramy) służy do dynamicz-
nego tworzenia stron WWW. Tak naprawdę przeglądarka wywołuje program
z serwera, który na bieżąco tworzy nową stronę. Ta strona WWW może bazować wy-
łącznie na danych serwera albo przetwarzać wyniki uzyskane w formularzu klienta,
adres URL wybrany przez klienta albo zmienne środowiskowe. Programy CGI mo-
żna pisać w prawie dowolnym języku, także w Javie, lecz obecnie większość progra-
mowania CGI odbywa się w Perlu, C lub AppleScripcie.
CGI_____________________________________________________TT
pr0gramy CGI działają jako niezależne procesy, inicjowane przez serwer HTTP po
każdym nadejściu żądania usługi. Ma to trzy ważne konsekwencje. Po pierwsze,
uruchamianie programów CGI jest względnie bezpieczne. Działanie programu CGI
może zakończyć się niepowodzeniem, co nie niszczy jednak serwera, przynajmniej
w systemach operacyjnych z wieloma zadaniami wywłaszczającymi i pamięcią
chronioną, takich jak Unix i NT. Po drugie, programy CGI mają ściśle wyznaczony
dostęp do serwera. Po trzecie, programy CGI są obsługiwane mniej wydajnie niż pliki
statyczne z powodu kosztów wydzielenia oddzielnego procesu dla każdego żądania.
Najprostsze programy CGI działają bez pobierania jakiegokolwiek wejścia od użyt-
kownika. Z punktu widzenia klienta dostęp do nich jest taki sam jak do wszystkich
innych stron WWW i dlatego nie one należą do tematu tej książki. Cała różnica mię-
dzy stronami WWW produkowanymi przez programy CGI, które nie pobierają ni-
czego z wejścia, i stronami WWW napisanymi w statycznym HTML-u ujawnia się na
serwerze. To, co dzieje się po stronie serwera, zostało należycie opisane w kilku in-
nych książkach. Więcej informacji o pisaniu programów serwera przetwarzających
wejście CGI i tworzących dynamiczne strony WWW znajdziesz w książce Programo-
wanie CGIwPerlu (Wydawnictwo RM, 2000) Scotta Guelicha, Shisira Gundavarama
i Gunthera Birznieksa.
W tej książce potraktowano CGI nietypowo: jak napisać klienta, który wysyła dane
programowi CGI. Najbardziej popularnym zastosowaniem CGI jest przetwarzanie
wejścia użytkownika z formularzy HTML. W tym zakresie CGI daje apletom i apli-
kacjom Javy standardowe, dobrze rozumiane i właściwie wspierane metody poro-
zumiewania się z systemami zdalnymi. Dlatego przedstawię, jak wykorzystać Javę
do komunikowania się z programem CGI na serwerze. Istnieją również inne metody
porozumiewania się programów w Javie z serwerami, między innymi RMI i serwle-
ry. Jednakże zdalne wywoływanie metod jest wolne, a serwlety nie są obsługiwane
przez wszystkie serwery WWW. Natomiast CGI jest dojrzały, solidny, lepiej
obsługiwany na różnorodnych platformach i serwerach WWW oraz lepiej znany
programistom sieciowym. Poza tym interfejs do serwletów po stronie klienta jest
prawie taki sam jak interfejs do programów CGI po stronie klienta, więc to, co zosta-
nie powiedziane o komunikowaniu się z programami CGI, będzie także dotyczyło
komunikowania się z serwletami.
Przykład 3-1 oraz rysunek 3-3 przedstawiają prosty formularz o dwóch polach,
przeznaczonych na nazwisko i adres poczty elektronicznej. Wartości wpisane przez
użytkownika w formularzu są odsyłane serwerowi po naciśnięciu przez użytkowni-
ka przycisku "Prześlij kwerendę". Programem uruchamianym po odebraniu da-
nych z formularza jest lcgi-binjregisier.pl. Został on wskazany za pomocą atrybutu
^-CTION elementu FORM. Zazwyczaj URL w tym parametrze jest adresem względ-
nym, tak jak w poniższym przykładzie.
Przykład 3-1. Prosty formularz z polami wejścia na nazwisko i adres e-mail


<~-~-E>Przykładowy formularz
^_________________________Rozdział ^Podstawowe pojęcia dotyczące sieci WWW




Podaj nazwisko:
Podaj adres e-mail:


, ; .

' ' '"'"' ' -t-' '
Ą|loim Mml - Miciosoft Inteinet Euplorei
Plik Edycja Widok Ulubione Nszedzia Pomoc
: ~ , * , ? 44 'Q 4J'~~<3 S* ^ S ,'Vj
Zatrzymaj Odświe^ Start Wyszukaj Ulubione _ Hstofia f^13 DiuM Edjłuj Dyskusta
A^res [*j D:\foim hlml~~~ ~" j] ^ P!KfH Łącza '
_____________________________ 3
Podaj nazwisko: ' [Elliolte Rusly Harold ,; , ., .
Podaj adres e-rnail: [elharo@metalab.unc.edu
Prześlij kwerendę J ,>.;,>/
;:."/;" i:-}'..:'^ _.ŚJ
Rysunek 3-3. Prosty formularz ( ; . ,,"-:
Przeglądarka sieciowa odczytuje dane wpisane przez użytkownika i koduje je
w prosty sposób. Nazwa każdego pola jest oddzielana od jego wartości za pomocą
znaku równości (=). Poszczególne pola są rozdzielane ampersandem (&). Każda na-
zwa pola i jego wartość są typu x-www-form-url-encoded, to znaczy, że każdy znak
niealfanumeryczny oraz innego typu niż ASCII jest zastępowany znakiem procentu
i szesnastkowym kodem tego znaku w jakimś zestawie znaków. Spacje stanowią
przypadek szczególny, ponieważ są tak powszechne. Dlatego nie są kodowane jako
%20, tylko zastępowane znakiem +. Z kolei znak + jest kodowany jako %2b. Na
przykład dane z formularza z rysunku 3-1 są kodowane jako:
usernarae=Elliotte+Rusty+HaroId&email=elharo%4:-e-aIab%2eunc%2eedu
Taki zapis nazywamy ciągiem zapytania.
Istnieją dwie metody wysyłania ciągu zapytania do serwera: GET i POST. Jeśli w for-
mularzu zostało określone, że jest to metoda GET; przeglądarka doczepia ciąg zapy-
tania do adresu URL, który wysyła serwerowi. Programy CGI, które wykorzystują
metodę POST, wysyłają ciąg zapytania w strumieniu wyjściowym. Formularz
z przykładu 3-1 posługuje się metodą GET do komunikowania się z serwerem, więc
łączy się z serwerem i wysyła mu następujące polecenie:
GET /cgi/register.pl?username=Elliotte+Rusty-K = rola&em.ail =
elharo%40metalab.unc.edu HTTP 1.0
Do serwera należy rozpoznanie, że adres URL zawiera nazwę programu CGI oraz
wejście dla tego programu. Przekazuje on ciąg zapytania programowi, zazwyczaj
Aplety i bezpieczeństwo_________ _______________________73
w postaci zmiennej środowiskowej. Ponieważ na niektórych platformach długość
zmiennej środowiskowej jest ograniczona, metoda GET jest zawodna przy
wysyłaniu więcej niż 200 znaków tekstu. W takich przypadkach lepiej zastosować
metodę POST.
W metodzie POST przeglądarka wysyła typowe nagłówki, po nich pustą linię (kolej-
no dwie pary znaków powrót karetki/przesuw o wiersz), a następnie ciąg zapy-
tania. Ciąg zapytania jest przekazywany programowi CGI przez standardowe wejście.
Gdyby formularz z rysunku 3-1 używał metody POST, to wysłałby serwerowi, co
następuje:
POST /cgi-bin/register .pl HTTP 1.0 ; . f v.
Content-type: application/x-www-form-urlencoded .' :.'-.::.
Content-length: 65 :
>!,'.', '. i l ''
username=Elliotte+Rusty+Harold&email=elharo%40metalab.unc.edu ; ;;.'.--..
W HTML-u istnieje wiele różnych znaczników do tworzenia w formularzach menu
rozwijanych, przełączników itp. Jednak mimo że wszystkie te wejściowe cudeńka
wyglądają inaczej u różnych użytkowników, to format danych, które wysyłają ser-
werowi, jest taki sam. Każdy element formularza dostarcza nazwę i zakodowany
ciąg wartości.
Aplety i bezpieczeństwo i ,
Teraz, kiedy rozumiesz już, w jaki sposób przesyła się pliki siecią WWW, możemy
zająć się tym, jak są transmitowane aplety. Z jednej strony aplety są po prostu na-
stępnymi plikami, które są przesyłane tak samo jak wszystkie inne. Z drugiej strony
to, co aplet może zrobić, ściśle zależy od tego, skąd pochodzi. Zależność ta nie odnosi
się do danych innego typu, takich jak HTML i GIF.
Skąd się wzięły aplety i klasy?
Przeglądarka, napotykając znacznik applet i decydując się na załadowanie i odpa-
lenie apleru, powoduje uruchomienie długiego ciągu zdarzeń. Powiedzmy, że twoja
przeglądarka natknęła się na następujący znacznik applet:
code="Animation.class" width="200" height="100"> -,
1. Przeglądarka wyznacza prostokątny obszar strony o szerokości 200 pikseli i wy-
sokości 100 pikseli. W większości przeglądarek ten obszar ma ustalone wymiary
i nie może zostać zmieniony po utworzeniu. Tylko appletviewer w JDK jest chlub-
nym wyjątkiem.
2. Przeglądarka otwiera połączenie z serwerem określone parametrem codebase,
używając portu 80, chyba że poprzez adres URL w parametrze codebas e zosta-
nie wskazany inny port. Jeśli parametr codebase nie zostanie podany, to
przeglądarka łączy się z tym samym serwerem, który dostarczał stronę HTML.
3- Przeglądarka żąda od serwera WWW pliku .class, tak jakby żądała jakiegokol-
wiek innego pliku. Jeśli parametr codebase został podany, to przyjmuje się, że
74_________________________Rozdział S^Podstawowepojęcia dotyczące sieci WWW
określa on nazwę żądanego pliku. W przeciwnym razie zostaje wykorzystana
baza dokumentu (katalog, który zawiera stronę HTML). Na przykład:
GET javafaq/classes/ Animation.class HTTP 1.0
4. Serwer odpowiada, wysyłając nagłówek MIME, po nim pustą linię (\ r \ n), a da-
lej dane binarne w pliku .class. Prawidłowo skonfigurowany serwer wysyła pliki
: .class, które mają typ MIME application/octet-stream. Na przykład:
'' HTTP 1.0 200 OK " !:'i ' '- ~ ; - - .
Datę: Mon, 10 Jun 1999 17:11:43 GMT :.....
Server: Apache/1.2.8
Content-type: application/octet-stream
Content-length: 2782 .;:"; ,. . - :
Last-modified: Fri, 08 Sęp 1998 21:53:55 GMT
Nie wszystkie serwery WWW są skonfigurowane tak, aby prawidłowo wysyłać
pliki .class. Niektóre wysyłają je jako text/plain, co w większości przypadków
działa, choć z technicznego punktu widzenia jest niewłaściwe.
5. Przeglądarka odbiera dane i zapamiętuje je w tablicy bajtów.
6. Kontroler kodu bajtowego sprawdza otrzymane kody bajtowe, aby upewnić się,
czy nie robią niczego zabronionego, na przykład nie przeprowadzają konwerto-
wania liczby całkowitej we wskaźnik.
7. Jeśli kontroler jest zadowolony z załadowanych bajtów, pierwotne dane są prze-
kształcane w klasę Javy za pomocą metod aefineClass () i LoadClass ()
bieżącego obiektu ClassLoader.
8. Przeglądarka konkretyzuje klasę Animation, używając jej bezargumentowego
konstruktora.
9. Przeglądarka wywołuje metodę init () klasy Animation. -'" .
10. Przeglądarka wywołuje metodę start (} klasy Animation. ' "
Jeżeli klasa Animation odwołuje się do innej klasy, interpreter Javy najpierw szuka
nowej klasy w ścieżce CLASSPATH użytkownika. Jeśli ją tam znajdziesz, to jest ona
tworzona na dysku twardym użytkownika na podstawie pliku .class. W przeciw-
nym razie przeglądarka wraca do witryny, z której pochodzi klasa, i ładuje plik .class
dla nowej klasy. Ta sama procedura jest realizowana dla nowej klasy i każdej innej,
która jest ściągana z Sieci. Jeśli nie można znaleźć nowej klasy, zgłaszany jest
wyjątek klasy ClassNotFoundExcepticr..
Bezpieczeństwo: z kim aplet może rozmawiać i co powiedzieć?
W publikacjach prasowych znajdziesz mnóstwo obaw, niepewnych wiadomości
i wątpliwości na temat tego, co aplety Javy mogą robić, a czego nie. Ta książka nie
traktuje o zabezpieczeniach w Javie, ale podajemy tu, czego nie wolno robić apletom
ściąganym z sieci.
Aplety nie mogą uzyskiwać dowolnego dostępu do adresów pamięci. W przeci-
wieństwie do innych ograniczeń z tej listy egzekwowanych przez menedżera
przeglądarki SecurityManager, jest to właściwością samego języka Java i kon-
trolera kodu bajtowego.
/(pięty i bezpieczeństwo
Aplety nie mogą w żaden sposób uzyskać dostępu do lokalnego systemu plików,
Nie wolno im czytać z lokalnego systemu plików ani w nim pisać, ani wyszukiwać
żadnych informaq'i o plikach. Dlatego nie potrafią się dowiedzieć, czy jakiś plik isti
nieje ani jaka jest data jego ostatniej modyfikaqi.
Aplety nie umieją uruchamiać u klienta innych programów. Innymi słowy, nie
potrafią wywołać metody System. exec () ani Runtime. exec ().
Aplety nie potrafią załadować macierzystych bibliotek ani zdefiniować macierzy-
stych wywołań metod.
Apletom nie wolno korzystać 2 metody System. getProperty () w sposób
ujawniający informacje o użytkowniku lub maszynie użytkownika, to znaczy na-
zwę użytkownika lub katalog macierzysty. Mogą posługiwać się metodą Sys-
tem . getProperty (), aby dowiedzieć się, która wersja Javy jest stosowana.
Aplety nie mogą definiować żadnych właściwości systemowych.
W Javie 1.1 i późniejszych nie mogą tworzyć ani przekształcać żadnych Thread
i ThreadGroup, które nie należą do ich własnych ThreadGroup. W Javie 1.0
mogą to robić.
Aplety nie mogą definiować ani używać nowych instancji ClassLoader, Secu-
rityManager, ContentHandlerFactory, SocketlmplFactory ani Url-
StreamHandlerFactory. Muszą używać tych, które już istnieją.
Na koniec to, co najważniejsze dla tej książki:
Aplet może otworzyć tylko połączenie z tym węzłem sieci, z którego sam został
ściągnięty.
Aplet nie może nasłuchiwać w portach o numerach niższych od 1024. (Internet
Explorer 5.0 nie zezwala apletom na nasłuchiwanie na żadnym z portów).
Jeśli nawet aplet nasłuchuje na jakimś porcie, to może odbierać połączenia przy-
chodzące tylko z tego węzła sieci, z którego został ściągnięty.
2 tych jedenastu punktów tylko drugi i dziewiąty są poważnymi niedogodnościami
dla znacznej liczby apletów. Tych ograniczeń można nie przestrzegać tak ściśle przy
apletach podpisanych cyfrowo.
Jeśli nawet podpiszesz aplet, nie powinieneś się spodziewać, że użytkownik zdecy-
duje się dać ci zezwolenie na otwieranie połączeń z dowolnymi węzłami sieci. Jeżeli
twój program nie może funkcjonować z takimi ograniczeniami, powinien być apli-
kacją, a nie apletem. Aplikacje Javy są takie same jak wszystkie inne rodzaje aplika-
cji: nie mają narzuconych ograniczeń stanowiących, co wolno im robić. Jeśli piszesz
aplikację, która będzie ładować i wykonywać klasy, powinieneś dobrze rozważyć,
jakie ograniczenia warto wprowadzić, i zaprojektować odpowiednią strategię bez-
pieczeństwa uwzględniającą te wymagania.
; . . :
i L
-'- i,- ~'#-. i"'- - f '.' e
'- - o "' '': '" ' ' i, * ' - --
-- ,. ;- " -' .--
-' :-^..-'i: & f ;; :- E1. - ? T ;._
;; ' :"-, ' ^ ;>
; '.: ,
:.c /- ' * - ". -,. -, -,-
- Ś- i,'. ;'- - - ' ' * '. , :'; -; v.-. ;r .-
" . !-" ''V l;V t; ; :; - - ;:; :-, ..y-; - -^ -. s. .;-."---- "" - 'l"
-. .: >: ^ : z >:,",-.; ^.. - ó . . -
^ :: ' v^ r;., -. ^rv ; **-' : .>. . ^ . -'. - * '.-
^ -:' f- ' - '] _ - - -T *' . ,' ' . *'
4
Wejście i wyjście w Javie
W tym rozdziale:
Strumienie wyjściowe
Strumienie wejściowe
Strumienie filtrujące
Klasy Reader i Writer
Większą część tego, czym zajmują się programy sieciowe, stanowi wejście i wyjście,
czyli przenoszenie bajtów z jednego systemu do drugiego. Bajty to po prostu bajty,
a przecież czytanie danych wysłanych przez serwer nie różni się tak bardzo od czy-
tania pliku. Wysyłanie tekstu do klienta nie różni się tak bardzo od pisania w pliku.
Jednak wejście i wyjście w Javie zostało zorganizowane inaczej niż w większości po-
zostałych języków, takich jak C, Pascal i C++. Dlatego zdecydowałem się poświęcić
cały rozdział na syntetyczny opis wyjątkowego podejścia w Javie do zagadnień we-
jścia i wyjścia.
Wejście i wyjście w Javie zostało zbudowane na strumieniach (ang. streams). Strumie-
nie wejściowe czytają dane. Strumienie wyjściowe zapisują dane. Różne fundamental-
ne klasy strumieni, takie jak klasa java. io .FilelnputStream i sun.net. Tel-
netOutputStream, odczytują i zapisują poszczególne źródła danych. Natomiast
wszystkie zasadnicze strumienie wyjściowe mają te same podstawowe metody zapi-
sywania danych, a wszystkie zasadnicze strumienie wejściowe używają tych samych
podstawowych metod czytania danych. Po utworzeniu strumienia często można
przestać się martwić tym, co dokładnie się zapisuje lub odczytuje.
Strumienie filtrujące mogą być dołączane łańcuchowo zarówno do strumieni
Wejściowych, jak i wyjściowych. Filtry mogą modyfikować dane w trakcie ich od-
czytywania lub zapisywania - na przykład szyfrując je lub kompresując - albo mogą
PO prostu dostarczyć dodatkowe metody przekształcające format danych odczyty-
wanych lub zapisywanych. Na przykład klasa j ava. io. DataOutputStream do-
starcza metodę, która zamienia liczbę typu int na cztery bajty i zapisuje je w swoim
Podstawowym strumieniu wyjściowym.
78____________________________ ____Rozdzlal^Weiście^wyjście w Jawę
Wreszcie do strumieni wejściowych i wyjściowych mogą zostać dołączone łańcu-
chowo strumienie klas Reade r i Wr i te r, aby umożliwić programom odczytywanie
i zapisywanie tekstu (to znaczy znaków), a nie bajtów. Filtry Reader i Writer,
właściwie zastosowane, mogą obsługiwać szeroki zakres sposobów kodowania
znaków, w tym wielobajtowe zestawy znaków, takie jak SJIS lub UTF-8.
Strumienie wyjściowe
Podstawową klasą wyjściową w Javie jest j ava . io . OutputStream:
public abstract class OutputStream
Ta klasa dostarcza fundamentalnych metod, które są niezbędne do zapisywania da-
nych. Są to:
public abstract void write(int b) throws IOException
public void write(byte[] data) throws IOException
public void write(byte[] data, int offset, int length) throws IOException
public void flush() throws IOException
public void close() throws IOException
Podklasy klasy OutputStream używają tych metod do zapisywania danych na
konkretnym nośniku. Na przykład podklasa FileOutputStream wykorzystuje te
metody do zapisywania danych w pliku, podklasa Te InetOutputS tream do zapi-
sywania danych na połączeniu sieciowym, a podklasa ByteAr rayOutputStrearn
do zapisywania danych w rozszerzalnej tablicy bajtów. Ale niezależnie od tego, na
jakim nośniku piszesz, przeważnie korzystasz tylko z pięciu tych samych metod.
Czasami możesz nawet nie wiedzieć dokładnie, na jakim rodzaju strumienia pi-
szesz. Na przykład w dokumentacji bibliotek klas Javy nie znajdziesz podklasy
TelnetOutputStream. Specjalnie została ukryta w pakiecie suń. Jest zwracana
przez różne metody z różnych klas pakietu j ava . net, takie jak metoda getOut-
putStream () klasy j ava . net. Socket. Jednak z deklaracji wynika, że te metody
zwracają jedynie klasę OutputStream, a nie konkretną podklasę TelnetOutput-
Stream. Na tym polega potęga polimorfizmu. Jeśli umiesz używać klas nadrzęd-
nych, to wiesz także, jak korzystać z podklas.
Podstawową metodą klasy OutputStream jest write (int b). Argumentem tej
metody jest liczba całkowita z zakresu od O do 255. Metoda ta zapisuje na strumieniu
wyjściowym bajt odpowiadający liczbie. Została ona zadeklarowana jako abstrak-
cyjna, ponieważ podklasy będą musiały ją zmienić, aby obsłużyć swoje nośniki. Na
przykład podklasa ByteArrayOutputStream może zastosować tę metodę w czy-
stym kodzie bajtowym Javy, kopiującym bajt do jej tablicy. Jednakże podklasa Fi-
leOutputStream będzie musiała użyć macierzystego kodu, który wie, jak zapisy-
wać dane w plikach na platformie hosta.
Zwróć szczególną uwagę na fakt, że chociaż argumentem tej metody jest ir.i, to za-
pisuje ona bajt bez znaku. W Javie nie istnieje typ danych bajt bez znaku i dlatego na-
leży tu zastosować typ int. Jedyną poważną różnicą między bajtem bez znaku a baj-
tem ze znakiem jest sposób jego interpretacji. Oba typy są złożone z ośmiu bitów
i gdy za pomocą metody write (int b) zapisujesz int na połączeniu sieciowym,
Strumienie wyjściowe_____ ___________________ 79
to wprowadzasz na kabel osiem bitów. Jeśli metodzie write(int b) zostanie prze-
kazana liczba int spoza zakresu 0-255, zapisywany jest najmniej znaczący bajt licz-
by, a pozostałe trzy bajty są pomijane. (Jest to skutkiem rzutowania typu int na typ
byte). Jednak sporadycznie można się natknąć na błędne klasy z trzeciej ręki, które
robią coś zupełnie innego, a mianowicie zgłaszają wyjątek 11 lega l Ar gumentExcep -
t i on lub zawsze piszą 255, więc najlepiej nie polegać na takim zachowaniu, o ile to
możliwe.
Na przykład protokół generatora znaków definiuje serwer, który wypuszcza tekst
ASCII. Najbardziej popularna odmiana tego protokołu wysyła 72-znakowe wiersze
zawierające drukowalne znaki ASCII. (Do drukowalnych znaków ASCII zaliczamy
te od 33 do 126, oprócz rozmaitych znaków białych i sterujących). Pierwszy wiersz
zawiera posortowane znaki od 33 do 104. Drugi wiersz zawiera znaki od 34 do 105,
trzeci od 35 do 106 i tak aż do wiersza 29., który zawiera znaki od 55 do 126. Od tego
momentu wiersz jest zawijany, tak więc linia 30. zawiera znaki od 56 do 126, a dalej
znowu znak 33. Wiersze są zakończone znakiem powrotu karetki (ASCII 13) i zna-
kiem przesuwu o wiesz (ASCII 10). Rezultat jest następujący:
!"#S%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]"_'abcdefgh
"#S%S'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]A_'abcdefghi
ł$%&'()'+,-.70123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]*_'abcdefghij
S%4' ()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]*_~abcdefghij k
%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]*_'abcdefghijkl
&' ()* + ,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]A_"abcdefghij kim
'()*-,-./0123456789: ;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\] A_~ abcdef ghi j klmn
ASCII jest 7-bitowym zestawem znaków, więc każdy znak jest wysyłany jako poje-
dynczy bajt. Dlatego też łatwo jest zaimplemęntować ten protokół za pomocą pod-
stawowej metody write (), co przedstawia poniższy fragment kodu:
public static void generateCharacters(OutputStream out) throws IOException {
int firstPrintableCharacter = 33;
int numberOfPrintableCharacters = 94; -..i ' ..' , ,.:. '. !,
int numberOfCharactersPerLine = 72;
int start = firstPrintableCharacter;
whiie (true) ( /*niesko ńczona pętla */
for (int i = start; i < start+numberOfCharactersPerLine; i++) { -:
out.write ( ( ,
(i-f irstPrintableCharacter) % numberOf PrintableCharacters) i:/ r,
+ firstPrintabieCharacter) ; ,..,-.. ., , . , ;> > '*< >
} ' '. -, . . , ;,: . J).':'
out. write ('\r'); //powrót karetki . . : . . .' ' '<:' *!" ''' :' . :
out. write ('\n'); //przesuw o wiersz < f. .:;.' \i, ',.. . . -.^-'r.,
start = ( (start + 1) - firstPrintableCharacter)
% numberOfPrintableCharacters + firstPrintableCharacter;
} .,.,,: .,
) <\\ " :; : .,' Wi...,;',.;.;,:, '. ,u ,'..,, ;.y.-
Wąsa serwera generatora znaków (której szczegóły poznamy dokładnie podczas
omawiania gniazd serwera w rozdziale 11. "Gniazda serwerów") przekazuje stru-
mień klasy OutputStream, nazwany out, metodzie generateCharacters () .
Bajty są pojedynczo zapisywane na strumieniu out. Występują w postaci liczb
80________________________________ Rozdział 4: Wejście^wyjście wJavie
całkowitych w sekwencji od 33 do 126, przesuwającej się krokowo o jeden. Więk-
szość działań arytmetycznych w tym przykładzie dotyczy przesuwania pętli w tym
zakresie o jeden. Po zapisaniu każdych 72 znaków na strumieniu wyjściowym jest
zapisywany znak powrotu karetki i znak przesuwu o wiersz. Obliczany jest kolejny
znak początkowy i pętla się powtarza. Cała metoda została zadeklarowana tak, by
zgłaszać wyjątki klasy IOException. Jest to ważne, gdyż serwer generatora znaków
skończy działanie tylko wtedy, gdy klient zamknie połączenie. Kod Javy będzie to
postrzegał jako wyjątek klasy IOException.
Zapisywanie po jednym bajcie w danej chwili jest często niewystarczające. Na
przykład każdy segment TCP, który wychodzi z twojej karty ethernetowej, zawiera
co najmniej 40 bajtów narzutu, potrzebnych przy rutingu i korekcji błędów. Jeśli ka-
żdy bajt byłby wysyłany oddzielnie, ilość danych, jaką wypełniłbyś kabel, byłaby 41
razy większa od przewidywanej. Dlatego też większość implementacji TCP/IP w ja-
kimś stopniu buforuje dane. To znaczy, że bajty są gromadzone w pamięci i ewentu-
alnie wysłane do swojego punktu przeznaczenia tylko wtedy, gdy zbierze się ich
określona liczba lub gdy upłynie określony czas. Natomiast, gdy gotowych do
wysłania bajtów jest więcej niż jeden, nie najgorszym pomysłem byłoby wysyłać je
równocześnie. Stosowanie metody write(byte[] data) lub write(byte[]
data, int offset, int length) jest zazwyczaj znacznie szybsze od zapisy-
wania wszystkich składników tablicy data po kolei. Oto przykład wykorzystania
metody generateCharacters () do wysyłania po jednym wierszu, dzięki we-
pchnięciu całej linii do tablicy bajtów:
public static void generateCharacters(OutputStream out) throws ICException {
int firstPrintableCharacter
int numberOfPrintableCharacters . ..
.!,,, int nuraberOfCharactersPerLine = 12: ' .'.::"'.., . .. . ' . .
int start = firstPrintableCharacter;
byte[] linę = new byte [numberOf CharactersPerLlne*23<ł' >'...- > .''.j. ś
// +2 jest dla znaku powrotu karetki i przsw(;.-w4*KS -. .' :' -
while (true) { /*nies kończona pętla */
'V' for (int i = start; i < start+numberOfCharactersPerLine; i-4-) {'
l linę [i-start] = (byte) ((i- f irstPrintableCharacter) :. a.
' % numberOf PrintableCharacters + f irstPrintableCharacter) ; ,
;" }
y, ; line[72] = (byte) '\r'; //powrót karet*- ..-. ,
.'. linę [73] = (byte) '\n'; //przesuw o wiersz . . . ' -
out.write(linę);
start = ((start + 1) - f irstPrintableCharacter)
% numberOfPrintabieCharacters + firstPrintableCharacter;
} . -
}
Algorytm obliczający, który bajt kiedy zapisać, jest taki sam jak w poprzedniej imple-
mentacji. Zasadnicza różnica polega na tym, że wszystkie bajty, zanim zostaną zapi-
sane w sieci, są wtłaczane w tablicę bajtów. Zwróć także uwagę, iż wynik obliczenia,
który jest typu int, należy rzutować na typ byte, zanim będzie można go zapisać
w tablicy. W poprzedniej implementacji nie było to konieczne, gdyż metoda poje-
dynczego bajtu write () została zadeklarowana tak, że jej argumentem był int.
Strum'iei]iewyiściowe_
81
Strumienie można również buforować poprzez oprogramowanie, bezpośrednio
w kodzie Javy, a także w sprzęcie sieciowym. Zazwyczaj realizuje się to poprzez
łańcuchowe dołączanie strumienia klasy BufferedOutputStream lub Buffe-
redWriter do strumienia podstawowego, którą to technikę pokrótce objaśnimy.
Dlatego jeśli zapisałeś dane, należy opróżnić strumień wyjściowy. Przypuśćmy na
przykład, że zapisałeś 300-bajtowe żądanie do serwera HTTP 1.1, który używa pro-
tokołu HTTP Keep-Alive. Zazwyczaj chcesz poczekać na odpowiedź, zanim
przekażesz więcej danych. Jeśli jednak strumień wyjściowy ma 1024-bajtowy bufor,
to może czekać na przybycie kolejnych danych, aby wysłać je wszystkie razem z bu-
fora. Na strumieniu nie będą zapisywane żadne dane, aż do nadejścia odpowiedzi
serwera, ale to nigdy nie nastąpi, ponieważ żądanie nie zostało jeszcze wysłane. Bu-
forowany strumień nie wyśle danych serwerowi, dopóki nie dostanie więcej danych
od strumienia podstawowego, lecz strumień podstawowy nie prześle kolejnych da-
nych do czasu, dopóki nie dostanie danych uwięzionych w buforze! Rysunek 4-1
przedstawia tę sytuację zakleszczenia typu Catch-22. Z tego impasu wybawi cię me-
toda flush (), która wymusi na buforowanym strumieniu, aby wysłał on swoje
dane, nawet jeśli nie jest jeszcze wypełniony.
serwer WWW
klient WWW
Rysunek 4-1. Dane mogą przepadać, jeśli nie będziesz opróżniać swoich strumieni
Opróżnianie strumieni jest ważne niezależnie od tego, czy uważasz, że jest to po-
trzebne, czy nie. W zależności od tego, w jakiej postaci dostałeś odwołanie do stru-
mienia, możesz wiedzieć lub nie, czy jest on buforowany. (Na przykład strumień
System. out jest buforowany, czy tego chcesz czy nie). Jeżeli dla jakiegoś strumie-
nia opróżnianie nie jest konieczne, to koszt jego wykonania i tak jest niewielki. Nato-
miast gdy opróżnianie jest potrzebne, to rzeczywiście tak jest. Zaniechanie opróżnia-
82_________________________ Rozdział 4: Wejście i wyjście w Jawę
nią w sytuacji, gdy jest niezbędne, może prowadzić do nieprzewidywalnych, niepo-
wtarzalnych zawieszeń programu, które są wyjątkowo trudne do zdiagnozowania,
jeśli nie masz pojęcia, co jest ich przyczyną. Wniosek z tego wszystkiego jest taki, że
powinieneś natychmiast opróżniać wszystkie strumienie, zanim je zamkniesz.
W przeciwnym razie w trakcie zamykania strumienia mogą przepaść dane pozosta-
wione w buforze.
Na koniec, gdy skończyłeś już ze strumieniem, powinieneś go zamknąć, wywołując
jego metodę cl osę (). Spowoduje to uwolnienie wszystkich zasobów związanych
ze strumieniem, takich jak symboliczne uchwyty plików lub porty. Gdy strumień
wyjściowy zostanie zamknięty, dalsze zapisywanie w nim spowoduje zgłoszenie
wyjątku klasy IOException. Niemniej niektóre rodzaje strumieni pozwalają jesz-
cze zrobić coś z obiektem. Na przykład zamknięty strumień ByteArrayOutput-
Stream może nadal zostać przekształcony w aktualną tablicę bajtów, a zamknięty
strumień DigestOutputStream wciąż może zwrócić swoją cyfrową sygnaturę.
Strumienie wejściowe
Podstawową klasą wejściową w Javie jest j ava . io . InputStrearr.:
public abstract class InputStream
Ta klasa dostarcza fundamentalnych metod niezbędnych do odczytywania danych.
Są to:
public abstract int read() throws IOException
public int read (byte[] input) throws IOException
public int read (byte[; input, int offset, inz length) throws ICException
public long skip(long n) throws IOException
public int available() throws IOException
public void closeO throws IOException
Poszczególne podklasy klasy InputStream używają tych metod do odczytywania
danych z konkretnego nośnika. Na przykład podklasa Filelr.putStream czyta
dane z pliku, podklasa TelnetlnputStrearr. z połączenia sieciowego, a podklasa
ByteArraylnputStream z rozszerzalnej tablicy bajtów. Ale niezależnie od tego,
z jakiego nośnika czytasz, przeważnie korzystasz tylko z sześciu tych samych me-
tod. Czasami możesz nawet nie wiedzieć dokładnie, z jakiego rodzaju strumienia
czytasz. Na przykład TelnetlnputStrearr. jest nieudokumentowaną klasą,
ukrytą w pakiecie suń . net. Jej instancje są zwracane przez różne metody z pakietu
j ava . net, na przykład przez metodę oper.Strearr, () klasy ; ava . r.er, . URL. Jed-
nakże według deklaracji te metody zwracają jedynie klasę InputStrearr., a nie kon-
kretną podklasę TelnetlnputStream. Jeszcze raz objawia się potęga polimorfi-
zmu. Instancja podklasy może być oczywiście używana jako instancja jej klasy nad-
rzędnej. Niepotrzebna jest żadna wiedza o podklasie.
Podstawową metodą strumienia klasy Inpur_Stream jestbezargumentowa metoda
read (). Wczytuje ona pojedynczy bajt danych ze źródła strumienia wejściowego
i zwraca go w postaci liczby z zakresu od O do 255. Koniec strumienia jest sygnalizo-
wany zwróceniem -l. W Javie nie istnieje typ danych bajt bez znaku i dlatego zwra-
świnienie wejściowe_____________ _____________________83
cana liczba jest typu int. Metoda read () czeka i blokuje wykonanie jakiegokol-
wiek występującego po niej kodu do czasu, aż bajt danych będzie dostępny i gotowy
do odczytania. Obsługa wejścia i wyjścia jest dosyć powolna, więc jeśli twój program
ma jeszcze robić coś innego i ważnego, powinieneś umieścić wejście i wyjście w od-
dzielnym wątku.
Metoda read () została zadeklarowana jako abstrakcyjna, ponieważ podklasy będą
musiały ją zmienić, aby obsłużyć swoje nośniki. Na przykład podklasa ByteAr-
raylnputStream może zastosować tę metodę w czystym kodzie bajtowym Javy,
kopiującym bajt z jej tablicy. Natomiast strumień klasy TelnetlnputStream bę-
dzie musiał użyć oryginalnej biblioteki, która potrafi odczytywać dane z interfejsu
sieciowego na platformie hosta.
poniższy fragment kodu wczytuje 10 bajtów ze strumienia wejściowego i n i prze-
chowuje je w tablicy bajtów i npu t. Jeśli jednak zostanie wykryty koniec strumienia,
pętla kończy się wcześniej:
byte[] input = new byte[10]; :\U' =.-. Kj,i' > . ",',. t\ . ... ;U ';,
for (int i = 0; i < input. length; i + + ) { .,<-.,'..'. .. , : .';;
int b = in.read(); ';;' ' . '' ":"
if (b == -1) break; '!''-'' " ' ''<''' ' '"' ' '"'.-' < . .' :
input [i] = (byte) b; >-' t'' . ',' ' , .
} ' - ".. '< . i ,'...- .... -
Chociaż metoda read () wczytuje tylko bajty, to zwraca liczbę typu int. Zatem
przed zapisaniem wyniku w tablicy bajtów konieczne jest rzutowanie. Oczywiście ta
procedura daje bajt ze znakiem z zakresu od -128 do 127, zamiast bajtu bez znaku
z zakresu od O do 255 zwracanego przez metodę read (). Dopóki jednak zachowu-
jesz rozeznanie, z którymi bajtami pracujesz, nie stanowi to poważnego problemu.
Możesz przekształcić bajt ze znakiem w bajt bez znaku w następujący sposób:
int i = b >= O ? b : 256 + b;
Czytanie po jednym bajcie jest tak samo nieefektywne, jak zapisywanie ich pojedyn-
czo. Dlatego istnieją też dwie przedefiniowane metody read (), które wypełniają
zadaną tablicę wieloma bajtami danych, odczytywanymi ze strumienia. Są to: read
(byte[] input) oraz read (byte[]input, int offset, int length).
Pierwsza z nich stara się wypełnić wskazaną tablicę input, a druga pod tablicę tabli-
cy input, poczynając od bajtu offset i kontynuując przez length bajtów.
Zwróć uwagę, że napisałem starają się wypełnić tablicę, gdyż niekoniecznie im się to
udaje. Ta próba może się nie powieść z kilku powodów. Na przykład nierzadko pro-
gram odczytuje dane ze zdalnego serwera WWW poprzez połączenie PPP, a błąd
w przełączniku centrali telefonicznej rozłącza ciebie i kilka tysięcy twoich sąsiadów
z całego świata. Spowodowałoby to wysłanie wyjątku klasy IOException. Bar-
dziej typowe są jednak przypadki, w których odczyt nie kończy się kompletnym fia-
skiem, ale także niezbyt pełnym sukcesem. Niektóre z żądanych bajtów mogą zostać
odczytane, ale nie wszystkie. Na przykład, gdy usiłujesz odczytać 1024 bajty z
połączenia sieciowego, a z serwera doszło tylko 512. Reszta jest nadal w drodze. Być
może dotrą, ale na razie nie są dostępne. Aby to uwzględnić, wielobajtowe metody
84___________________________________Rozdzial^:Weiścienvyiście wJavie
odczytu zwracają liczbę wczytanych już bajtów. Rozważmy na przykład nastę-
pujący fragment kodu:
byte[] input = new byte[1024];
int bytesRead = in.read(input);
Stara się on wczytać do tablicy input 1024 bajty ze strumienia wejściowego in. Je-
żeli jednak dostępnych jest tylko 512 bajtów, to tylko tyle zostanie wczytanych,
a by te sRead przyjmie wartość 512. Aby mieć pewność, że wszystkie potrzebne baj-
ty zostały wczytane, musisz umieścić odczyt w pętli, która powtarza odczyt tak
długo, aż tablica zostanie wypełniona. Na przykład:
int bytesRead =0;
int bytesToRead = 1024; ''
byte [ ] input = new byte [bytesToRead] ; ....._.;
while (bytesRead < bytesToRead) ( ..'
bytesRead += in.read(input, bytesRead, bytesToRead - bytesRead); "
} -"
Ten sposób jest szczególnie istotny dla strumieni sieciowych. Wszystko wskazuje na
to, że jeśli plik jest w ogóle dostępny, to wszystkie jego bajty są również dostępne.
Jednak sieci działają znacznie wolniej niż procesory, więc program z łatwością opró-
żnia bufor sieciowy, zanim nadejdą wszystkie dane. W rzeczywistości, jeżeli jedna
z tych dwóch metod próbuje odczytać dane z chwilowo pustego, ale otwartego bufo-
ra sieciowego, zazwyczaj zwraca O, co oznacza, że nie ma dostępnych żadnych da-
nych, lecz strumień nie został jeszcze zamknięty. Jest to na ogół lepsze od działania
jednobajtowej metody read (}, która w tym samych okolicznościach zablokuje wy-
konywanie działającego programu.
Wszystkie trzy metody odczytu zwracają -l, aby zasygnalizować koniec strumienia.
Jeżeli strumień skończy się, a pozostaną jeszcze nie wczytane dane, to wielobajtowa
metoda odczytu będzie zwracać te dane, aż bufor zostanie opróżniony. Następne
wywołanie którejkolwiek z tych metod odczytu zwróci -1. Jednak -l nigdy nie jest
wstawiane do tablicy, ponieważ zawiera ona tylko bieżące dane. Powyższy frag-
ment kodu jest błędny, ponieważ nie dopuszcza możliwości, że wszystkie 1024 bajty
mogą nigdy nie dotrzeć (w przeciwieństwie do sytuacji, w której są dostępne natych-
miast). Poprawienie tego błędu wymaga testowania wartości, zwracanej przez me-
todę read () przed dodaniem jej do bytesRead. Na przykład:
v* f -
int bytesRead = 0; : .' , "
int bytesToRead = 1024; ";. ''''
byte [ ] input = new byte [bytesToRead! ; "
while (bytesRead < bytesToRead) {
int result = in.read(input, bytesRead, bytesToRead - bytesRead);
if (result == -1) break;
bytesRead +=result;
}
Jeżeli z jakiegoś powodu nie chcesz czytać tak długo, aż wszystkie potrzebne ci bajty
będą bezpośrednio dostępne, możesz zastosować metodę available(), aby
stwierdzić, ile bajtów można wczytać bez spowodowania blokady. Podaje ona mini-
malną liczbę bajtów, które możesz wczytać. W rzeczywistości może dać się wczytać
Strumienie wejściowe ^________________________85
więcej, ale będziesz mógł wczytać przynajmniej tyle bajtów, ile sugeruje metoda
a va i lab l e (). Na przykład:
int bytesAvailable = in . available () ; '"
byte[] input = new byte[bytesAvailable];
int bytesRead = in.read(input, O, bytesAvailable);
//dalej wykonuj pozostałą część programu...
W tym przypadku możesz sprawić, aby bytesRead było równe dokładnie by-
tesAvailable. Nie możesz jednak zagwarantować, aby bytesRead było większe
niż zero. Możliwa jest sytuacja, w której żadne bajty nie są dostępne. Na końcu stru-
mienia metoda availabie () zwraca 0. Na ogół metoda read (byte [ ] input,
int offset, int length) zwraca-l na końcu strumienia, ale jeśli l engt h wy-
nosi O, to nie zauważy końca strumienia i zamiast tego zwróci 0.
Czasami może się zdarzyć, że chcesz przeskoczyć przez dane, nie czytając ich. Zrobi
to metoda s kip (). Przy czytaniu z połączenia sieciowego jest ona mniej przydatna
niż przy czytaniu z pliku. Połączenia sieciowe są sekwencyjne i wszystkie dość wol-
ne, więc czytanie danych nie pochłania istotnie więcej czasu niż ich przeskoczenie.
Dostęp do plików jest bezpośredni, a zatem ominięcie danych można osiągnąć, po
prostu zmieniając pozycję wskaźnika pliku. Nie trzeba przetwarzać każdego bajtu,
który ma zostać ominięty.
Gdy twój program skończy działać na strumieniu wejściowym, to tak samo jak przy
strumieniach wyjściowych, powinien go zamknąć, wywołując jego metodę clo-
se (). Spowoduje to uwolnienie wszystkich zasobów związanych ze strumieniem,
takich jak symboliczne uchwyty plików lub porty. Gdy strumień wejściowy zostanie
zamknięty, dalsze czytanie z niego spowoduje wysłanie wyjątku klasy IOExcep-
tion. Niemniej niektóre rodzaje strumieni pozwalają jeszcze zrobić coś z obiektem.
Na przykład zazwyczaj nie chcesz dostać cyfrowej sygnatury dla klasy j ava . se-
curity. DigestlnputStream, dopóki wszystkie dane nie zostaną wczytane,
a strumień zamknięty. ,r
Znakowanie i cofanie ;..,.'..' , ,i ,/ ,
Klasa InputStream ma też trzy rzadziej stosowane metody, które umożliwiaj^
programom powrót i ponowne odczytanie danych już przeczytanych. Są to: "?
public void mark(int readAheadLimit)
public void resetO throws IOException
public boolean markSupported()
W tym celu znakujesz aktualną pozycję w strumieniu za pomocą metody mark ().
Znajdując się w dalszym punkcie, możesz przestawić strumień do oznakowanej po-
zycji za pomocą metody reset (). Wtedy kolejne odczyty będą zwracać dane,
począwszy od oznakowanej pozycji. Jednak możesz nie być w stanie cofnąć się tak
daleko, jakbyś sobie tego życzył. Liczba bajtów, które możesz odczytać od znacznika
oraz cofnięcie są określone argumentem readAheadLimit metody mark (). Jeśli
spróbujesz cofnąć się za daleko, zostanie zgłoszony wyjątek klasy IOException.
Co więcej, w danej chwili w strumieniu może występować tylko jeden znacznik.
Wstawienie drugiego znacznika powoduje usunięcie pierwszego.
86 Rozdział 4: Wejście i wyjście w Jawę
Znakowanie i cofanie zazwyczaj implementuje się poprzez zapamiętanie w wew-
nętrznym buforze każdego bajtu odczytanego od pozycji znacznika. Jednak nie we
wszystkich strumieniach wejściowych jest to obsługiwane,. Dlatego zanim spróbujesz
wykorzystać znakowanie i cofanie, powinieneś sprawdzić, czy metoda markSuppor-
ted() zwraca wartość true. Jeśli tak, strumień obsługuje znakowanie i cofanie.
W przeciwnym razie metoda mark () nie zrobi niczego, a reset () wyśle wyjątek kla-
sy IOException.
UWAGA Moim zdaniem dowodzi to bardzo słabego projektowania. W praktyce spotyka się
więcej strumieni, które nie obsługują znakowania i cofania. Doczepianie do abstrakcyjnej klasy
nadrzędnej jakiejś funkcji, która nie jest dostępna wielu podkla.som (prawdopodobnie więk-
szości), jest bardzo złym pomysłem. Lepiej byłoby umieścić te trzy metody w oddzielnym in-
terfejsie, który mógłby być implementowany przez klasy udostępniające tę funkcję. Wadą
takiego podejścia jest to, że wtedy nie mógłbyś wywołać tych metod w dowolnie wybranym
strumieniu wejściowym o nieznanym typie, ale w rzeczywistości i tak nie możesz tego zrobić,
ponieważ nie wszystkie strumienie obsługują znakowanie i cofamie. Dostarczenie metody, ta-
kiej jak markSupported (), która sprawdza tę funkq'ę w dowolnym momencie, jest przeja-
wem bardziej tradycyjnego, nieobiektowego sposobu rozwiązywania problemu. Przy
podejściu obiektowym zostałoby to wprowadzone poprzez system typów zmiennych inter-
fejsów i klas, co pozwoliłoby na sprawdzenie wszystkiego w czasie kompilacji.
Jedynymi dwoma klasami strumienia wejściowego w java.io, które zawsze
obsługują znakowanie, są Buf f eredlnputStreamoraz ByteArraylr.putStre-
am. Natomiast inne strumienie wejściowe, takie jak TelnetlnputStream, mogą
obsługiwać znakowanie, jeśli najpierw zostaną doczepione do buforowanego stru-
mienia wejściowego.
Strumienie filtrujące
InputStreami OutputStream są dość prostymi klasami. Umożliwiają zapisywa-
nie i odczytywanie bajtów, pojedynczo bądź grupami, i to wszystko. Decyzja co do
znaczenia tych bajtów - czy są liczbami całkowitymi, liczbami zmiennoprzecinko-
wymi standardu IEEE 754, czy też tekstem unikodowym - w całości należy do pro-
gramisty i kodu. Istnieją natomiast formaty danych, które są bardzo popularne
i mogą korzystać z solidnych implementacji w bibliotece klas. Na przykład wiele
liczb całkowitych przekazywanych jako część protokołów sieciowych jest 32-bito-
wymi liczbami całkowitymi typu big-endian. Znaczna część tekstu przesyłanego
przez sieć WWW jest 7-bitowym kodem ASCII lub 8-bitowym kodem Latin-1. Wiele
plików przesyłanych przez ftp jest zapisywana w formacie zip. Java dostarcza szereg
klas filtrów, które możesz doczepić do nieobrobionych strumieni, aby przetłuma-
czyć pierwotne bajty na te formaty i inne oraz z powrotem.
Filtry istnieją w dwóch wersjach: strumienie filtrujące oraz filtry Reader i Writer.
Strumienie filtrujące nadal działają na pierwotnych danych takich jak bajty, na
przykład kompresując je lub interpretując jako liczby binarne. Filtry Reader i Wri-
ter obsługują specjalne przypadki tekstu w różnych wariantach kodowania, takich
jak UTF-8 i ISO 8859-1. Strumienie filtrujące umieszcza się na wierzchu pierwotnych
Strumienie filtrujące
strumieni, takich jak TelnetlnputStreamlub FileOutputStream , lub nad in-
nymi strumieniami filtrującymi. Filtry Reader i Writer mogą tworzyć warstwy
nad pierwotnymi strumieniami, strumieniami filtrującymi lub nad innymi filtram]
Reader i Writer. Natomiast strumienie filtrujące nie mogą zostać umieszczeni
nad filtrem Reader lub Writer, dlatego zaczniemy od omawiania strumieni fil
trujących, a filtrami Reader i Writer zajmiemy się w następnym podrozdziale.
Filtry są ułożone łańcuchowo, jak pokazuje rysunek 4-2. Każde ogniwo tego łańcu
cha otrzymuje dane od poprzedniego filtra lub strumienia i przekazuje je dalej, dc
następnego ogniwa w łańcuchu. W tym przykładzie skompresowany, zaszyfrowa
ny plik tekstowy nadchodzi z lokalnego interfejsu sieci, po czym macierzysty koc
wstawia go do nieudokumentowanego strumienia klasy TelnetlnputStream
Buf feredlnputStream buforuje dane, aby przyspieszyć cały proces. Strumief
CipherlnputStream je odszyfrowuje, a GZIPlnputStream dekompresuje od
szyfowane dane. Potem InputStreamReader przekształca zdekompresowane
dane na tekst w Unikodzie. Na koniec tekst jest wczytywany do aplikacji i przetwa
rżany.
Każdy wyjściowy strumień filtrujący ma takie same metody write (), close ()
i flushO jak klasa java . io .OutputStream. Każdy wejściowy strumień fil-
trujący ma takie same metody read(), close () i available() jak klasę
java. io . InputStream. W niektórych przypadkach, takich jak Buf feredln-
putStream i Buf f eredOutputStream, mogą to być jedyne posiadane przez nie
metody. Filtrowanie jest procesem czysto wewnętrznym i nie ujawnia żadnych no-
wych publicznych interfejsów. Natomiast w większości przypadków strumień fil-
trujący dodaje metody publiczne o uzupełniającym przeznaczeniu. Czasami są one
przewidziane jako uzupełnienie typowych metod read () i write (), jak w przy-
padku metody unread () klasy PushbacklnputStream. Innym razem prawie
całkowicie zastępują oryginalny interfejs. Na przykład względnie rzadko stosuje się
metodę write () klasy PrintStream zamiast innych jej metod, print () oraz
println ().
Łańcuchowe łączenie filtrów
Filtry są podłączane do strumieni poprzez ich konstruktory. Na przykład poniższy
fragment kodu buforuje wejście pliku data.txt. Najpierw powstaje obiekt f i n stru-
mienia FilelnputStream poprzez przekazanie konstruktorowi strumienia Fi-
le InputStream nazwy pliku jako argumentu. Następnie tworzony jest obiekt bin
strumienia Buf feredlnputStream poprzez przekazanie bin jako argumentu
konstruktorowi strumienia FilelnputStream:
FilelnputStream fin = new FilelnputStream("data.txt");
BufferedlnputStream bin = new BufferedlnputStream(fin);
Od tego momentu możliwe jest zastosowanie metod read () zarówno dla obiektu
fin, jak i bin w celu wczytania danych z pliku data.txt. Jednak nieuporządkowane
wywołania różnych strumieni, podłączonych do tego samego źródła, mogą zakłócać
zależności pomiędzy strumieniami filtrującymi. Dlatego zwykle do przeprowadza-
nia odczytu lub zapisu powinieneś używać tylko ostatniego filtra z łańcucha. Jedy-
88_________________________________ Rozdział 4: Weiściej^fyiśaew^ąvie
nym sposobem napisania kodu tak, aby wprowadzenie tego rodzaju błędów było
przynajmniej trudniejsze, jest intencjonalne uwolnienie odnośnika do podstawowe-
go strumienia wejściowego. Na przykład:
InputStream in = new FilelnputStream("data.txt");
in = new BufferedlnputStream(in);
aplikacja
zbulorowany tekst
l InputStreamReader
:.
zbuforowane dań*
;' \
j GZIPInputStream |
zbuforowane, skompresowane dar*
i CipherlnputStream
zbuforowane. skompresowane i zaszyfttMMdini
BufferedlnputStream
pierwotne skompresowane i zaszyfrowuM
TelnetlnputStream j
pierwotne skompresowane i zaszyfrov?"e dane
sieć
Rysunek 4-2. Przepływ danych przez łańcuch filtrów
Po wykonaniu tych dwóch linii kodu nie będzie już żadnej możliwości uzyskania
dostępu do podstawowego strumienia wejściowego pliku, więc nie będziesz mógł
omyłkowo z niego czytać i uszkodzić bufora. Ten przykład działa, ponieważ nie jest
konieczne wprowadzanie rozróżnienia między metodami strumienia inputstre-
am a metodami strumienia Buf feredlnputStream. Buf f eredlnputStrearr. jest
Strumienie filtrujące________ _________________________89
po prostu wykorzystywany polimorficznie jako pierwszoplanowa instancja stru-
mienia InputStream. W takich sytuacjach, w których konieczne jest zastosowanie
dodatkowych metod strumienia filtrującego, nie zadeklarowanych w klasie nad-
rzędnej, możesz starać się skonstruować jeden strumień bezpośrednio wewnątrz
drugiego. Na przykład:
Da-aOutputStream dout = new DataOutputStream(new BufferedOutputStream ' "
(new FileOutputStream("data.txt") ) ) ; ,-.':
Takie instrukcje robią się nieco przydługie, więc łatwiej jest podzielić je na kilka linii,
jak poniżej:
DataOutputStream dout = new DataOutputStream(
new Buf feredOutputStream ( '' ';.. ''' .'-.:
new FileOutputStream("data.txt") ..'-.,, . ''' ' -j '. ;. f .," -'i.'*-.
) .;;>,;* r,,,- ; '"..," H '.',,-: ..:
) : ' " ......
Zdarzają się przypadki, w których musisz użyć metod wielu filtrów łańcucha. Na
przykład, gdy czytasz plik tekstowy w formacie Unicode, możesz chcieć odczytać
z trzech pierwszych bajtów znacznik porządku bajtów, aby sprawdzić, czy plik zo-
stał zakodowany jako big-endian UCS-2, little-endian UCS-2 lub UTF-8, a następnie
wybrać odpowiedni filtr Reader do odkodowania. Albo jeżeli jesteś połączony
z serwerem WWW, możesz chcieć przeczytać wysyłany przez serwer nagłówek
MIME, aby znaleźć pozycję Content-encoding i następnie użyć tego kodowania
treści, żeby wybrać właściwy filtr Reader do odczytania tekstu odpowiedzi. Albo
chcesz wysłać połączeniem sieciowym liczby zmiennoprzecinkowe za pomocą stru-
mienia DataOutputStream, a następnie pobrać MessageDigest ze strumienia
DigestOutputStream, do którego jest podłączony łańcuchowo strumień DataOut-
putStream. We wszystkich tych przypadkach musisz zapisać i wykorzystać odno-
śniki do każdego z podstawowych strumieni. Jednak pod żadnym pozorem nie po-
winieneś nigdy czytać z jakiegokolwiek innego filta niż ostatni w łańcuchu, również
pisać powinieneś tylko na tym filtrze. . ,, .,
Strumienie buforowane ;
Klasa Buf feredOutputStream przechowuje buforowane dane w buforze (chro-
nionej tablicy bajtów zwanej buf) do czasu, aż bufor się napełni lub strumień zosta-
nie opróżniony. Następnie zapisuje jednocześnie wszystkie dane na jej podstawo-
wym strumieniu wyjściowym. Jeden zapis wielu bajtów jest prawie zawsze szybszy
niż wiele małych zapisów, które dodają je porcjami. Szczególnie dotyczy to połączeń
sieciowych, ponieważ każdy segment TCP lub pakiet UDP przenosi skończoną ilość
danych narzutu, zazwyczaj wartą około 40 bajtów. A to oznacza, że przesłanie l kilo-
bajta danych po jednym bajcie wymaga wysłania kablem 40 kilobajtów, podczas gdy
wysłanie ich razem nieco ponad l kilobajt danych. Większość kart sieciowych i im-
plementacji TCP ma wbudowany pewien poziom buforowania, więc prawdziwe
statystyki nie są aż tak dramatyczne. Niemniej jednak buforowanie wyjścia siecio-
wego na ogół ogromnie poprawia wydajność.
90______________________________^ Rozdzia^Wejście^wyiście w Javie
Klasa Buf f eredlnputStream także posiada chronioną tablicę bajtów zwaną buf,
która służy jako bufor. Gdy wywoływana jest jedna z metod read () strumienia, to
najpierw próbuje ona pobrać żądane dane z bufora. Dopiero kiedy bufor opróżni się
z danych, strumień czyta z podstawowego źródła. W tym momencie wczytuje ze
źródła do bufora tyle danych, ile zdoła, niezależnie od tego, czy potrzebuje wszyst-
kich tych danych już teraz, czy nie. Dane, które nie zostaną wykorzystane natych-
miast, będą dostępne przy następnych wywołaniach metody read (). Przeczytanie
kilku tysięcy bajtów danych z podstawowego strumienia, jeśli pliki są czytane z dys-
ku lokalnego, jest prawie tak samo szybkie, jak wczytanie jednego bajta danych. Wi-
dać zatem, że buforowanie znacznie poprawia wydajność. Zysk jest mniej oczywisty
przy połączeniach sieciowych, gdzie często prędkość, przy której sieć może dostar-
czać dane, jest determinowana przez "korek" w sieci, a nie przez prędkość, z jaką in-
terfejs sieciowy dostarcza dane programowi, ani nie prędkość, z jaką działa pro-
gram. Pomimo tego buforowanie wejścia rzadko jest szkodliwe, a będzie stawać się
coraz istotniejsze, w miarę jak prędkość w sieci będzie rosła.
KlasaBuf f eredlnputStream ma dwa konstruktor)', podobnie jak Buf f eredOut-
putStream:
public BufferedlnputStream(InputStream in) .
public BufferedlnputStream(InputStream in, int bufferSize) .. :'
public BufferedOutputStream(OutputStream out)
public Buf feredOutputStream (OutputStream out, int bufferSize) .' ,.
Pierwszy argument jest podstawowym strumieniem, z którego zostaną odczytane
niezbuforowane dane lub w którym zostaną zapisane buforowane dane. Drugi ar-
gument, jeśli jest określony, definiuje liczbę bajtów w buforze. W przeciwnym przy-
padku rozmiar bufora jest ustalany na 2048 bajtów dla strumienia wejściowego i 512
bajtów dla strumienia wyjściowego. Idealny rozmiar bufora zależy od rodzaju bufo-
rowanego strumienia. Dla połączeń sieciowych dobrze jest mieć bufor trochę więk-
szy od typowego rozmiaru pakietu. Jednak może to być trudne do przewidzenia
i zmieniać się w zależności od lokalnych połączeń sieciowych i protokołów. Szybsze
sieci o szerszym paśmie przenoszenia raczej używają większych pakietów, tak więc
8 kilobajtów jest w efekcie maksymalnym rozmiarem pakietu dla UDP w większości
współczesnych sieci, a segmenty TCP często mają nie więcej niż jeden kilobajt.
Klasa Buf feredlnputStream nie ma zadeklarowanych żadnych nowych,
własnych metod. Nadpisuje jedynie metody z klasy Ir.put.Stream. Obsługuje zna-
kowanie i cofanie. Na przykład:
public synchronized int read O throws IOExcepticr.
public synchronized int read (byte [ ] input, inr offset, int length)
throws IOException
public synchronized long skipdong n) throws ICEy.ception
public synchronized int available() throws IOExcepticn '' ' ,
public synchronized void mark(int readLimit) -.': ': '. '.
public synchronized void resetO throws IOExcepticn
public boolean markSupported()
Począwszy od Javy 1.2, dwie wielobajtowe metody read () starają się kompletnie
wypełnić wybraną tablicę lub podtablicę danych, czytając z podstawowego strumie-
nia wejściowego tyle razy, ile jest to konieczne. Zwracają dane tylko wtedy, gdy ta-
Strumienie filtrujące_________________________________________97
blica lub podtablica została w całości wypełniona, koniec strumienia został osiągnię-
ty albo gdy podstawowy strumień zablokowałby się przy dalszych odczytach. Wię-
kszość strumieni wejściowych (w tym buforowany strumień wejściowy w Javie l .1 .x
i wcześniejszych) nie działa w opisany tu sposób. Czytają one z podstawowego stru-
jnienia lub źródła danych tylko jeden raz, zanim zaczną zwracać dane.
Klasa Buf f eredOutputStream także nie ma zadeklarowanych żadnych nowych,
własnych metod. Nadpisuje jedynie trzy metody z klasy OutputStream:
public synchronized void write(int b) throws IOException
public synchronized void write (byte [] data, int offset, int length) ' ''
throws IOException -.;'
public synchronized void flushO throws IÓException
Wywołuje się te metody dokładnie tak samo jak w przypadku każdego innego stru-
mienia wyjściowego. Różnica polega na tym, że każda metoda write () umieszcza
dane w buforze, a nie bezpośrednio w podstawowym strumieniu wyjściowym. Dla-
tego tak istotne jest opróżnianie strumienia, gdy tylko można to zrobić.
Klasa PrintStream
Klasa PrintStream jest pierwszym wyjściowym strumieniem filtrującym, z któ-
rym spotyka się większość programistów, ponieważ strumień System, out jest
klasą PrintStream. Natomiast inne strumienie wyjściowe mogą być łańcuchowo
dołączane do strumieni drukujących za pomocą poniższych dwóch konstruktorów:
public PrintStream(OutputStream out)
public PrintStream(OutputStream out, boolean autoFlush)
Domyślnie strumienie drukujące powinny być w jawny sposób opróżniane. Jeśli jed-
nak argumentem autoFlush jest true, to strumień będzie opróżniany za każdym
razem, gdy zostanie zapisana tablica bajtów lub znak przesuwu o wiersz albo gdy
zostanie wywołana metoda println ().
Klasa PrintStream, oprócz typowych metod write (), f lush () iclose(),ma
dziewięć przedefiniowanych metod print () i dziesięć przedefiniowanych metod
println ():
public void print (boolean b) ' ''''' '*'
public void print(char c) >''"'!'" -.-:' 7;"*Ś'TJ .-,,:.
public void print (int i) .:// .-r.;. ;,. <'!;.,: ,
public void print (long 1) . ;,'.../.,.,,,' " ^ . r, <,. r.. (,.-,,:,,).?'",....,..,
public void printffloat f) '"'. ' ' ,"".''''" '' ':v"'^ "'' f''"'.-"^'^;. ,,
Public void printfdouble d) ' ,'" !"Y"::I : '"':'. -" l .'" ''-*;' -''''' .;,-"'.';- ".
Public void printfchar;; text) ',;;fc:,i.; ; ,< -'...,.:::. 'l1,--' '-,' '
Public void print (String s) " ' ;" ''' ' - ' '' "
Public void print (Object o) '.':-' ''',' '". ;'' :fV/'-x-- /' :' '-''.' ' ':*' .',-;> *'..'<
Public void println () r|'-;";. .- ,, : .'.; ; < ' ;.','' '; ;'t , >
Public void println (booiean b) ...",,.: . . ;,, , ,\. ,
Public void println(char c) ," - . .-: - .. ;-,.
Public void println (int i) '-' I:L "'' : ' ' ; ' >'' '' '
Public void println (long 1) ,,-:.", - . : .. . / ,...',
Public void println (float f) .,. . '. . ., ... .. , :. ...,..'
Public void println (double d) " ' .,>-.,
Public void println (char [] text) ": ' - ' ' . -'... ''.' "
Public void println (String s) :'i , ., ?>?!:;; ,' i ,,..; j.^ .;,-..,
Public void println(Object o)
92_____________________________ Rozdział 4: Wejście i wyjście w Jawę
Każda metoda print () przekształca swój argument w ciąg w połowicznie przewi-
dywalny sposób i zapisuje go na podstawowym strumieniu wyjściowym, wykorzy-
stując domyślne kodowanie. Metody println () robią to samo, ale ponadto dodają
zależny od platformy znak oddzielania linii, aby zakończyć linię, którą zapisały.
W jest to znak przesuwu o wiersz (\n), na Macintoshu znak powrotu karetki (\r),
a w systemie Windows para znaków powrót karetki/przesuw o wiersz (\r \n).
Klasa PrintStream jest diabłem wcielonym i programiści sieciowi powinni unikać jej jak ognia
Pierwszym problemem jest to, że wyjście metody println () zależy od platformy.
W zależności od tego, w jakim systemie uruchamiasz swój kod, linie czasami mogą
być łamane znakami przesuwu o wiersz, znakami powrotu karetki lub parami znaków
powrót karetki/przesuw o wiersz. Nie powoduje to kłopotów, gdy piszesz na kon-
soli, ale ma katastrofalne skutki przy pisaniu sieciowych klientów i serwerów, które
muszą być zgodne z określonym protokołem. Większość protokołów sieciowych, ta-
kich jak HTTP, wymaga, aby linie były zakończone parą znaków: powrót karet-
ki/przesuw o wiersz. Stosowanie metody println () ułatwia pisanie programu,
który zadziała w systemie Windows, ale skończy się niepowodzeniem w Uniksie
i na Macintoshach. Chociaż wiele serwerów i klientów jest dość liberalnych pod tym
względem i potrafi obsłużyć niepoprawne zakończenia linii, to jednak trafiają się
wyjątki. W szczególności użycie metody println () przez klienta uruchomionego
na Macintoshu, w połączeniu z pokrótce omówionym błędem w metodzie readLi-
ne (), może zawiesić zarówno serwer, jak i klienta. Do pewnego stopnia można
temu zaradzić, używając jedynie metody print () i unikając println (). Ale są
też inne problemy z klasą PrintStream.
Drugi problem polega na tym, że klasa PrintStream zakłada, iż zastosowano do-
myślne kodowanie platformy, na której działa. Jednakże kodowanie nie musi być ta-
kie, jakiego spodziewają się serwer lub klient. Na przykład przeglądarka WWW,
otrzymując pliki XML, będzie oczekiwać, że zostały one zapisane w kodowaniu
UTF-8 lub zwykłym Unikodzie, chyba że serwer poinformuje ją, że tak nie jest. Nato-
miast serwer WWW, który stosuje klasę PrintStream, równie dobrze może wysłać
pliki zakodowane w CP1252 w amerykańskiej wersji systemu Windows lub w SJIS
w systemie japońskim, nie zważając na to, czy klient spodziewa się takiego kodowa-
nia lub je zrozumie. Klasa PrintStream nie dostarcza żadnego mechanizmu, za
pomocą którego dałoby się zmienić domyślne kodowanie. Można temu zaradzić,
stosując zamiast PrintStream pokrewną klasę PrintWriter. Problem sam w so-
bie jednak nie zniknie.
Trzecia trudność to fakt, że klasa PrintStream połyka wszystkie wyjątki. To po-
woduje, że klasa PrintStream jest odpowiednia dla prostych podręcznikowych
programów, takich jak HelloWorld, ponieważ prostego wyjścia konsoli można na-
uczać bez obarczania początkujących studentów obsługą wyjątków i wszystkimi
tego konsekwencjami. Natomiast połączenia sieciowe są znacznie mniej niezawod-
ne niż konsola. Połączenia normalnie zawodzą z powodu zatłoczenia sieci, arogancji
firm telefonicznych, awarii systemów zdalnych i z wielu innych przyczyn. Progra-
my sieciowe muszą radzić sobie z nieoczekiwanymi przerwaniami przepływu da-
Strumienie filtrujące_______ ______________ __ 93
nych. Służy temu obsługa wyjątków. Natomiast klasa Pr intstream przechwytuje
wszystkie wyjątki zgłaszane przez podstawowy strumień wyjściowy. Zwróć uwagę,
że deklaracja standardowych 5 metod klasy OutputStream w klasie PrintStream
nie zawiera typowej formułki throws IOException: ,.<>;/.,
public abstract void write(int b) ' ':'..''.' ,.'
public void write(byte[] data) , , ; ..,,.,. t . . .
public void write (byte [ ] data, int offset, int length) ' ' ',
public void flushO ' " ' > '" -
public void closeO
Zamiast tego klasa PrintStream posługuje się przestarzałą i nieodpowiednią flagą
błędu. Jeśli podstawowy strumień zgłosi wyjątek, ta wewnętrzna flaga błędu zostaje
postawiona. Trzeba mieć nadzieję, że programista sprawdzi wartość flagi za po-
mocą metody checkError ():
public boolean checkError()
Jeżeli programiści w ogóle przeprowadzają jakiekolwiek sprawdzanie błędów
w klasie PrintStream, to muszą po kolei sprawdzić każde wywołanie. Poza tym,
gdy błąd już wystąpił, nie ma żadnego sposobu, by opuścić flagę, więc nie da się wy-
kryć następnych błędów. Oprócz tego nie jest dostępna żadna informacja, co to był
za błąd. Krótko mówiąc, powiadamianie o błędach w klasie PrintStream nie
spełnia potrzeb zawodnych połączeń sieciowych. Na końcu tego rozdziału zostanie
wprowadzona klasa, która nadrabia wszystkie te niedociągnięcia.
Klasa PushbacklnputStream
PushbacklnputS t ream jest podklasą klasy Fi l ter InputS t r eam, która umożli-
wia "pchnięcie stosu z powrotem" (ang. push back stack), tak więc program może
"cofnąć odczyt" bajtów ze strumienia wejściowego. Klasy PushbacklnputStream
używa program obsługujący w Javie l .2 protokół HTPP. Możesz korzystać z tej pod-
klasy, gdy chcesz sprawdzić, co było nieco wcześniej w strumieniu, a potem wrócić.
Na przykład jeśli czytasz dokument XML, możesz przeczytać z nagłówka tyle, ile
trzeba, aby znaleźć deklarację kodowania, która informuje, jakiego zestawu znaków
użyto w dokumencie, a potem możesz wszystkie przeczytane dane wepchnąć z po-
wrotem do strumienia wejściowego i ponownie zacząć czytać z filtrem Reader,
skonfigurowanym odpowiednio do tego zestawu znaków.
Metody read () iavailable() podklasy PushbacklnputStream są wywoływa-
ne dokładnie tak samo, jak w przypadku normalnych strumieni wejściowych. Z tym,
że najpierw starają się wykonać odczyt z bufora typu pushback, zanim zaczną czytać
z podstawowego strumienia wejściowego. Tym, co wnosi ta klasa, jest metoda unre-
ad (), która cofa dane do bufora:
Public void unreadfint b) throws IOException
Ta metoda wpycha do strumienia bajt bez znaku, dany w postaci liczby typu int
z zakresu od O do 255. Liczby całkowite spoza tego zakresu są obcinane poprzez rzu-
towanie na typ byte. Jeżeli założymy, że nic innego nie zostało z powrotem we-
pchnięte do tego strumienia, to następny odczyt ze strumienia zwróci ten właśnie
94___________________________________Rozdział 4: Wejście i wyjście w Javie
bajt. Gdy do strumienia wpychamy wiele bajtów przez powtarzające się wywołania
metody unreadO, to są one przechowywane w stosie i zwracane w kolejności
"ostatni wchodzący jest pierwszym wychodzącym". W istocie rzeczy bufor jest sto-
sem umieszczonym nad strumieniem wejściowym. Tylko wtedy, gdy stos jest pusty,
można dokonać odczytu podstawowego strumienia.
Istnieją jeszcze dwie inne metody unread (), które wpychają do strumienia wska-
zaną tablicę lub podtablicę:
public void unread (byte [] input) throws IOException
public void unread(byte[] input, int offset, int leng-h) throws IOExcep-ion
Tablice są przechowywane na stosie w kolejności "ostatnia wchodząca jest pierwszą
wychodzącą". Natomiast bajty wypchnięte z tej samej tablicy będą zwracane w ko-
lejności, w jakiej wystąpiły w tablicy. To oznacza, że składnik zerowy tablicy zosta-
nie odczytany przed pierwszym.
Domyślnie bufor ma tylko jeden bajt długości, więc próba "cofnięcia odczytu" wię-
cej niż jednego bajtu spowoduje wysłanie wyjątku klasy IOException. Rozmiar
bufora można jednak zmieniać za pomocą drugiego z poniższych konstruktorów:
public PushbacklnputStream (InputStream in)
public PushbacklnputStream (InputStream in, int sizej
Chociaż obie klasy - PushbacklnputStream oraz Buf feredlnputStrearr. -
używają buforów, to Buf f eredlnputStream wykorzystuje go na dane odczytane
z podstawowego strumienia wejściowego, a PushbacklnputStream na dowolne
dane, które oryginalnie mogły zostać odczytane ze strumienia albo nie. Poza rym
klasa PushbacklnputStream nie umożliwia znakowania i cofania. Metoda
markSupported () klasy PushbacklnputStream zwraca wartość f alse.
Strumienie danych
Klasy DatalnputStream oraz DataOutputStrearr. dostarczają metod czyta-
jących i zapisujących prymitywne typy danych i ciągi Javy w formacie binarnym.
Formaty binarne są przeznaczone przede wszystkim do wymiany danych między
dwoma różnymi programami w Javie poprzez połączenie sieciowe, plik danych, po-
tok lub poprzez jakiś inny nośnik pośredni. To, co wyjściowy strumień danych zapi-
sze, strumień wejściowy może odczytać. Jednak zdarza się, że stosowane formaty są
takie same, jak te używane przez większość protokołów Internetu, które wymieniają
się binarnymi liczbami. Na przykład protokół czasu wykorzystuje 32-bitowe liczby
całkowite typu big-endian, czyli dokładnie takie jak w jawowym typie danych i r. t.
Usługa kontrolująca obciążenia elementów sieciowych używa 32-bitowych liczb
zmiennoprzecinkowych standardu IEEE 754, czyli takich jak w jawowym typie da-
nych f loat. (Prawdopodobnie jest to zamierzona, a nie przypadkowa zbieżność.
I Java, i większość protokołów sieciowych została opracowana przez projektantów
Uniksa i dlatego w obu przypadkach dominuje wykorzystanie formatów typowych
dla większości systemów uniksowych). Nie dotyczy to jednak wszystkich proto-
kołów sieciowych, więc powinieneś sprawdzić każdy protokół, którego używasz.
Na przykład w NTP (ang. Network Time Protocol - protokół czasu sieci) czas jest re-
Strumienie filtrujące________ __________________________95
prezentowany za pomocą 64-bitowych liczb stałopozycyjnych bez znaku z częścią
całkowitą w pierwszych 32 bitach i częścią ułamkową w ostatnich 32 bitach. Ten for-
mat nie pasuje do żadnego prymitywnego typu danych w żadnym z popularnych ję-
zyków programowania, chociaż praca z nim jest dość prosta, przynajmniej jeśli cho-
dzi o potrzeby NTP.
Klasa DataOutputStream dostarcza następujących jedenaście metod zapisywania
poszczególnych typów danych w Javie:
public finał void writeBoolean(boolean b) throws IOException ' ' :' -
public finał void writeByte (int b) throws IOException , .;.,.."'
public finał void writeShort (int s) throws IOException . ' ,
public finał void writeChar (int c) throws IOException . . ;!
public finał void writelnt(int i) throws IOException ' ' -' ,.'' '"'
public finał void writeLong (long 1) throws IOException ...';,. ,i\ i.. /^;-.:
public finał void writeFloat(float f) throws IOException
public finał void writeDouble (double d) throws IOException ': "'*?' tv'"''' 1'-i)-'a" '.
public finał void writeChars (String s) throws IOException . : ,:> :;v.' '
public finał void writeBytes (String s) throws IOException .:;., ,tf\ ,:,,:, ii..'.
public finał void writeUTF (String s) throws IOException '.'" -
Wszystkie dane są zapisywane w formacie big-endian. Liczby całkowite są zapisy-
wane w dwójkowym dopełnieniu w minimalnej liczbie możliwych bajtów. Zatem
byte jest zapisywany jako jeden bajt dwójkowego dopełnienia, shor t jako dwa baj-
ty dwójkowego dopełnienia, int jako cztery bajty dwójkowego dopełnienia, a long
jako osiem bajtów dwójkowego dopełnienia. Liczby typu float i double są zapisy-
wane w formacie IEEE 754 odpowiednio w4 i 8 bajtach. Dane typu boolean są zapi-
sywane w postaci jednego bajtu o wartości O w przypadku fal s e i wartości l dla
true. Dane typu char są zapisywane jako bajty bez znaku.
Ostatnie trzy metody są nieco mylące. Metoda writeChars () przeprowadza itera-
q'ę przez argument String, zapisując każdy kolejny znak jako 2-bajtowy znak Uni-
kodu o formacie big-endian. Metoda writeBytes () wykonuje iterację przez argu-
ment String, ale zapisuje tylko najmniej znaczący bajt każdego znaku. Dlatego in-
formacje z każdego ciągu, który będzie zawierać znaki spoza zestawu Latin-1,
zostaną utracone. Ta metoda może być przydatna w niektórych protokołach sie-
ciowych, które stosują kodowanie ASCII, ale na ogół powinieneś jej unikać.
Ani metoda writeChars (), ani writeBytes () nie kodują długości ciągu zna-
ków w strumieniu wyjściowym. W konsekwencji nie można tak naprawdę rozróżnić
pierwotnych znaków od znaków stanowiących część ciągu. Metoda wri-
teUTF () wyznacza długość ciągu znaków. Sam ciąg koduje w wariancie formatu
UTF-8 zamiast w zwykłym Unikodzie. Ponieważ metoda writeUTF () wykorzy-
stuje wariant formatu UTF-8, który w nieznacznym stopniu jest niekompatybilny z
większością nie jawowego oprogramowania, powinna być stosowana jedynie do
wymiany danych z innymi programami w Ja vie, które wykorzystują klasę Dataln-
putStreamdo czytania ciągów. Do wymiany tekstu w formacie UTF-8 z całą resztą
oprogramowania, powinieneś zastosować klasę InputStreamReader z odpo-
wiednim kodowaniem. (Nie byłoby żadnych wątpliwości, gdy firma Sun po prostu
nazwała tę metodę i jej partnerkę writeString () i ReadString () , zamiast
writeUTF () i readUTF ()).
96________________________________Rozdział 4: Wejście i wyjście wJavie
DataOutputStream, oprócz tych metod do zapisywania liczb binarnych, nadpisu-
je trzy z typowych metod OutputStream:
public void writednt b) "-*
public void write(byte[] data, int offset, int length)
public void flush()
Wywołuje się je w zwykły sposób, z typową składnią.
Da t a InputS t ream jest klasą komplementarną do klasy Dat aOutputStream.
Każdy format zapisywany przez DataOutputStream, może zostać odczytany
przez DatalnputStream. Poza tym klasa DatalnputStreamma typowe metody
read (), available (), skip () oraz close (), a także metody do wczytywania
kompletnych tablic bajtów i linii tekstu.
Istnieje dziwięć metod czytania danych binarnych, które odpowiadają jedenastu
metodom w klasie DataOutputStream (nie ma dokładnego odpowiednika dla
metod writeBytes () i writeChars (); są one obsługiwane poprzez wczytywa-
nie bajtów pojedynczo):
public finał boolean readBoolean () throws IOException ... ,
public finał byte readByte() throws IOException ':., '.'.
public finał char readCharO throws IOException , ..-- ,. >
public finał short readShortO throws IOException , .......
public finał int readlntO throws IOException
public finał long readLongO throws IOException '<' '; \ "' ' '-':-
public finał float readFloatO throws IOException .\ ",-- ,. ' ''v :,.-.,"
public finał double readDoubleO throws IOExcep"ion , t r .,,-..,,--
public finał String readUTFO throws IOException ~~ "' '"
Oprócz tego klasa DatalnputStream zapewnia dwie metody do odczytywania
bajtów bez znaku i liczb typu short bez znaku i zwraca równoważnik typu int.
W Javie nie ma żadnego z tych typów danych, ale możesz je napotkać podczas czyta-
nia danych binarnych, które zostały zapisane przez program w języku C:
public finał int readUnsignedByte () throws IOException ,
public finał int readUnsignedShort () throws lOException
Klasa DatalnputStream ma też dwie typowe, wielobajtowe metody read (), które
wczytują dane do tablicy lub podtablicy i zwracają liczbę wczytanych bajtów. Posia-
da też dwie metody readFully (), które wielokrotnie wczytują do tablicy dane
z podstawowego strumienia wejściowego, aż zostanie osiągnięta zadana liczba bajtów.
Jeśli niemożliwe jest przeczytanie wystarczającej liczby danych, wysyłany jest
wyjątek klasy IOException. Te metody są szczególnie przydatne, gdy z góry wia-
domo, ile jest bajtów do przeczytania. Tak może być w przypadku, gdy odczytasz
pole Content-length nagłówka MIME protokołu HTTP i stąd wiesz, ile jest
bajtów:
public finał int read(byte[] input) throws IOException
public finał int read(byte[] input, int offset, int length) throws IOException
public finał void readFully (byte[] input) throws IOException
public finał void readFully (byte[] input, int offset, int length)
throws IOException
Strumienie filtrujące_______ ________________________ 97
Ponadto klasa DatalnputStream oferuje popularną metodę readLine (), która
wczytuje linię tekstu ograniczoną terminatorem linii i zwraca ciąg:
public finał String readLine() throws IOException
Jednakże ta metoda pod żadnym pozorem nie powinna być używana. Została zdys-
kwalifikowana, ponieważ nie działa prawidłowo. Została odrzucona, gdyż w więk-
szości przypadków nie przekształca poprawnie znaków nie-ASCII w bajty. To zada-
nie wykonuje obecnie metoda readLine () klasy Buf f eredReader. Jednak obie
te metody zawierają ten sam podstępny błąd: nie zawsze uznają pojedynczy znak
powrotu karetki za koniec linii. Metoda readLine () rozpoznaje tylko znak przesu-
wu o wiersz lub parę znaków: powrót karetki/przesuw o wiersz. Wtedy, kiedy w
strumieniu zostanie wykryty znak powrotu karetki, metoda readLine () czeka,
aby sprawdzić, czy następnym w kolejności będzie znak przesuwu o wiersz, zanim
zacznie kontynuować. Jeśli następnym znakiem będzie znak przesuwu o wiersz, to
oba znaki: powrót karetki i przesuw o wiersz zostaną odrzucone, a linia jest zwra-
cana jako String. Jeżeli natomiast następnym znakiem nie będzie znak przesuwu o
wiersz, to znak powrotu karetki jest odrzucany, linia zwracana jako String, a ten
dodatkowy, przeczytany znak stanie się częścią następnej linii. Jeśli jednak znak po-
wrotu karetki jest ostatnim znakiem w strumieniu (bardzo prawdopodobne, gdy
strumień pochodzi z Macintosha lub pliku utworzonego na Macintoshu), to metoda
readLine () zawiesza się, czekając na ostatni znak, który nie nadchodzi.
Ten problem nie jest tak oczywisty, gdy odczytuje się plik, ponieważ prawie na pew-
no pojawi się następny znak, choćby -l na końcu strumienia. Natomiast przy stałych
połączeniach sieciowych, takich jak te używane w FTP i ostatnim modelu HTTP, ser-
wer lub klient może po prostu przerwać wysyłanie danych po ostatnim znaku i cze-
kać na odpowiedź, nie zamykając połączenia. Jeśli masz szczęście, to na jednym lub
drugim końcu połączenia może zostać przekroczony czas i otrzymasz wyjątek klasy
IOException, choć prawdopodobnie zajmie to co najmniej kilka minut. Jeśli ci się
nie poszczęści, program zawiesi się definitywnie.
Zwróć uwagę, że w celu uniknięcia tego błędu, nie wystarczy tylko uruchomić pro-
gram w systemie Windows lub Unix. Trzeba także zagwarantować, że program nie
wyśle ani nie odbierze plików tekstowych utworzonych na Macintoshu i że nigdy
nie będzie się komunikować z klientem lub serwerem Macintosha. Te warunki są
bardzo trudne do spełnienia w różnorodnym świecie internetowym. Znacznie
łatwiej jest po prostu unikać metody readLine ().
Strumienie kompresowane
Pakiet j ava . util. zip zawiera strumienie filtrujące, które kompresują i dekom-
presują strumienie w formatach zip, gzip i deflate. Dobrze znane są zastosowania
tych formatów dla plików, ale oprócz tego ułatwiają one aplikacjom Javy wymianę
skompresowanych danych poprzez sieć. HTTP 1.1 w jawny sposób zawiera obsługę
transferu skompresowanych plików, w której serwer kompresuje pliki, a przeglądar-
ka je dekompresuje, dzięki czemu angażuje coraz tańszą moc procesora, zamiast
wciąż drogiego pasma przenoszenia sieci. Jest to realizowane w sposób zupełnie nie-
98________________________________Rozdział 4: Wejście^wyjście w Javie
zauważalny dla użytkownika. Oczywiście nie jest to niewidoczne dla programisty,
który napisał kod kompresujący i dekompresujący dane. Jednak dzięki stru-
mieniowi filtrującemu java . util. zip jest to mniej widoczne, niż w jakimkolwiek
innym przypadku.
Istnieje sześć klas strumieni, które zajmują się kompresją i dekompresją danych.
Strumienie wejściowe dekompresują dane, a wyjściowe je kompresują. Są to:
public class DeflaterOutputStream extends FilterOutputStream
public class InflaterlnputStream extends FilterlnputStream
public class GZIPOutputStream extends FilterOutputStream ''>'
public class GZIPInputStreara extends FilterlnputStream . .. -
public class ZipOutputStream extends FilterOutputStream .
public class ZipInputStream extends FilterlnputStreair.
Wszystkie te metody tak naprawdę wykorzystują ten sam algorytm kompresji. Róż-
nią się tylko rozmaitymi stałymi i metainformacjami zawartymi w skompresowa-
nych danych. Poza tym strumień zip może zawierać więcej niż jeden skompresowa-
ny plik.
Kompresowanie i dekompresowanie danych za pomocą tych klas jest tak naprawdę
wyjątkowo łatwe. Należy po prostu łańcuchowo dołączyć filtr do podstawowego
strumienia i czytać lub pisać jak zwykle. Na przykład przypuśćmy, że chcesz prze-
czytać skompresowany plik wszystkienazwy.gz. Wystarczy otworzyć strumień Fi-
lelnputStream dla pliku i podłączyć łańcuchowo GZIPInputStream:
FilelnputStream fin = new FilelnputStream ( "wszystkier.azwy. gz" ) ;
GZIPInputStream gzin = new GZIPInputStream(fin);
Począwszy od tego momentu możesz czytać nieskompresowane dane ze strumienia
gzin, stosując po prostu typowe metody read (), skip {) oraz availabie () . Na
przykład ten fragment kodu czyta i dekompresuje plik o nazwie wszystkienazwy.gz
w bieżącym katalogu roboczym:
FilelnputStream fin = new FilelnputStream ("wszystkier.azwy . gz" ) ;
GZIPInputStream gzin = new GZIPInputStream (fin) ; ,."'.
FileOutputStream fout = new FileOutputStream ("wszystkier.azwy" );
int b = 0; ; ';
while ((b = gzin.readO) != -1) f out. write (b) ; .. "?-",
gzin . close () ; , -,,
out.flush() ;
out. close () ; ''''
Prawdę mówiąc, nie trzeba nawet wiedzieć, że strumień gzin jest instanq'ą klasy
GZIPInputStream. Równie dobrze zadziałałby zwykły typ InputStrea-. Na
przykład:
InputStream in = new GZIPInputStream(new FilelnputStream("wszystkienazwy.gz"));
Korzystanie z klas Def laterOutputStream oraz Inf laterlnputStream jest
równie proste. Z kolei stosowanie klas ZipInputStream oraz ZipOutputStream
jest nieco bardziej skomplikowane, ponieważ plik zip to właściwie archiwum, które
może zawierać wiele wpisów, a każdy z nich należy czytać oddzielnie. Każdy plik w
archiwum zip jest reprezentowany przez obiekt zipE.itry, dla którego metoda
Strumienie filtrujące_______ _____________________ 99
getName () zwraca oryginalną nazwę pliku. Na przykład poniższy fragment kodu
dekompresuje archiwum shareware.zip w bieżącym katalogu roboczym:
F; lelnputStream fin = new FilelnputStream ("shareware. zip") ; ',.; - ,
ZipInputStream zin = new ZipInputStream (f in) ; ; ' '
ZipEntry ze = null; : ! ' !'
int b = 0; , , . , .v- .
whi-e ((ze = zin.getNextEntry ()) != null) {
FileOutputStream fout = new FileOutputStreamfze.getName());
while ((b = zin.readO) != -1) f out. write (b) ; - " "''- :.'':
zin. closeEntry () ; ...
fout.flushO ; V ,. .. . . . , ^ . . .
fout .close O ; "',':' '" '' : '. J- ''' ' ' ' . <''-' v' ; :
l V! ',''' ' '"' ' ' ' ';' '' ''':''', --.''..: ^ .;.'".
zin.closeO; ^r'^ .... '. ,, t ,, , -\ , / ', ';<-:,\,.,, V? .-. " r \ ,,. .',.. ..
Strumienie sygnowane
Pakiet java. util. security zawiera dwa strumienie filtrujące, które mogą
wyliczyć cyfrową sygnaturę dla strumienia. Są to DigestlnputStream oraz
DigestOutputStream. Sygnatura, reprezentowana w Javie przez klasę java.
util. security .Me s s ageDige s t, jest dużym streszczeniem strumienia. Jest ona
obszerną liczbą całkowitą (zazwyczaj o długości 20 bajtów w formacie binarnym),
którą można łatwo wyliczyć na podstawie strumienia o dowolnej długości w taki
sposób, by z sygnatury nie dało się uzyskać żadnych informacji o strumieniu. Sygna-
tura może być wykorzystywana jako cyfrowy podpis lub do wykrywania danych,
które zostały uszkodzone podczas przesyłania siecią.
W praktyce ważniejsze jest zastosowanie sygnatury jako cyfrowego podpisu. Zwykłe
uszkodzenie danych da się wykryć za pomocą znacznie prostszych algorytmów,
które nie wymagają tak kosztownych obliczeń. Jednak strumienie sygnujące są tak
łatwe w użyciu, że niekiedy koszt wyliczenia sygnatury opłaca się ze względu na
uzyskiwany wzrost wydajności programistycznej. Aby wyliczyć sygnaturę dla stru-
mienia wyjściowego, musisz najpierw skonstruować obiekt MessageDigest, który
stosuje konkretny algorytm, taki jak SHA (ang. Secure Hash Algorithm - bezpieczny
algorytm z mieszaniem). Zarówno obiekt MessageDigest, jak i strumień, który
chcesz poddać algorytmowi, przekazujesz konstruktorowi klasy DigestOutput-
Stream. W ten sposób łączysz łańcuchowo strumień sygnujący z podstawowym
strumieniem wyjściowym. Potem, jak zwykle, zapisujesz dane na strumieniu, opró-
żniasz go i zamykasz, a następnie wywołujesz metodę getMessageDigest (), by
pobrać obiekt MessageDigest. Na koniec wywołujesz metodę digestO na
obiekcie MessageDigest, aby dokończyć wyliczanie aktualnej sygnatury. Oto
przykład:
3 n*v!,:'../};..:.:'
HessageDigest sha = MessageDigest .getlnstance ("SHA") ; _, .... ,,",,;,",'
3^ges-OutputStream dcut = new DigestOutputStream (out, sha); ....... < '.'
byte ;; buffer = new byte [128] ; ' '>,'.'.">: :';
while (true) ( '-':' -' "',/'?'''"','.'', ''-
int bytesRead = in . read (buffer) ; {-.-> ...-./ ,,,,,; ,^'';:,'--,;.
if (bytesRead < 0) break; ... . .... '".,-. ', ' -
dout .write (buffer, O, bytesRead); .<.>,. yi .i... .,( . ..
) .-'i.iiH Jf.lMi,-^ ,!C/ti'v,W>
100 Rozdział 4: Wejście i wyjście w Javie
dout .flush () ;
dout. close () ;
byte[] result = dout.getMessageDigest().digest();
Obliczenie sygnatury dla odczytywanego strumienia wejściowego jest równie
łatwe. Nie jest to jednak tak oczywiste jak przy innych strumieniach filtrujących,
gdyż musisz posiadać przynajmniej podstawową biegłość w metodach klasy
MessageDigest. Niemniej jednak jest to i tak prostsze, niż napisanie własnej za-
bezpieczonej funkcji mieszania i ręczne podawanie jej każdego bajtu, który zapi-
sałeś.
Oczywiście potrzebny jest również sposób związania konkretnej sygnatury z kon-
kretnym strumieniem. W pewnych okolicznościach sygnatura może być przesyłana
tym samym kanałem, który jest wykorzystywany do transmisji streszczonych da-
nych. Nadawca może wyliczyć sygnaturę przy wysyłaniu danych, a odbiorca zrobić
to samo, gdy je dostanie. Gdy wysyłający skończy, przesyła pewien sygnał, który
odbiorca rozpoznaje jako oznaczenie końca strumienia, oraz wysyła sygnaturę. Ad-
resat odbiera sygnaturę, sprawdza, czy jest ona taka sama, jak ta wyliczona przez
niego, i zamyka połączenie. Jeśli sygnatury się nie pokrywają, odbiorca może popro-
sić nadawcę o ponowne wysłanie wiadomości, zamiast zamykać połączenie. Innym
rozwiązaniem jest zapisanie sygnatury i plików, których dotyczy, w jednym archi-
wum zip. Istnieje też wiele innych możliwości. Sytuacje, takie jak ta, aż proszą się
o zaprojektowanie względnie formalnego, specjalnego protokołu. Jednakże proto-
kół mógłby być skomplikowany, a obliczenie sygnatury jest proste, dzięki klasom
filtrów DigestlnputStream oraz DigestOutputStream.
Strumienie szyfrujące
Nie wszystkie strumienie filtrujące stanowią część kluczowego interfejsu API Javy.
Z powodów legislacyjnych filtry przeznaczone do szyfrowania i odszyfrowywania
danych, CipherlnputStream oraz CipherOutputStream, są częścią standardo-
wego rozszerzenia Javy zwanego JCE (ang. Java Cryptogmphy Extension - szyfrujące
rozszerzenie Javy). Znajduje się ono w pakiecie j avax . crypto. Firma Sun udo-
stępnia implementację tego API w Stanach Zjednoczonych i w Kanadzie pod adre-
sem http://java.sun.com/products/jce/, a różne inne produkty, napisane jako niezależne
implementacje, są powszechnie dostępne na całym świecie. Szczególną uwagę nale-
ży zwrócić na pakiet Open Source Cryptbc, który można pobrać z witryny
http://unuw.cryptix.org/.
Obie klasy CipherlnputStream i CipherOutputStream są zasilane przez mo-
tor Cipher, czyli obiekt, w którym zagnieżdżony jest algorytm przeznaczony do
szyfrowania i odszyfrowywania danych. Zmieniając obiekt Cipher, wymieniasz
algorytm wykorzystywany przez strumienie do szyfrowania i odszyfrowywania.
Do większości szyfrów potrzebny jest klucz, który został użyty do szyfrowania i od-
szyfrowywania danych. Szyfry z symetrycznym lub tajnym kluczem wykorzystują
ten sam klucz do szyfrowania i odszyfrowywania danych. Szyfry z asymetrycznym
lub publicznym kluczem wykorzystują do szyfrowania inny klucz niż do odszyfro-
wywania. Klucz szyfrujący może być rozpowszechniany dopóty, dopóki klucz do
Strumienie filtrujące_________ __________ 707
łamania szyfru jest trzymany w tajemnicy. Klucze są specyficzne dla zastosowanego
algorytmu i w Javie są reprezentowane przez instanq'e interfejsu java.securi-
ty.Key. Obiekt Cipher jest określany w konstruktorze. Argumentem tych kons-
truktorów, podobnie jak wszystkich konstruktorów strumieni filtrujących, jest inny
strumień wejściowy:
public CipherlnputStream(InputStream in, Cipher c)
public CipherOutputStreamdnputStream in, Cipher c)
Aby uzyskać właściwie zainiq'alizowany obiekt Cipher, używamy statycznej,
wbudowaanej metody Cipher. getlnstance (). Ten obiekt Cipher, zanim zo-
stanie przekazany do jednego z powyższych konstruktorów, musi zostać zainicjali-
zowany do szyfrowania albo do odszyfrowywania za pomocą metody i n i t (). Na
przykład następujący fragment kodu przygotowuje CipherlnputStream do od-
szyfrowywania za pomocą hasła "two and not fnord" i algorytmu DES (ang. Data
Encryption Standard - standard szyfrowania danych):
byte[] desKeyData = "two and not a fnord".getBytes();
DESKeySpec desKeySpec = new DESKeySpec (desKeySpec);
SecretKeyFactory keyFactory = SecretKeyFactory.getlnstance("DES");
SecretKey desKey = keyFactory.generateSecret(desKeySpec);
Cipher des = Cipher.getlnstance("DES");
des.init(Cipher.DECRYPT_MODE, desKey);
CipherlnputStream cin = new CipherlnputStream(fin, des);
Ten fragment kodu wykorzystuje klasy z pakietów j ava. security, j ava. secu-
rity.spec, javax.crypto oraz javax.crypto. spec. Różne implementacje
JCE obsługują różne grupy algorytmów szyfrujących. Popularnymi algorytmami są
DES, RSA oraz Blowfish. Konstruowanie klucza jest w zasadzie specyficzne dla al-
gorytmu. Więcej informacji na ten temat znajdziesz w dokumentacji swojej imple-
mentacji JCE.
Klasa CipherlnputStream nadpisuje większość zwykłych metod klasy
InputStream, takich jak read() oraz avai labie () .Z kolei klasa CipherOutput-
Stream nadpisuje większość typowych metod klasy OutputStream, takich jak wri-
te () oraz f l u s h (). Te metody wywołuje się w znacznym stopniu tak samo jak dla
każdego innego strumienia. Z tym, że w trakcie czytania lub zapisywania danych
obiekt Cipher strumienia deszyfruje dane lub je zaszyfrowuje. (Zakładając, że twój
program ma działać na odszyfrowanych danych, co jest typowym przypadkiem,
wejściowy strumień szyfrujący będzie odszyfrowywał dane, a wyjściowy strumień
szyfrujący będzie je zaszyfrowywał). Na przykład ten fragment kodu zaszyfrowuje
plik sekrety.txt za pomocą hasła "Marysia ma małego pająka":
String infile = "sekrety.txt"; . ; '''. ' ;
String outfile = "sekrety.des"; v : , ;,,vv ',. > \
String password = "Marysia ma małego pająka"; . ../'..
try { /,,.;.. ...,!,,-w. .,'.
FilelnputStream fin = new FilelnputStreamfinf ile) ; ,.-.; , '.-. . J
FileOutputStream fout = new FileOutputStream(outfile);
//rejestracja dostawcy, który zaimplementował algorytm
Provider sunJce = new com.suń.crypto.provider.SunJCE();

Wyszukiwarka

Podobne podstrony:
08 Integracja Javy z innymi językami, programowanie sieciowe
Programowanie sieciowe
java programowanie sieciowe(1)
Programowanie sieciowe dzienne L2 Podstawy Javy
Programowanie sieciowe dzienne W2 Podstawy Javy
Programowanie sieciowe dzienne W2 Podstawy Javy
zestawy cwiczen przygotowane na podstawie programu Mistrz Klawia 6
Międzynarodowy Program Badań nad Zachowaniami Samobójczymi
CSharp Introduction to C# Programming for the Microsoft NET Platform (Prerelease)
Instrukcja Programowania Zelio Logic 2 wersja polska
Program wykładu Fizyka II 14 15
roprm ćwiczenie 6 PROGRAMOWANIE ROBOTA Z UWZGLĘDNIENIEM ANALIZY OBRAZU ARLANG
io port programming 3ogqzy3bscrrpgv753q3uywjfexgwwoiiffd46a 3ogqzy3bscrrpgv753q3uywjfexgwwoiiffd46a
2009 12 Metaprogramowanie algorytmy wykonywane w czasie kompilacji [Programowanie C C ]

więcej podobnych podstron