1 / 42

Mre žno računarstvo

Mre žno računarstvo. Soketi za klijente (iz 9. poglavlja). Soketi za klijente. podaci se šalju preko Interneta u paketima ograničene veličine, koji se nazivaju datagram-ima datagram ima header i payload

Télécharger la présentation

Mre žno računarstvo

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Mrežno računarstvo Soketi za klijente (iz 9. poglavlja)

  2. Soketi za klijente • podaci se šalju preko Interneta u paketima ograničene veličine, koji se nazivaju datagram-ima • datagram ima header i payload • header – adresa i port kuda paket ide, adresa i port odakle dolazi itd. ostali podaci neophodni za pouzdani prenos • payload – sami podaci

  3. Soketi za klijente • podela podataka u pakete • njihovo spajanje na odredištu • izgubljeni i oštećeni paketi koje treba ponovo poslati • paketi ne stižu dobrim redosledom, pa ih treba preurediti • dakle, podela u paketa, generisanje zaglavlja, parsiranje zaglavlja dolazećih paketa, praćenje koji paketi jesu, a koji nisu pristigli – tu ima dosta posla

  4. Soketi za klijente • Srećom, mi o tome ne moramo da brinemo. • Soketi omogućavaju programeru da tretira mrežnu konekciju kao još jedan stream u koji može pisati bajtove, odnosno iz kojih može čitati bajtove • Soketi štite programera od detalja nižeg nivoa, poput otkrivanja grešaka, veličina paketa, retransmisije paketa, itd.

  5. Osnove soketa • Soket predstavlja konekciju između dva hosta • On može vršiti 7 osnovnih operacija: • povezivanje na udaljenu mašinu (connect) • slanje podataka (send) • primanje podataka (receive) • zatvaranje konekcije (close) • povezivanje na port (bind to port) • osluškivanje dolazećih podataka (listen) • prihvatanje konekcija sa udaljenih mašina na povezanom portu

  6. Socket klasa (i ServerSocket) • klasa Socket, koju koriste i klijenti i serveri, ima metode koji odgovaraju prvim 4 od prethodnih 7 operacija • Poslednje 3 operacije neophodne su samo serverima, koji čekaju da ih klijenti kontaktiraju. Ove operacije implementirane su klasom ServerSocket

  7. uobičajeno korišćenje soketa za klijente • Java programi obično koriste klijentske sokete na sledeći način • program konstruktorom kreira novi soket • soket pokušava da se konektuje na udaljeni host • nakon što je konekcija uspostavljena, lokalni i udaljeni host uzimaju input i output stream-ove od soketa i koriste te stream-ove da šalju podatke jedan drugome. Konekcija je full-duplex, što znači da oba hosta mogu da primaju i šalju podatke istovremeno. Šta su podaci, zavisi od protokola; različite komande se šalju FTP serveru nego HTTP serveru • kada je prenos podataka završen, jedna ili obe strane zatvaraju konekciju. Neki protokoli, poput HTTP 1.0 zahtevaju da se konekcija zatvori nakon obrade svakog zahteva. Drugi, poput FTP dopuštaju obradu većeg broja zahteva jednom konekcijom

  8. klasa Socket • java.net.Socket • osnovna klasa za izvršavanje client-side TCP operacija • ostale klijentski orijentisane klase koje prave TCP mrežne konekcije (URL, URLConnection, Applet, JEditorPane) pozivaju metode ove klase • interfejs koji klasa obezbeđuje programeru su stream-ovi. Stvarno čitanje i pisanje podataka preko soketa vrši se poznatim stream klasama

  9. konstruktori • jednostavni • svaki dopušta da se zada host i port na koji želimo da se konektujemo • host se može zadati kao InetAddress ili String • portovi se uvek zadaju kao int vrednosti od 0 do 65535 • 2 konstruktora takođe zadaju lokalnu adresu i lokalni port sa kojih se šalju podaci (to je možda potrebno kada se želi izabrati jedan određeni mrežni interfejs sa kog se šalju podaci, ako ih je više) • postoje i 2 konstruktora koja kreiraju nekonektovane sokete. Oni su korisni kada se žele postaviti opcije soketa pre pravljenja prve konekcije

  10. public Socket(String host, int port) throws UnknownHostException, IOException • kreira TCP soket ka zadatom portu i zadatom hostu i pokušava da se konektuje na udaljeni host try{ Socket toOReilly = new Socket(”www.oreilly.com”, 80); // send and receive data … }catch(UnkownHostException ex){ System.err.println(ex); }catch(IOException ex){ System.err.println(ex); }

  11. host je hostname (String). Ako domain name server ne može da razreši hostname ili ne funkcioniše, izbacuje se UnkownHostException • ako soket ne može biti otvoren iz drugih razloga, izbacuje se IOException. Mnogi su razlozi: taj host možda ne prihvata konekcije, dialup konekcija je možda pukla, ili problemi rutiranja sprečavaju pakete da stignu do odredišta • ovaj konstruktor ne samo da kreira soket, već takođe pokušava da konektuje soket na udaljeni host, pa se ovaj objekat može koristiti za utvrđivanje da li su dopuštene konekcije na određeni port • primer 1 (LowPortScanner)

  12. Primer - objašnjenja • na Unix sistemima, koji servisi su na kojim portovima može se videti u fajlu /etc/services • program na Unix sistemima treba da nađe tačno portove iz tog fajla • ne koristite LowPortScanner da probate na mašini koju ne posedujete, jer većina sistem administratora to smatra neprijateljskim činom

  13. public Socket(InetAddress host, int port) throws IOException • radi isto što i prethodni konstruktor (kreira TCP soket ka zadatom portu na zadatom hostu) i pokušava da se konektuje • razlikuje se po tome što koristi InetAddress objekat za zadavanje hosta (umesto hostname) • izbacuje IOException ako ne može da se konektuje, ne i UnknownHostException: ako je host nepoznat, saznaćemo kada kreiramo InetAddress objekat

  14. primer upotrebe: try{ InetAddress oreilly = InetAddress.getByName(”www.oreilly.com”); Socket oreillySocket = new Socket(oreilly, 80); // send and receive data … } catch(UnknownHostException ex){ System.err.println(ex); } catch(IOException ex){ System.err.println(ex); } • U retkim situacijama kada otvarate mnogo soketa na istom hostu, efikasnije je konvertovati hostname u InetAddress i zatim koristiti InetAddress za kreiranje soketa. • Primer 2 (HighPortScanner)

  15. ostali konstruktori • … page 8 of 65 • još 2 argumenta: lokalni mrežni interfejs i port • ako se za port izabere 0, Java bira slučajan dostupan port između 1024 i 65535 • ... page 10 of 65 • konstruktori koji kreiraju sokete koji ne pokušavaju da se konektuju

  16. Dobijanje informacija o soketu • public InetAddress getInetAddress() koji je udaljeni host na koji je soket konektovan, ili, ako je konekcija zatvorena, na koji je soket bio konektovan dok je bio konektovan • public int getPort() koji je port na udaljenom hostu na koji je soket bio, je ili će biti konektovan • public int getLocalPort() (postoje 2 kraja konekcije: remote i local host) Za razliku od remote porta koji je (za klijenta) obično dobro poznat, local port se obično bira od strane sistema u vreme izvršavanja od dostupnih neiskorišćenih portova. Na ovaj način, mnogi različiti klijenti mogu pristupati istom servisu u isto vreme. Local port je ugrađen u IP pakete zajedno sa IP adresom local host-a, tako da server može poslati podatke nazad na pravi port klijenta. • public InetAddress getLocalAddress() za koji mrežni interfejs je soket vezan. Ovo se obično koristi na hostu sa većim brojem mrežnih interfejsa • primer 3, SocketInfo

  17. public InputStream getInputStream() throws IOException • vraća ulazni tok koji može čitati podatke iz soketa u program • obično se olančava ovaj InputStream na filter tok ili čitač koji nudi veću funkcionalnost – DataInputStream ili InputStreamReader, npr. pre čitanja ulaza. • Zbog poboljšanja performansi, jako je dobra ideja baferisati ulaz olančavanjem na BufferedInputStream i/ili BufferedReader

  18. daytime protokol (RFC 867) • Sa ulaznim tokom, možemo čitati podatke iz soketa i početi eksperimentisanje sa nekim stvarnim Internet protokolima • jedan od najjednostavnijih je daytime • klijent otvara soket na portu 13 daytime servera • kao odgovor, server šalje vreme u čitljivom formatu i zatvara konekciju • ”Wed Nov 12 23:39:15 2003” linija koju je poslao server • primer 4, DaytimeClient

  19. primer 4, objašnjenja • DaytimeClient čita hostname daytime servera iz komandne linije i koristi ga za konstruisanje novog Soketa koji se konektuje na port 13 servera • ako se izostavi hostname, the National Institute of Standards and Technology server na time.nist.gov se koristi • klijent zatim poziva theSocket.getInputStream() da dobije ulazni tok od soketa, i smešta taj tok u promenljivu timeStream • pošto daytime protokol specifikuje ASCII, DaytimeClient ne olančava čitač na tok. On samo čita bajtove u StringBuffer, jedan po jedan, prekidajući kada server zatvori konekciju pošto protokol to od njega zahteva.

  20. primer 4, objašnjenja • vremenski serveri na različitim host-ovima koriste različite formate. • daytime protokol ne određuje format u kome se vraća vreme, osim da bude čitljiv • zato, teško je konvertovati karaktere koje vrati server u Java Date na pouzdan način. • Ako želimo da kreiramo Date objekat na osnovu vremena na serveru, lakše je koristiti time protokol iz RFC 868, jer on određuje format vremena

  21. Time protocol (RFC 868) • Kada se čitaju podaci sa mreže, bitno je imati na umu da ne koriste svi protokoli ASCII, čak ni tekst • npr, time protokol zadat u RFC 868 zadaje da se vreme šalje kao broj sekundi od ponoći 1. januara 1900 po Griniču (GMT) • Međutim, to se ne šalje kao ASCII string ”2,524,521,600” ili ”-1297728000”, već kao 32-bitni, neoznačeni, big-endian binarni broj

  22. RFC podrazumeva da znamo da svi mrežni protokoli koriste big endian brojeve • primer 5 (TimeClient) • Pošto ovo nije tekst, naš program ne može čitati odgovor servera pomoću Reader-a niti bilo koje vrste readLine() metoda. • Java program koji se konektuje na time servere mora čitati neobrađene bajtove i interpretirati ih na odgovarajući način • U ovom primeru, taj posao komplikuje nedostatak 32-bitnog neoznačenog celobrojnog tipa u Javi. • Zato, bajtovi se moraju čitati jedan po jedan i ručno konvertovati u long korišćenjem bitskih operatora << i |. • Kada se radi o drugim protokolima, oni mogu baratati formatima podataka koji su još čudniji za Javu, npr. nekoliko mrežnih protokola koristi 64-bitne brojeve u fiksnom zarezu. Tu nema prečice koja će rukovati svim mogućim slučajevima. Prosto, mora se iskodirati sva matematika neophodna za rukovanje podacima u onom formatu koji server pošalje.

  23. primer 5 objašnjenja • program čita hostname servera i opcioni port iz komandne linije i koristi ih za konstruisanje novog Socket objekta koji se konektuje na taj server • Ako korisnik izostavi hostname, koristi se time.nist.gov • podrazumevani port je 37 • klijent zatim poziva theSocket.getInputStream() da dobije ulazni tok, koji smešta u prom. raw

  24. primer 5, objašnjenja • 4 bajta se čitaju iz ovog toka i koriste za konstruisanje long-a koji predstavlja vrednost ta 4 bajta interpretiranu kao 32-bitni neoznačeni ceo broj • ovo daje broj sekundi proteklih od 12:00 A.M. January 1, 1900 GMT (time protocol epoch) • 2,208,988,800 sekundi se oduzima od tog broja da bi se dobio broj sekundi proteklih od 12:00 A.M. January 1, 1970 GMT (Java Date class epoch) • ovaj broj se množi sa 1000 da bi se konvertovao u milisekunde • konačno, taj broj milisekundi konvertuje se u Date objekat koji se štampa kako bi prikazao tekuće vreme i datum

  25. public OutputStream getOutputStream() throws IOException • vraća neobrađeni OutputStream za pisanje podataka iz naše aplikacije drugom kraju soketa • obično olančavamo ovaj tok klasama DataOutputStream ili OutputStreamWriter pre njegovog korišćenja • Za poboljšanje performansi, dobra ideja je baferisati ga, takođe.

  26. Writer out; try{ Socket http = new Socket(”www.oreilly.com”,80); OutputStream raw = http.getOutputStream(); OutputStream buffered = new BufferedOutputStream(raw); out = new OutputStreamWriter(buffered, ”ASCII”); out.write(”GET / HTTP 1.0\r\n\r\n”); // read the server response … } catch(Exception ex){ System.err.println(ex); } finally{ try{ out.close(); } catch(Exception ex){} }

  27. primer 6, echo protocol • echo protokol, definisan u RFC 862, jedan je od najjednostavnijih interaktivnih TCP servisa • klijent otvara soket na portu 7 echo servera i šalje podatke • server šalje podatke nazad • ovo se nastavlja dok klijent ne zatvori konekciju • echo protokol je koristan za testiranje mreže, kako bismo bili sigurni da podaci nisu izopačeni  pogrešnim ponašanjem rutera ili firewall-a.

  28. primer 6, objašnjenja • primer koristi getOutputStream() i getInputStream() da implementira jednostavni echo klijent. • korisnik kuca ulaz u komandnoj liniji, koji se zatim šalje serveru • server ga vraća nazad • program se završava kada korisnik ukuca tačku u posebnoj liniji • echo protokol ne određuje kodiranje karaktera. Zapravo, on zadaje da su podaci poslati serveru tačno oni koje server vraća. Server vraća neobrađene bajtove, ne karaktere koje oni predstavljaju. Tako, ovaj program koristi podrazumevano karaktersko kodiranje i line separator klijentskog sistema za čitanje iz System.in, slanje podataka udaljenom sistemu i ispis izlaza na System.out. • Kako echo server vraća upravo ono što je poslato, to je kao da se server dinamički podešava prema klijentskim konvencijama za karaktersko kodiranje i prelom linija. • Zato, koriste se uobičajene klase i metodi poput PrintWriter i readLine() koje bi u opštem slučaju bile previše nepouzdane

  29. primer 6, objašnjenja • novi Socket objekat, theSocket, kreira se na portu 7 • InputStream soketa vraća se metodom getInputStream() i olančava na InputStreamReader, a ovaj na BufferedReader nazvan networkIn koji čita odgovore servera • Pošto ovaj klijent takođe treba da čita ulaz korisnika, on kreira drugi BufferedReader, koji se zove userIn i čita iz System.in • Dalje, EchoClient poziva theSocket.getOutputStream() da dobije izlazni tok soketa theSocket, koji se koristi za konstruisanje novog PrintWriter objekta out. • Podaci se čitaju iz userIn i pišu na out. • Nakon što se podaci pošalju echo serveru, networkIn čeka odgovor. • Kada odgovor stigne, on se štampa na System.out. • Teoretski, klijent bi mogao da čeka na odovor koji nikada ne stiže. Međutim, to nije verovatno ako se može napraviti konekcija, pošto TCP protokol proverava loše pakete i automatski traži od servera zamene. Za implementiranje UDP echo klijenta (glava 13) potreban je drugačiji pristup jer UDP ne vrši kontrolu grešaka.

  30. primer 6, objašnjenja • primer je linijski-orijentisan • on čita liniju iz konzole, šalje je serveru, i čeka da pročita liniju koju mu ovaj vrati • međutim, echo protokol to ne zahteva • on vraća svaki bajt pošto ga primi • nije mu stalo da ti bajtovi predstavljaju karaktere u istom kodiranju ili da budu podeljeni u linije • Java ne dopušta da se konzola prebaci u ”neobrađeni” mod, gde se svaki karakter čita čim se ukuca umesto čekanja da korisnik pritisne Enter. • Za razliku od mnogih protokola, echo ne zahteva da klijent pošalje zahtev, a onda čeka na pun odgovor servera pre nego što pošalje još podataka. Najjednostavniji način za rukovanje takvim protokolom u Javi je smestiti mrežni ulaz i izlaz u odvojene niti.

  31. Zatvaranje soketa • ovo je skoro sve što je potrebno znati o soketima • kada se piše klijentska aplikacija, skoro sav posao je rukovanje tokovima i interpretiranje podataka • sa samim soketima se radi jednostavno (svi teški delovi skriveni su od programera)

  32. public void close() throws IOException • primeri do sada podrazumevali su da se soketi sami zatvaraju i nisu radili ništa da počiste za sobom • tačno je da se soket automatski zatvara kada se zatvori jedan od njegova dva stream-a, kada se završi program, ili kada ga počisti garbage collector. • Međutim, loša je praksa pretpostavljati da će sistem zatvarati naše sokete, posebno za programe koji se mogu izvršavati neograničeno dugo • u programima koji intenzivno koriste sokete, poput web browser-a, sistem može dostići max broj otvorenih soketa pre nego što ih pokupi garbage collector. • primeri 1 i 2 su naročito loši u tom pogledu, pošto može proteći puno vremena dok program prođe sve portove

  33. kada završite sa soketom, treba pozvati njigov close() metod za diskonektovanje • idealno, on se stavlja u finally blok tako da se soket zatvara bez obzira da li je izbačen izuzetak ili ne • sintaksa je pravolinijska

  34. Socket connection = null; try{ connection = new Socket(”www.oreilly.com” , 13); // interact with the socket… } // end try catch(UnknownHostException ex){ System.err.println(ex); } catch(IOException ex){ System.err.println(ex); } finally{ if(connection != null) connection.close(); }

  35. nakon što je soket zatvoren, njegov InetAddress, broj porta, lokalna adresa i lokalni broj porta su još uvek dostupni preko odgovarajućih get*() metoda • međutim, iako je moguće zvati getInputStream() ili getOutputStream(), pokušaj čitanja ili pisanja podataka dovodi do izbacivanja IOException • primer 7, revizija PortScanner programa koja zatvara svaki soket kada završi sa njim. Ne zatvara sokete koji nisu uspeli da se konektuju. Pošto oni nisu nikada otvoreni, ne moraju se zatvoriti. Zapravo, kada konstruktor ne uspe, connection ima vrednost null.

  36. public boolean isClosed() • vraća true ako je soket zatvoren, false inače • ako niste sigurni kakvo je stanje soketa, možete proveriti ovim metodom, radije nego da reskirate IOException • if(socket.isClosed()) // do something ... else // do something else • međutim, ovo nije savršen test. ako soket nikada nije bio konektovan, isClosed() vraća false, čak i kada soket nije otvoren

  37. public boolean isConnected() • ime može da zavara • ovaj metod ne kaže da li je soket trenutno konektovan na udaljeni host, već da li je soket ikada bio konektovan na udaljeni host. • ako je soket bio u mogućnosti da se konektuje na udaljeni host ikada, metod vraća true, čak i ako je soket zatvoren • za proveru da li je soket trenutno otvoren, mora se proveriti da isConnected() vraća true i isClosed() vraća false. • boolean connected = socket.isConnected() && !socket.isClosed();

  38. public boolean isBound() • odnosi se na lokalni kraj soketa • metod kaže da li je soket uspešno povezan na izlazni port lokalnog sistema. To u praksi nije vrlo važno. Postaće važnije kod serverskih soketa

  39. poluzatvoreni soketi • close() metod zatvara oba input i output soketa • povremeno, želimo da zatvorimo samo pola konekcije, bilo izlaz bilo ulaz • public void shutdownInput() throws IOException • public void shutdownOutput() throws IOException • Ovo ne zatvara soket. Ali podešava tok povezan na njega da misli da je kraj toka. Dalje čitanje iz ulaznog toka vraća -1. Dalje pisanje u izlazni tok izbacuje IOException. • Mnogi protokoli, poput finger, whois, HTTP počinju tako što klijent šalje zahtev serveru, a zatim čita odgovor. Moguće je zatvoriti izlaz nakon što klijent pošalje zahtev.

  40. primer • Sledeći fragment koda šalje zahtev HTTP serveru i onda zatvara izlaz, pošto neće više ništa pisati serveru preko tog soketa Socket connection = null; try{ connection = new Socket(”www.oreilly.com”, 80); Writer out = new OutputStreamWriter(connection.getOutputStream, ”8859_1”); out.write(”GET / HTTP 1.0\r\n\r\n”); out.flush(); connection.shutdownOutput(); // read the response … } catch(IOException ex){} finally{ try{ if(connection!=null) connection.close(); } catch(IOException ex){} }

  41. primetite da iako zatvorite pola, ili obe polovine konekcije, još uvek treba da zatvorite soket kada završite sa njim. • shutdown metodi prosto utiču na tokove soketa. Oni ne oslobađaju resurse pridružene soketu poput porta koji on zauzima • public boolean isInputShutdown() • public boolean isOutputShutdown() • ovi metodi se mogu koristiti (radije nego isConnected() i isClosed()) za određeniju proveru da li se može pisati ili čitati iz soketa

  42. page 30 of 65 • 9.3.4 Setting Socket Options page 39 of 65 • 9.6 Examples

More Related