Programy typu klient serwer. Programowanie w środowisku rozproszonym. Wykład 5.
Schemat Internetu R R R R R R R 2
Model Internetu 3
Protokoły komunikacyjne stosowane w sieci Internet Protokoły warstwy dostępu do sieci, Protokoły warstwy intersieci, Protokoły warstwy transmisji, Protokoły warstwy zastosowań (aplikacji). 4
Protokoły warstwy dostępu do sieci Protokoły warstwy dostępu do sieci - określają zasady przesyłania danych w obrębie jednej sieci lokalnej: protokoły sieci lokalnych (np. protokoły komunikacyjne sieci Ethernet, Token Ring, FDDI). 5
Protokoły warstwy intersieci Protokoły warstwy intersieci (odpowiedzialne za realizację funkcji warstwy intersieciowej): Protokół intersieciowy (protokół IP - Internet Protocol) - definiuje sposób adresowania komputerów przyłączonych do sieci Internet oraz odpowiada za wyznaczenie tras, po których przesyłane będą pakiety, Protokoły routingu - pozwalają na wymianę informacji pomiędzy routerami umoŝliwiającą im zebranie informacji niezbędnych do realizacji zadania doboru trasy, czyli rozwiązywania problemu routingu (RIP /Routing Information Protocol/, OSPF /Open Shortest Path First/, BGP /Border Gateway Protocol/), Protokół ICMP /Internet Control Message Protocol)/ protokół diagnostyczny słuŝący do informowania o problemach związanych z funkcjonowaniem sieci, Protokoły ARP /Address Resolution Protocol/ i RARP /Reverse Address Resolution Protocol/ protokoły odwzorowania adresów (dokonują translacji pomiędzy adresami stosowanymi w warstwie międzysieciowej i dostępu do sieci), Protokół dynamicznego konfigurowania węzłów protokół DHCP (Dynamic Host Configuration Protocol) pozwala na automatyczną konfigurację komputera przyłączonego do sieci Internet. 6
Protokoły warstwy transmisji Protokoły warstwy transmisji (odpowiedzialny za dostarczenie danych od nadawcy do odbiorcy): Protokół sterowania transmisją (protokół TCP - Transmission Control Protocol) - dokonuje podziału danych na segmenty i sprawdza poprawność ich transmisji; Protokół datagramów uŝytkownika protokół UDP (User Datagram Protocol) dokonuje podziału danych na datagramy i przesyła je bez weryfikacji poprawności transmisji. 7
Protokoły warstwy zastosowań Protokoły warstwy zastosowań (definiują usługi dostępne w sieci Internet): Protokół transferu hipertekstu (protokół HTTP - Hypertext Transfer Protocol) - pozwala na przesyłanie stron WWW; Protokół transferu plików (protokół FTP - File Transfer Protocol) - umoŝliwia kopiowanie plików pomiędzy komputerami przyłączonymi do sieci Internet; Protokół transferu poczty (protokół SMTP - Simple Mail Transfer Protocol) - określa zasady przesyłania listów poprzez Internet; Protokoły odbioru poczty (protokół POP - Post Office Protocol oraz IMAP Internet Message Access Protocol) - definiują sposób pobierania listów ze skrzynek pocztowych i zarządzania zawartością skrzynek; Protokół DNS (Domain Name System Protocol protokół obsługi systemu nazw domenowych) pozwala na konwersję nazwy domenowej komputera na identyfikujący go numer IP. 8
Identyfikacja komputera w sieci lasa java.net.inetaddress - reprezentuje adres IP komputera Tworzenie obiektu klasy InetAddress uwaga: klasa InetAddress nie posiada publicznych konstruktorów; tworzenie obiektów klasy InetAddress odbywa się za pomocą metod: public static InetAddress getbyname( String host) throws UnknownHostException; public static InetAddress[] getallbyname( String host) throws UnknownHostException; public static InetAddress getlocalhost() throws UnknownHostException; 9
Przykłady wywołań metod InetAddress adres = InetAddress.getByName( helion.com.pl ); InetAddress mojadres = InetAddress.getLocalHost(); 10
Przykładowy program import java.net.*; class MojAdres { public static void main (String [] args) { try { InetAddress adres = InetAddress.getByName("www.onet.pl"); System.out.println(adres); catch (UnknownHostException e) { System.out.println("Nie mogę znaleźć adresu komputera."); 11
Porty Port - identyfikator programu działającego w systemie komputerowym (numer portu jest liczbą szesnastobitową). Dobrze znane porty - identyfikatory przydzielone najpopularniejszym programom, np.: 23 - telnet 25 - SMTP 80 - HTTP 110 - POP3 20, 21 - FTP - dane (20), polecenia (21) 12
omunikacja omunikują się ze sobą programy, a nie komputery (w szczególnym przypadku komunikujące się programy mogą być uruchomione na tym samym komputerze). 13
omunikacja z poziomu programu połączenie widziane jest jako strumień: wysyłanie danych - zapis danych do strumienia, odbiór danych - pobieranie danych ze strumienia. gniazdo komunikacyjne (ang. Socket)- końcówka połączenia dostępna z poziomu programu. Strony uczestniczące w komunikacji: serwer - program oczekujący na połączenie ze strony klienta klient - program inicjujący połączenie. 14
omunikacja program A połączenie program B gniazdo gniazdo 15
Prosty klient import java.net.*; import java.io.*; public class Prostylient { public static void main(string [] args) { int bajt; BufferedReader klawiatura; String nowalinia = System.getProperty("line.separator"); 16
Prosty klient //utworzenie strumienia skojarzonego z klawiatura InputStreamReader klaw = new InputStreamReader(System.in); klawiatura = new BufferedReader(klaw); //nawiazanie polaczenia z serwerem try { Socket gniazdoomunikacyjne = new Socket("192.168.0.3",4444); // połączenie z programem działającym na komputerze o // podanym IP // i identyfikowanym przez numer portu // wyswietlenie informacji o numerach portow System.out.println("Server - port: " + gniazdoomunikacyjne.getport()); //numer zdalnego portu System.out.println("Server - localport: " + gniazdoomunikacyjne.getlocalport()); //numer lokalnego portu 17
Prosty klient //utworzenie strumienia tekstowego z danymi od serwera InputStream strumienodserwera = gniazdoomunikacyjne.getinputstream(); BufferedReader strumientekstowyodserwera = new BufferedReader(new InputStreamReader(strumienOdSerwera)); //utworzenie struienia tekstowego wysylajacego dane do serwera OutputStream strumiendoserwera = gniazdoomunikacyjne.getoutputstream(); BufferedWriter strumientekstowydoserwera = new BufferedWriter(new OutputStreamWriter(strumienDoSerwera)); //powitanie String powitanie = strumientekstowyodserwera.readline(); System.out.println(powitanie); 18
Prosty klient //wczytywanie danych z klawiatury i wysylanie do serwera while (true) { System.out.print("Tekst do wysłania: "); String s = klawiatura.readline(); strumientekstowydoserwera.write(s + nowalinia); strumientekstowydoserwera.flush(); //oczekiwanie na odpowiedz od serwera String odp = strumientekstowyodserwera.readline(); //wyswietlenie odpowiedzi System.out.println("SERWER: " + odp); if (s.tolowercase().startswith("koniec")) break; 19
Prosty klient strumientekstowydoserwera.close(); strumientekstowyodserwera.close(); klawiatura.close(); gniazdoomunikacyjne.close(); catch(unknownhostexception e1) { System.out.println("Nieznany host: " + e1.getmessage()); catch(ioexception e2) { System.out.println("Błąd operacji wejścia/wyjścia: " + e2.getmessage()); 20
Prosty serwer import java.net.*; import java.io.*; public class ProstySerwer { public static void main(string[] args) { String nowalinia = System.getProperty("line.separator"); //utworzenie gniazda nasłuchującego ServerSocket gniazdonasluchujace = null; try { gniazdonasluchujace = new ServerSocket(4444); catch (IOException e) { System.err.println("Serwer nie moze nasluchiwac na porcie: 4444."); System.exit(1); System.out.println("ServerSocket - localport: " + gniazdonasluchujace.getlocalport()); //numer lokalnego portu (4444) 21
Prosty serwer Socket gniazdoomunikacyjne = null; try { gniazdoomunikacyjne = gniazdonasluchujace.accept(); catch (IOException e) { System.err.println("Błąd połaczenia z klientem"); System.exit(1); System.out.println("Server - port: " + gniazdoomunikacyjne.getport()); //numer zdalnego portu System.out.println("Server - localport: " + gniazdoomunikacyjne.getlocalport()); //numer lokalnego portu 22
Prosty serwer try { //utworzenie strumienia tekstowego z danymi od klienta InputStream strumienodlienta = gniazdoomunikacyjne.getinputstream(); BufferedReader strumientekstowyodlienta = new BufferedReader(new InputStreamReader(strumienOdlienta)); //utworzenie strumienia tekstowego z danymi do klienta OutputStream strumiendolienta = gniazdoomunikacyjne.getoutputstream(); BufferedWriter strumientekstowydolienta = new BufferedWriter(new OutputStreamWriter(strumienDolienta)); strumientekstowydolienta.write("serwer wita klienta!" + nowalinia); strumientekstowydolienta.flush(); 23
Prosty serwer String pytanie, odpowiedz; while (true) { pytanie = strumientekstowyodlienta.readline(); if (pytanie.tolowercase().startswith("koniec")) { strumientekstowydolienta.write("oniec PRACY!!!" + nowalinia); break; odpowiedz = "ECHO: " + pytanie + nowalinia; strumientekstowydolienta.write(odpowiedz); strumientekstowydolienta.flush(); strumientekstowydolienta.close(); strumientekstowyodlienta.close(); gniazdoomunikacyjne.close(); gniazdonasluchujace.close(); catch(ioexception e) { System.out.println("Wyjątek wejscia/wyjscia"); 24
Serwer współbieŝny import java.net.*; import java.io.*; class ObslugaJednegolienta extends Thread { private Socket gniazdoomunikacyjne = null; String nowalinia = System.getProperty("line.separator"); ObslugaJednegolienta(Socket gniazdoomunikacyjne) { this.gniazdoomunikacyjne = gniazdoomunikacyjne; 25
Serwer współbieŝny public void run() { System.out.println("Przylaczenie nowego klienta"); System.out.println("Server - port: " + gniazdoomunikacyjne.getport()); //numer zdalnego portu System.out.println("Server - localport: " + gniazdoomunikacyjne.getlocalport()); //numer lokalnego portu try { //utworzenie strumienia tekstowego z danymi od klienta InputStream strumienodlienta = gniazdoomunikacyjne.getinputstream(); BufferedReader strumientekstowyodlienta = new BufferedReader( new InputStreamReader(strumienOdlienta)); 26
Serwer współbieŝny // utworzenie strumienia tekstowego // z danymi do klienta OutputStream strumiendolienta = gniazdoomunikacyjne.getoutputstream(); BufferedWriter strumientekstowydolienta = new BufferedWriter(new OutputStreamWriter(strumienDolienta)); strumientekstowydolienta.write("serwer wita klienta!" + nowalinia); strumientekstowydolienta.flush(); String pytanie, odpowiedz; 27
Serwer współbieŝny while (true) { pytanie = strumientekstowyodlienta.readline(); if (pytanie.tolowercase().startswith("koniec")) { strumientekstowydolienta.write ("ONIEC POLACZENIA Z LIENTEM" + nowalinia); break; 28
Serwer współbieŝny odpowiedz = "ECHO: " + pytanie + nowalinia; strumientekstowydolienta.write(odpowiedz); strumientekstowydolienta.flush(); strumientekstowydolienta.close(); strumientekstowyodlienta.close(); gniazdoomunikacyjne.close(); catch(ioexception e) { System.out.println("Wyjątek wejscia/wyjscia"); 29
Serwer współbieŝny public class SerwerWspolbiezny { public static void main(string[] args) throws IOException{ String nowalinia = System.getProperty("line.separator"); boolean serwerstop = false; //utworzenie gniazda nasłuchującego ServerSocket gniazdonasluchujace = null; try { gniazdonasluchujace = new ServerSocket(4444); catch (IOException e) { System.err.println("Serwer nie moze nasluchiwac na porcie: 4444."); System.exit(1); System.out.println("ServerSocket - localport: " + gniazdonasluchujace.getlocalport()); //numer lokalnego portu (4444) 30
Serwer współbieŝny while (!serwerstop) new ObslugaJednegolienta(gniazdoNasluchujace.accept()).start(); gniazdonasluchujace.close(); 31