Komunikacja sieciowa
Klasy sieciowe znajdują się w pakiecie java.net (import java.net.*;). Pakiet java.net zawiera następujące klasy do
obsługi komunikacji sieciowej:
java.lang.Object
java.net.InetAddress opisuje adres komputera w sieci poprze z:
nazwę/domenę, np. www.fu w.edu.pl oraz
numer IP, np. 193.0.81.28.
java.net.SocketAddress
java.net.Socket
java.net.ServerSocket
java.net.Datagra mSoc ket
Wyróżniamy gniazda strumieniowe, ko munikujące się za po mocą protokołu TCP oraz gniazda datagramowe,
działające w oparciu o protokół UDP.
Do gniazd TCP zaliczamy klasy:
Socket -Wykorzystuje ją klient i serwe r (wysyłają i odbie rają prze z nią dane).Daje kontakt z Internetem
naszemu apletowi i serwerowi (tak jak gniazdo sieci elektrycznej u możliwia podłączenie do niej różnych
urząd zeń).
Klasa ta posiada szereg różnych konstruktorów, z których najbardziej popularne są dwa:
Socket(String host, int por t)
// gdzie host to tekst oznaczający nazwę hosta
// port - numer portu (0-65535)
Socket(InetAddress address, int port)
//gdzie address to obiekt klasy InetAddress będący
//adresem IP lub nazwą hosta
Posiada ona również metody, które pozwalają uzyskać informacje związane z obiektami tej klasy, takie jak:
getLocal Address() - zwraca lo kalny adres, do którego dowią zane jest gniazdo,
getLocalPort() - zwraca loka lny port, do którego dowią zane jest gniazdo,
getInetAddress() - zwraca zdalny adres, do którego gniazdo jest podłączone,
getPort() - zwraca zda lny numer portu, do którego gniazdo jest podłączone.
Przykład 1. Przykładowy wygląd klasy Klient wykorzystująca klasę Socket może wyglądać następująco
:
class
Klient
{
// strumień we jściowy
public
DataInputStream we;
// strumień wyjścio wy
public
PrintStrea m wy;
// gniazdo do Internetu
private
Soc ket gnia zdo;
// konstruktor: host (adres serwera), port (nr portu, na którym nas łuchuje serwer)
public
Klient(String host, int port)
{
try
{
gnia zdo = new Socket(host,port);
wy = new PrintStrea m(gnia zdo.getOutputStream());
we = ne w DataInputStream(gniazdo.getInputStream());
} //
try
catch
(IOException e) {}
} // konstruktor Klient(String host, int port)
} // klasa Klient
Frag ment kodu tej klasy mo że wyg lądać następująco:
public
class
Klient {
public
static
void
ma in(St ring[] args) {
Socket gnia zdo;
try
{ gnia zdo =
ne w
Soc ket
(
"www.fuw.edu.pl"
, 80); }
catch
(Unknown HostException e)
{ System.err.println(e); }
catch
(IOException e)
{ System.err.println(e); }
}
}
W powyższy m przykład zie podjęta jest próba połączenia z serwerem www.fuw.edu.pl na porcie 80. Jeśli nazwa
hosta jest nieznana lub serwer nazw nie d ziała, to zostanie zwrócony wyjątek n ieznanego hosta -
UnknownHostException. Jeśli z innych przyczyn nie uda się u zyskać połączen ia, zostanie zwrócony wyjątek
IOException
Można użyć też jej np. tak:
Klient klient = new Klient(...);
String msg = "Pozdro wien ia od klienta";
klient.wy.println(msg); // wys łanie danych do serwera
msg = klient.we.readLine(); // przec zytanie odpowiedzi
Przykład 2. Inna imple mentacja klasy Klient
import
java.net.Socket;
import
java.net.UnknownHostException;
import
java.io.IOException;
import
java.io.BufferedReader;
import
java.io.InputStreamReader;
import
java.io.PrintWriter;
otwiera gnia zdo
static
final String HOST = "violet 01.mimu w.edu.pl";
Socket sd =
null;
try
{
sd = new Socket(HOST, Server.PORT);
}
catch
(UnknownHostException e ) {}
otwiera stru mień wejściowy i wy jściowy na gnieździe
Buffe redReader in = null;
PrintWriter out = null;
try
{
in = new Buffe redReader(ne w InputStrea mReader(sd.getInputStream()));
out = new PrintWriter(sd.getOutputStream(),true);
}
catch
(IOException e) {}
zamy ka strumienie związane z gniazdem
out.close();
in.close();
za my ka gnia zdo
sd.close();
ServerSocket- słu ży do tworzenia gnia zd serwerowych .
Jej metoda acce pt powoduje, że wąte k serwe ra zawiesza się c ze ka jąc na zgłoszenie klienta:
// port na którym nasłuchuje serwer
fina l static
int SERVER_PORT = 9001;
ServerSocket serwer;
Socket gnia zdo;
String msg;
try
{
server = ne w Se rverSoc ket(SERVER_ PORT);
// serwer c ze ka na klienta
gnia zdo = server.accept();
// mając gniazdo wy mienia dane z kliente m
// analogic znie jak on . . .
}
catch
(IOException e) {}
Przykład 3. Implementacja Serwera
import
java.net.Socket;
import
java.net.ServerSoc ket;
import
java.io.IOException;
import
java.io.BufferedReader;
import
java.io.InputStreamReader;
import
java.io.PrintWriter;
otwiera gniazdo nasłuchujące na porcie, port 0 oznacza p ierwszy wo lny
import
java.net.ServerSoc ket;
import
java.io.IOException;
public static fina l
int PORT = 1024;
ServerSocket sd = null;
try
{
sd = new ServerSocket(PORT);
}
catch
(IOException e ) {}
Maksymalna d ługość kolejki oczekujących na połączenie wynosi 50.
akceptuje nadchodzące połączenie od klienta
import
java.net.Socket;
Socket client = nu ll;
try
{
c lient = sd.accept();
}
catch
(IOException e ) {}
Wątek serwera zostaje zab lokowany aż zaakceptuje połączenie.
otwiera stru mień wejściowy i wy jściowy na gnieździe klienckim
za my ka strumienie zwią zane z gnia zde m
za my ka gnia zdo
Dla przykładu podaje program łączący się z serwerem czasu, a następnie wyświetlający czas na ekranie:
import
java.net.*;
import
java.io.*;
public
class
Zegar {
public
static
void
main(String[] a rgs) {
Socket gnia zdo;
String host = "info.cyf-kr.edu.pl";
Buffe redReader strumienCzasu;
if
(args.length > 0) {
host = args[0];
}
try
{
gniazdo
=
ne w
Soc ket (host, 13);
strumien Czasu =
new
Buffe redReader(
new
InputStreamReader(gniazdo.getInputStream()));
String c zas = strumien Czasu.readLine();
System.out.println("Na "+host+" jest: "+czas);
}
catch
(UnknownHostException e ) {System.err.println(e);}
catch
(IOException e) {System.err.println(e );}
}
}
Ponadto oddzielna klasa powinna imp lementować protokół ko munikacyjny.
class Protocol {
St ring processInput(String in) {
// zwraca odpowiedź na podstawie otrzy manego pytania i/lub swojego stanu.
}
}
Podsumowanie
Aby aplet mógł się ko munikować n ie tylko z ko mputerem, z którego został pobrany, możn a stworzyć
ko munikację pośrednią przez serwer. Inne zastosowania serwera d ziałającego na ko mputerze źródłowy m strony:
* wyciąganie i wprowad zanie danych do bazy,
* pobieranie danych od jednego klienta i wysyłanie do pozostałych,
* ogólnie wykonywanie dowolnej usługi żądanej przez klienta.
Dodatkowo:
Inna klasa wy korzystywaną w Javie do adresowania ko mputerów jest klasa URL ora z je j pochodne:
URLClassLoader,
URLConnection,
URLDecoder,
URLEncoder,
URLStrea mHandler.
URL c zyli Uniform Resource Locator jes t specjalną formą adresu zasobów w siec i. URL posiada dwa
podstawowe elementy: identyfikator protokołu o raz nazwę zasobów. Identyfikator p rotokołu to np. http, ftp,
gopher, rmi czy jdbc. Nazwę zasobów stanowią takie elementy jak: nazwa hosta, nazwa pliku, numer portu,
nazwa odwo łania (w danym p liku).
Tworząc obiekt klasy URL otrzy mujemy gotowy wskaźn ik, który jest wykorzystywany przez liczne metody
Javy (np. otwieran ie obrazka getImage(), tworzenie połączen ia w JDBC - Connection).
Konstruktor y klasy URL
W odróżnieniu od klasy InetAddress tworzenie obie któw klasy URL odbywa się poprze z wy korzystanie jednego
z jej licznych konstruktorów.
Każdy z n ich związany jest z koniecznością obsługi wyjątku MalformedURLException powstającym w
przypadku problemów
z identyfikac ją wska zanego w wy wołaniu konstruktora protokołu.
Przykładowe konstruktory:
URL(String adres),
URL(String protokół, String host, int port, String plik)
Klasa URL zawiera szereg metod u możliwiających filtrację adresu,
a więc pobranie nazwy protokołu - getProtocol(), nazwy ko mputera - getHost(), p liku - getFile() czy nu meru
portu - getPort().
Dodatkowo klasa URL zawiera metody u możliwiające wy konywanie połączenia z hostem – tworzenie gniazda i
przesłanie danych.
Program u mo żliwia pobranie kodu źródło wego wskazanej strony WWW
i wyświetlen ie go na ekran ie.
import
java
.net.*;
import
java
.io.*;
public
class
Pobierz {
public
static
void
main(String args[]) {
URL url;
String tekst;
try
{
url =
new
URL(
"http://www.fuw.edu.pl/"
);
InputStreamReader in =
new
InputStrea mReader(url.openStrea m());
Buffe redReader br =
new
Buffered Reader(in);
while
( (tekst=br.read Line()) !=
null
) {
System.out.println(tekst);
}
}
catch
(Exception e) {e.p rintStackTrace(); }
}
}