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

Mre žno računarstvo

Embed Size (px)

DESCRIPTION

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 - PowerPoint PPT Presentation

Citation preview

MreMrežno računarstvožno računarstvo

Soketi za klijenteSoketi za klijente

(iz 9. poglavlja)(iz 9. poglavlja)

Soketi za klijenteSoketi za klijente

podaci se šalju preko Interneta u paketima podaci se šalju preko Interneta u paketima ograničene veličine, koji se nazivaju ograničene veličine, koji se nazivaju datagram-imadatagram-ima

datagram ima header i payloaddatagram ima header i payload

header – adresa i port kuda paket ide, header – adresa i port kuda paket ide, adresa i port odakle dolazi itd. ostali adresa i port odakle dolazi itd. ostali podaci neophodni za pouzdani prenospodaci neophodni za pouzdani prenos

payload – sami podacipayload – sami podaci

Soketi za klijenteSoketi za klijente

podela podataka u paketepodela podataka u paketenjihovo spajanje na odredištunjihovo spajanje na odredištuizgubljeni i oštećeni paketi koje treba ponovo izgubljeni i oštećeni paketi koje treba ponovo poslatiposlatipaketi ne stižu dobrim redosledom, pa ih treba paketi ne stižu dobrim redosledom, pa ih treba preureditipreureditidakle, podela u paketa, generisanje zaglavlja, dakle, podela u paketa, generisanje zaglavlja, parsiranje zaglavlja dolazećih paketa, praćenje parsiranje zaglavlja dolazećih paketa, praćenje koji paketi jesu, a koji nisu pristigli – tu ima dosta koji paketi jesu, a koji nisu pristigli – tu ima dosta poslaposla

Soketi za klijenteSoketi za klijente

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

Osnove soketaOsnove soketa

Soket predstavlja konekciju između dva hostaSoket predstavlja konekciju između dva hosta

On može vršiti 7 osnovnih operacija:On može vršiti 7 osnovnih operacija:– povezivanje na udaljenu mašinu (connect)povezivanje na udaljenu mašinu (connect)– slanje podataka (send)slanje podataka (send)– primanje podataka (receive)primanje podataka (receive)– zatvaranje konekcije (close)zatvaranje konekcije (close)– povezivanje na port (bind to port)povezivanje na port (bind to port)– osluškivanje dolazećih podataka (listen)osluškivanje dolazećih podataka (listen)– prihvatanje konekcija sa udaljenih mašina na prihvatanje konekcija sa udaljenih mašina na

povezanom portupovezanom portu

Socket klasa (i ServerSocket)Socket klasa (i ServerSocket)

klasa Socket, koju koriste i klijenti i serveri, klasa Socket, koju koriste i klijenti i serveri, ima metode koji odgovaraju prvim 4 od ima metode koji odgovaraju prvim 4 od prethodnih 7 operacijaprethodnih 7 operacija

Poslednje 3 operacije neophodne su samo Poslednje 3 operacije neophodne su samo serverima, koji čekaju da ih klijenti serverima, koji čekaju da ih klijenti kontaktiraju. Ove operacije implementirane kontaktiraju. Ove operacije implementirane su klasom ServerSocketsu klasom ServerSocket

uobičajeno korišćenje soketa za uobičajeno korišćenje soketa za klijenteklijente

Java programi obično koriste klijentske sokete na sledeći Java programi obično koriste klijentske sokete na sledeći načinnačin– program konstruktorom kreira novi soketprogram konstruktorom kreira novi soket– soket pokušava da se konektuje na udaljeni hostsoket pokušava da se konektuje na udaljeni host– nakon što je konekcija uspostavljena, lokalni i udaljeni host nakon što je konekcija uspostavljena, lokalni i udaljeni host

uzimaju input i output stream-ove od soketa i koriste te stream-uzimaju input i output stream-ove od soketa i koriste te stream-ove da šalju podatke jedan drugome. Konekcija je full-duplex, ove da šalju podatke jedan drugome. Konekcija je full-duplex, što znači da oba hosta mogu da primaju i šalju podatke što znači da oba hosta mogu da primaju i šalju podatke istovremeno. Šta su podaci, zavisi od protokola; različite istovremeno. Šta su podaci, zavisi od protokola; različite komande se šalju FTP serveru nego HTTP serverukomande se šalju FTP serveru nego HTTP serveru

– kada je prenos podataka završen, jedna ili obe strane zatvaraju kada je prenos podataka završen, jedna ili obe strane zatvaraju konekciju. Neki protokoli, poput HTTP 1.0 zahtevaju da se konekciju. Neki protokoli, poput HTTP 1.0 zahtevaju da se konekcija zatvori nakon obrade svakog zahteva. Drugi, poput konekcija zatvori nakon obrade svakog zahteva. Drugi, poput FTP dopuštaju obradu većeg broja zahteva jednom konekcijomFTP dopuštaju obradu većeg broja zahteva jednom konekcijom

klasa Socketklasa Socket

java.net.Socketjava.net.Socket

osnovna klasa za izvršavanje client-side TCP osnovna klasa za izvršavanje client-side TCP operacijaoperacija

ostale klijentski orijentisane klase koje prave ostale klijentski orijentisane klase koje prave TCP mrežne konekcije (URL, URLConnection, TCP mrežne konekcije (URL, URLConnection, Applet, JEditorPane) pozivaju metode ove klaseApplet, JEditorPane) pozivaju metode ove klase

interfejs koji klasa obezbeđuje programeru su interfejs koji klasa obezbeđuje programeru su stream-ovi. Stvarno čitanje i pisanje podataka stream-ovi. Stvarno čitanje i pisanje podataka preko soketa vrši se poznatim stream klasamapreko soketa vrši se poznatim stream klasama

konstruktorikonstruktori

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

public Socket(String host, int port) throws public Socket(String host, int port) throws UnknownHostException, IOExceptionUnknownHostException, IOException

kreira TCP soket ka zadatom portu i zadatom hostu i kreira TCP soket ka zadatom portu i zadatom hostu i pokušava da se konektuje na udaljeni hostpokušava da se konektuje na udaljeni host

trytry{{ Socket toOReilly = new Socket(”Socket toOReilly = new Socket(”www.oreilly.com”, 80);”, 80); // send and receive data …// send and receive data … }catch(UnkownHostException ex){}catch(UnkownHostException ex){ System.err.println(ex);System.err.println(ex); }catch(IOException ex){}catch(IOException ex){ System.err.println(ex);System.err.println(ex); }}

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

Primer - objašnjenjaPrimer - objašnjenja

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

public Socket(InetAddress host, int public Socket(InetAddress host, int port) throws IOExceptionport) throws IOException

radi isto što i prethodni konstruktor (kreira TCP radi isto što i prethodni konstruktor (kreira TCP soket ka zadatom portu na zadatom hostu) i soket ka zadatom portu na zadatom hostu) i pokušava da se konektujepokušava da se konektuje

razlikuje se po tome što koristi InetAddress razlikuje se po tome što koristi InetAddress objekat za zadavanje hosta (umesto hostname)objekat za zadavanje hosta (umesto hostname)

izbacuje IOException ako ne može da se izbacuje IOException ako ne može da se konektuje, ne i UnknownHostException: ako je konektuje, ne i UnknownHostException: ako je host nepoznat, saznaćemo kada kreiramo host nepoznat, saznaćemo kada kreiramo InetAddress objekatInetAddress objekat

primer upotrebe:primer upotrebe: trytry{{ InetAddress oreilly = InetAddress.getByName(”InetAddress oreilly = InetAddress.getByName(”www.oreilly.com”);”); Socket oreillySocket = new Socket(oreilly, 80);Socket oreillySocket = new Socket(oreilly, 80); // send and receive data …// send and receive data … } catch(UnknownHostException ex){} catch(UnknownHostException ex){ System.err.println(ex);System.err.println(ex); } catch(IOException ex){} catch(IOException ex){ System.err.println(ex);System.err.println(ex); }}

U retkim situacijama kada otvarate mnogo soketa na istom hostu, U retkim situacijama kada otvarate mnogo soketa na istom hostu, efikasnije je konvertovati hostname u InetAddress i zatim koristiti efikasnije je konvertovati hostname u InetAddress i zatim koristiti InetAddress za kreiranje soketa.InetAddress za kreiranje soketa.Primer 2 (HighPortScanner)Primer 2 (HighPortScanner)

ostali konstruktoriostali konstruktori

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

Dobijanje informacija o soketuDobijanje informacija o soketupublic InetAddress getInetAddress() public InetAddress getInetAddress()

koji je udaljeni host na koji je soket konektovan, ili, ako je konekcija koji je udaljeni host na koji je soket konektovan, ili, ako je konekcija zatvorena, na koji je soket bio konektovan dok je bio konektovanzatvorena, na koji je soket bio konektovan dok je bio konektovanpublic int getPort()public int getPort()

koji je port na udaljenom hostu na koji je soket bio, je ili će biti konektovankoji je port na udaljenom hostu na koji je soket bio, je ili će biti konektovanpublic int getLocalPort()public int getLocalPort()

(postoje 2 kraja konekcije: remote i local host)(postoje 2 kraja konekcije: remote i local host) Za razliku od remote porta koji je (za klijenta) obično dobro poznat, local port 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 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 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 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 adresom local host-a, tako da server može poslati podatke nazad na pravi port klijenta.port klijenta.public InetAddress getLocalAddress()public InetAddress getLocalAddress()

za koji mrežni interfejs je soket vezan. Ovo se obično koristi na hostu sa za koji mrežni interfejs je soket vezan. Ovo se obično koristi na hostu sa većim brojem mrežnih interfejsavećim brojem mrežnih interfejsaprimer 3, SocketInfoprimer 3, SocketInfo

public InputStream getInputStream() public InputStream getInputStream() throws IOExceptionthrows IOException

vraća ulazni tok koji može čitati podatke iz vraća ulazni tok koji može čitati podatke iz soketa u programsoketa u program

obično se olančava ovaj InputStream na filter tok obično se olančava ovaj InputStream na filter tok ili čitač koji nudi veću funkcionalnost – ili čitač koji nudi veću funkcionalnost – DataInputStream ili InputStreamReader, npr. pre DataInputStream ili InputStreamReader, npr. pre čitanja ulaza.čitanja ulaza.

Zbog poboljšanja performansi, jako je dobra Zbog poboljšanja performansi, jako je dobra ideja baferisati ulaz olančavanjem na ideja baferisati ulaz olančavanjem na BufferedInputStream i/ili BufferedReaderBufferedInputStream i/ili BufferedReader

daytime protokol (RFC 867)daytime protokol (RFC 867)

Sa ulaznim tokom, možemo čitati podatke iz Sa ulaznim tokom, možemo čitati podatke iz soketa i početi eksperimentisanje sa nekim soketa i početi eksperimentisanje sa nekim stvarnim Internet protokolimastvarnim Internet protokolimajedan od najjednostavnijih je daytimejedan od najjednostavnijih je daytimeklijent otvara soket na portu 13 daytime serveraklijent otvara soket na portu 13 daytime serverakao odgovor, server šalje vreme u čitljivom kao odgovor, server šalje vreme u čitljivom formatu i zatvara konekcijuformatu i zatvara konekciju””Wed Nov 12 23:39:15 2003” linija koju je poslao Wed Nov 12 23:39:15 2003” linija koju je poslao serverserverprimer 4, DaytimeClientprimer 4, DaytimeClient

primer 4, objašnjenjaprimer 4, objašnjenja

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

primer 4, objašnjenjaprimer 4, objašnjenja

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

Time protocol (RFC 868)Time protocol (RFC 868)

Kada se čitaju podaci sa mreže, bitno je imati na Kada se čitaju podaci sa mreže, bitno je imati na umu da ne koriste svi protokoli ASCII, čak ni umu da ne koriste svi protokoli ASCII, čak ni teksttekst

npr, time protokol zadat u RFC 868 zadaje da se npr, time protokol zadat u RFC 868 zadaje da se vreme šalje kao broj sekundi od ponoći 1. vreme šalje kao broj sekundi od ponoći 1. januara 1900 po Griniču (GMT)januara 1900 po Griniču (GMT)

Međutim, to se ne šalje kao ASCII string Međutim, to se ne šalje kao ASCII string ”2,524,521,600” ili ”-1297728000”, već kao 32-”2,524,521,600” ili ”-1297728000”, već kao 32-bitni, neoznačeni, big-endian binarni brojbitni, neoznačeni, big-endian binarni broj

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

primer 5 objašnjenjaprimer 5 objašnjenja

program čita hostname servera i opcioni port iz program čita hostname servera i opcioni port iz komandne linije i koristi ih za konstruisanje komandne linije i koristi ih za konstruisanje novog Socket objekta koji se konektuje na taj novog Socket objekta koji se konektuje na taj serverserver

Ako korisnik izostavi hostname, koristi se Ako korisnik izostavi hostname, koristi se time.nist.govtime.nist.gov

podrazumevani port je 37podrazumevani port je 37

klijent zatim poziva theSocket.getInputStream() klijent zatim poziva theSocket.getInputStream() da dobije ulazni tok, koji smešta u prom. rawda dobije ulazni tok, koji smešta u prom. raw

primer 5, objašnjenjaprimer 5, objašnjenja

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

public OutputStream getOutputStream() public OutputStream getOutputStream() throws IOExceptionthrows IOException

vraća neobrađeni OutputStream za vraća neobrađeni OutputStream za pisanje podataka iz naše aplikacije pisanje podataka iz naše aplikacije drugom kraju soketadrugom kraju soketa

obično olančavamo ovaj tok klasama obično olančavamo ovaj tok klasama DataOutputStream ili OutputStreamWriter DataOutputStream ili OutputStreamWriter pre njegovog korišćenjapre njegovog korišćenja

Za poboljšanje performansi, dobra ideja je Za poboljšanje performansi, dobra ideja je baferisati ga, takođe.baferisati ga, takođe.

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

primer 6, echo protocolprimer 6, echo protocol

echo protokol, definisan u RFC 862, jedan je od echo protokol, definisan u RFC 862, jedan je od najjednostavnijih interaktivnih TCP servisanajjednostavnijih interaktivnih TCP servisa

klijent otvara soket na portu 7 echo servera i klijent otvara soket na portu 7 echo servera i šalje podatkešalje podatke

server šalje podatke nazadserver šalje podatke nazad

ovo se nastavlja dok klijent ne zatvori konekcijuovo se nastavlja dok klijent ne zatvori konekciju

echo protokol je koristan za testiranje mreže, echo protokol je koristan za testiranje mreže, kako bismo bili sigurni da podaci nisu izopačeni kako bismo bili sigurni da podaci nisu izopačeni pogrešnim ponašanjem rutera ili firewall-a. pogrešnim ponašanjem rutera ili firewall-a.

primer 6, objašnjenjaprimer 6, objašnjenja

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

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

primer 6, objašnjenjaprimer 6, objašnjenja

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

Zatvaranje soketaZatvaranje soketa

ovo je skoro sve što je potrebno znati o ovo je skoro sve što je potrebno znati o soketimasoketima

kada se piše klijentska aplikacija, skoro kada se piše klijentska aplikacija, skoro sav posao je rukovanje tokovima i sav posao je rukovanje tokovima i interpretiranje podatakainterpretiranje podataka

sa samim soketima se radi jednostavno sa samim soketima se radi jednostavno (svi teški delovi skriveni su od programera)(svi teški delovi skriveni su od programera)

public void close() throws public void close() throws IOExceptionIOException

primeri do sada podrazumevali su da se soketi sami primeri do sada podrazumevali su da se soketi sami zatvaraju i nisu radili ništa da počiste za sobomzatvaraju i nisu radili ništa da počiste za sobomtačno je da se soket automatski zatvara kada se zatvori tačno je da se soket automatski zatvara kada se zatvori jedan od njegova dva stream-a, kada se završi program, jedan od njegova dva stream-a, kada se završi program, ili kada ga počisti garbage collector.ili kada ga počisti garbage collector.Međutim, loša je praksa pretpostavljati da će sistem Međutim, loša je praksa pretpostavljati da će sistem zatvarati naše sokete, posebno za programe koji se zatvarati naše sokete, posebno za programe koji se mogu izvršavati neograničeno dugomogu izvršavati neograničeno dugou programima koji intenzivno koriste sokete, poput web u programima koji intenzivno koriste sokete, poput web browser-a, sistem može dostići max broj otvorenih browser-a, sistem može dostići max broj otvorenih soketa pre nego što ih pokupi garbage collector.soketa pre nego što ih pokupi garbage collector.primeri 1 i 2 su naročito loši u tom pogledu, pošto može 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 portoveproteći puno vremena dok program prođe sve portove

kada završite sa soketom, treba pozvati kada završite sa soketom, treba pozvati njigov close() metod za diskonektovanjenjigov close() metod za diskonektovanje

idealno, on se stavlja u finally blok tako da idealno, on se stavlja u finally blok tako da se soket zatvara bez obzira da li je se soket zatvara bez obzira da li je izbačen izuzetak ili neizbačen izuzetak ili ne

sintaksa je pravolinijskasintaksa je pravolinijska

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

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

public boolean isClosed()public boolean isClosed()

vraća true ako je soket zatvoren, false inačevraća true ako je soket zatvoren, false inačeako niste sigurni kakvo je stanje soketa, možete ako niste sigurni kakvo je stanje soketa, možete proveriti ovim metodom, radije nego da reskirate proveriti ovim metodom, radije nego da reskirate IOExceptionIOExceptionif(socket.isClosed())if(socket.isClosed())

// do something ...// do something ... elseelse // do something else// do something else

međutim, ovo nije savršen test. ako soket nikada međutim, ovo nije savršen test. ako soket nikada nije bio konektovan, isClosed() vraća false, čak i nije bio konektovan, isClosed() vraća false, čak i kada soket nije otvorenkada soket nije otvoren

public boolean isConnected()public boolean isConnected()

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

public boolean isBound()public boolean isBound()

odnosi se na lokalni kraj soketaodnosi se na lokalni kraj soketa

metod kaže da li je soket uspešno metod kaže da li je soket uspešno povezan na izlazni port lokalnog sistema. povezan na izlazni port lokalnog sistema. To u praksi nije vrlo važno. Postaće To u praksi nije vrlo važno. Postaće važnije kod serverskih soketavažnije kod serverskih soketa

poluzatvoreni soketipoluzatvoreni soketi

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

primerprimerSledeći fragment koda šalje zahtev HTTP serveru i onda zatvara izlaz, Sledeći fragment koda šalje zahtev HTTP serveru i onda zatvara izlaz, pošto neće više ništa pisati serveru preko tog soketapošto neće više ništa pisati serveru preko tog soketa

Socket connection = null;Socket connection = null;try{try{ connection = new Socket(”connection = new Socket(”www.oreilly.com”, 80);”, 80); Writer out = new OutputStreamWriter(connection.getOutputStream, Writer out = new OutputStreamWriter(connection.getOutputStream,

”8859_1”);”8859_1”); out.write(”GET / HTTP 1.0\r\n\r\n”);out.write(”GET / HTTP 1.0\r\n\r\n”); out.flush();out.flush(); connection.shutdownOutput();connection.shutdownOutput(); // read the response …// read the response …}}catch(IOException ex){}catch(IOException ex){}finally{finally{ try{try{ if(connection!=null) connection.close();if(connection!=null) connection.close(); }} catch(IOException ex){}catch(IOException ex){}}}

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

page 30 of 65page 30 of 65

9.3.4 Setting Socket Options9.3.4 Setting Socket Options

page 39 of 65page 39 of 659.6 Examples9.6 Examples