Računalne mreže I usluge Peer-To-Peer aplikacije, socket programiranje s tcp I udp, I primjeri u Pythonu




Дата канвертавання25.04.2016
Памер90.67 Kb.


Sveučilište Josipa Jurja Strossmayera u Osijeku

Odjel za matematiku



Seminarski rad iz kolegija

Računalne mreže i usluge

Peer-To-Peer aplikacije, socket programiranje

s TCP i UDP, i primjeri u Pythonu

Studentice:

Ivana Matišić, 907

Ivana Šimić, 875

Marija Špringman, 876

Ivana Umiljanović, 881

Osijek, svibanj 2012.

Sadržaj


Sadržaj 3

1. Uvod 4

2. P2P mreže 5

2.1. Što su to P2P mreže? 5

2.2. Generacijski razvoj P2P mreža 5

2.3. Arhitektura P2P mreža 5

2.4. Prednosti i nedostaci P2P mreža 6

2.5. Primjena 7

3. Peer To Peer (P2P) aplikacije 8

3.1. Peer-to-peer aplikacije za dijeljenje podataka 9

3.2. Peer-to-peer aplikacije za IM & online chat 11

3.3. Peer-to-peer aplikacije za glasovnu i pisanu komunikaciju (VoIP) 13

3.4. Peer-to-peer aplikacije za multimediju 14

3.5. Peer-to-peer aplikacije za suradnju i grupe za diskusiju 14

4. Programiranje socketa s TCP i UDP 16

4.1. Socket programiranje s TCP-om 16

4.2. Socket programiranje s UDP-om 20

5. Primjeri 24

Literatura 27



1. Uvod


Posljednjih godina povećanjem dostupnosti brzog Interneta, među korisnicima raste zanimanje za dohvaćanje raznovrsnog multimedijalnog sadržaja. Kako dohvaćanje multimedijalnog sadržaja uglavnom troši velike količine poslužiteljskih sredstava, bilo je potrebno rasteretiti poslužitelje te što veći dio posla preusmjeriti na same klijente. Zadatak prva dva poglavlja seminara je predstaviti P2P (eng. Peer-to-Peer) mreže i različite modele razmjene datoteka koje se koriste u današnjim P2P aplikacijama. Proći ćemo i kroz neke poznatije P2P aplikacije.

Kako bi različita računala mogla stupiti u komunikaciju preko mreže potrebno je korisiti određena pravila koja bi vrijedila za sva računala u mreži – protokole. Budući da su socketi vrata između procesa i protokola, u poglavlju 3. ćemo, preko jednostavih implementacija klijenta i servera, prikazati kako programirati sockete za TCP i UDP. U poglavlju 4. možete pronaći gotove kodove kroz koje smo prošli u poglavlju 3.


2. P2P mreže

2.1. Što su to P2P mreže?


Peer-to-peer (P2P) je računalna mreža u kojoj nema servera i klijent-server modela. Svi su čvorovi (eng. peer) u P2P modelu hijerarhijski jednaki, istodobno su i klijenti i serveri te dijele podatke između sebe. Ne postoji netko tko će kontrolirati koji podaci se dijele u mreži, jer ne postoji server niti neko glavno računalo koje nadgleda sve ostale. P2P mreže imaju svojevrsne servere, ali oni ne sadrže datoteke za razmjenu već služe za spajanje ponude i potražnje dvaju P2P klijenta na mreži. Sama razmjena datoteka odvija se izravno između dva čvora („klijenta“).

2.2. Generacijski razvoj P2P mreža


Razlikujemo tri generacije P2P mreža. Prva generacija P2P mreža bila je potpuno centralizirana. Klijenti nisu međusobno komunicirali, već se prijenos datoteka odvijao preko servera. Primjer mreže prve generacije je Napster. Sve informacije potrebne za funkcioniranje i pretraživanje mreže nalazile su se na jednom serveru. Američki sudovi proglasili su osobe koje kontroliraju ovim informacijama odgovornima za moguće kršenje autorskih prava ili druge ilegalne radnje na ovim mrežama. Uslijed toga, dolazi do razvoja druge generacije P2P mreža.

Druga generacija P2P mreža je donijela potpunu decentralizaciju. Svi klijenti su postali međusobno ravnopravni i izravno pretraživali i dijelili datoteke, bez posredovanja servera. Primjer mreže druge generacije bila je prva verzija Gnutelle.

Treća generacija P2P mreža je uvela anonimnost i kriptiranje podataka. Primjer mreže treće generacije je BitTorrent.

2.3. Arhitektura P2P mreža


P2P mreže prema strukturi dijelimo na centralizirane i decentralizirane. U nastavku je dan pregled osnovnih svojstava svake od mreža te njihovi najpoznatiji predstavnici.

Počnimo s centraliziranim P2P mrežama. Njihova osnovna svojstva navedena su u potpoglavlju 2.2.. Primjer ovakve mreže je Napster. Također, osnovna svojstva decentraliziranih P2P mreža navedena su u potpoglavlju 2.2. Primjeri ovakve mreže su prva verzija Gnutelle i Freenet. Decentralizirane mreže dalje možemo podijeliti na strukturirane i nestrukturirane.

Kod strukturiranih P2P mreža su čvorišta organizirana prema specifičnim kriterijima ili algoritmima. Ovakve mreže se zasnivaju na ideji distribuiranih hash tablica (DHT), a primjeri ovakve mreže su Can i Chord. Kod nestrukturiranih P2P mreža nije bitna struktura mreže. Članovi su međusobno spojeni na proizvoljan način. Primjer ovakve mreže je Gnutella.

Nestrukturirane mreže ne bi trebale imati nikakav centralizirani sustav, no u praksi postoji nekoliko vrsta nestrukturiranih mreža s različitim stupnjevima centralizacije. Stoga nestrukturirane mreže dalje možemo podijeliti na čiste i hibridne. Čiste P2P mreže sastoje se od ravnopravnih čvorova koji objedinjuju ulogu klijenta i servera. Ne postoji centralni server koji upravlja mrežom niti neki preferirani čvor s posebnom ulogom. Primjer ovakve mreže su Gnutella i Freenet.

Hibridne P2P mreže možemo promatrati kao mješavinu klijent-server i čiste P2P arhitekture. Hibridni pristup dopušta postojanje preferiranih čvorova tzv. superčvorova koji su nadređeni ostalima te na razne načine mogu utjecati na mrežu. Klijent-server arhitekutura se odnosi na pretraživanje datoteka, a čisti P2P na njihov prijenos. Primjeri ovakve mreže su Gnutella2 (moderna implementacija Gnutelle) i Kazaa.

Slika 1. Hibridna P2P mreža



(Slike 1. preuzeta sa: http://static.usenix.org/event/hotbots07/tech/full_papers/wang/wang_html/ (09.05.2012.))

2.4. Prednosti i nedostaci P2P mreža


Jedna od glavnih prednosti P2P mreža je dostupnost velike količine podataka putem velikog broja klijenata. Svaki klijent koji preuzme sadržaj ujedno služi i kao izvor istog te se na taj način povećava dostupnost sadržaja. Zbog toga postoji velik broj izvora što omogućuje brz pristup podacima. Kako se povećava broj izvora, tako se povećava i brzina prijenosa podataka. Nadalje, pogon P2P mreže je uvelike pojednostavljen jer za njenu uspostavu i održavanje nije potreban administrator. Ako neki klijent zakaže, prijenos podataka se može nastaviti sa ostalih klijenata te P2P mreža nastavlja funkcionirati bez posljedica.

Međutim, postoje i nedostaci. Jedan od njih je taj da zajedničko korištenje datoteka može usporiti internetsku vezu. Također, datoteke kopirane iz nepoznatog izvora mogu biti zaražene virusima. Upitna je i legalnost sadržaja. Naime, P2P mreže mogu sadržavati nezakonit materijal i služe za distribuciju nelicenciranih kopija glazbe, filmova, knjiga, igrica, programa koje krše autorska prava. Obično vrijedi pravilo da je preuzimanje nezakonito ako ne plaćate za sadržaj.


2.5. Primjena


P2P mreže su našle primjenu u diskusijskim forumima, prijenosu multimedijalnog sadržaja (Multimedia streaming), razmjeni datoteka (dokumenti, glazbene ili video datoteke,...) i telefoniji (telekonferencijska veza). Također se upotrebljavaju i u drugim područjima života kao što su bioinformatika, poduzetništvo, prosvjeta i vosjka. Svoju primjenu u bioinformatici su pronašle u pokretanju velikih programa s ogromnim skupovima podataka, npr. u istraživanju karcinoma. Primjena P2P mreža u poduzetništvu je u još početnom stanju zbog mnoštva sigurnosnih problema. U prosvjeti se koriste u akademskim i istraživačkim zajednicama dok u vojsci kao dio moderne mrežne ratne strategije.

3. Peer To Peer (P2P) aplikacije

P
eer-to-peer koncept podrazumijeva umrežavanje i komunikaciju računala bez posredstva i prisutnosti poslužitelja gdje je svako računalo inteligentna i ravnopravna stanica u mreži sposobna pronaći druga računala i izravno s njima komunicirati, bez potrebe autorizacije na nekom centralnom poslužitelju. Također, peer-to-peer (P2P) aplikacije su i vrlo popularan način razmjene podataka i informacija među korisnicima, a razmjena se temelji na međusobnom povjerenju sudionika, što može stvoriti probleme i štetu ukoliko su u pitanju zlonamjerni sudionici. Za razliku od klijent – server modela, gdje cjelokupna komunikacija teče preko centralnog poslužitelja, u P2P modelu je komunikacija izravna između svih računala koji su u mreži, što je shematski prikazano na slikama 2. i 3.




Slika 2. Klijent – server model Slika 3. P2P model

(Slike 2. i 3. preuzete sa: Google pretraga (30.04.2012.))
Kod P2P koncepta mrežni resursi su dostupni i drugim sudionicima mreže bez potrebe za središnjim upravljačkim jedinicama kao što su poslužitelji (eng. Server) ili domaćini (eng. Host). Sudionici mreže su ravnopravni, tj. svi sudionici posjeduju jednaka prava uzimanja i davanja resursa (za razliku od modela s poslužiteljem, gdje sudionici mogu samo uzimati a poslužitelj davati resurse). Arhitektura P2P aplikacija je jednostavnija od klijet – server modela. One mogu podnijeti velika opterećenja u radu, ali kod velikog broja sudionika takav način rada značajno usporava rad samog mrežnog sustava.

Peer-to-peer aplikacije dijelimo na:



  • Aplikacije za dijeljenje podataka

  • Aplikacije za IM & online chat

  • Aplikacije za glasovnu i pisanu komunikaciju (VoIP)

  • Aplikacije za multimediju

  • Aplikacije za suradnju i grupe za diskusiju


3.1. Peer-to-peer aplikacije za dijeljenje podataka


Trenutno najpopularnija upotreba peer-to-peer aplikacija je pri dijeljenju podataka među korisnicima. Ovakvo preuzimanje podataka može, ali ne mora biti brže od preuzimanja podataka s poslužitelja. U tu svrhu razvijen je niz računalnih programa koji korisnicima omogućuje preuzimanje besplatnih sadržaja od drugih korisnika. Sadržaji koji se, od drugih korisnika, mogu preuzeti ovim programima uključuju multimedijske datoteke, podatke, druge programe itd.

P2P aplikacije dijelimo po protokolu koji koriste:



  • BitTorent: µTorrent, Vuze (Azureus), Bitcomet, rTorrent

  • Gnutella: BearShare, Limewire, Frostwire, Shareaza

  • Napster: Napster

  • eDonkey: aMule, eMule, Morpheus, Shareaza

µTorrent

Najpopularnija upotreba mreža za dijeljenje podataka među korisnicima je BitTorrent. Temelji se na BitTorrent protokolu za dijeljenje velikih količina podataka. Prema istraživanju tvrtke Ipoque za 2008. i 2009.g., procijenjeno je da, ovisno o geografskoj lokaciji, BitTorrent ostvaruje 22-57% svojega Internetskoga prometa, a u području istočne Europe čak 57% Internetskoga prometa (slika 4.) .


Slika 4. Ostvaren promet u pojedinoj mreži za područje istočne Europe
(Slika 4. preuzeta sa: Google pretraga (30.04.2012.))

Jedna od aplikacija za dijeljenje podataka koja se temelji na BitTorrent protokolu je µTorrent, bespalatan alat za rad s BitTorrent P2P protokolom.

Slika 5. prikaz grafičkog sučelja aplikacije µTorrent



(Slika 5. preuzeta sa: Google pretraga (30.04.2012.))
Podatci se preuzimaju putem „torrent“ datoteka koje sadrže adrese drugih sudionika mreže, koji posjeduju tražene podatke. µTorrent datoteke moguće je pronaći na Internetu putem tražilica, ali i izravnom pretragom u samom programu µTorrent. (Slika 5.)

Prefiks "mikro" u nazivu je dobio zbog načina dizajna, čiji je cilj bio što manje zauzimanje računalnih resursa od strane aplikacije, a da pri tome nudi funkcionalnost, kojom bi konkurirala velikim BitTorrent klijentima poput Vuzea i BitCometa.


LimeWire

LimeWire je P2P aplikacija za razmjenu datoteka koja koristi Gnutella protokol. Postoji besplatna verzija, ali i komercijalna, "Pro" verzija. Kako je LimeWire pisan u Javi, moguće ga je pokrenuti na svakom računalu sa Java Virtual Machine podrškom. Konkretno, LimeWire podržava Microsoftove Windowse, Mac OS X i Linux.


Napster

Iako Napster (2.0) više nije peer-to-peer aplikacija, zaslužuje da ga se spomene. Napster je bio aplikacija za razmjenu glazbe. Napravio ju je Shawn Fanning, za vrijeme studija u Bostonu. Napster je bio "online" od lipnja 1999. do srpnja 2001. Najveću popularnost postigao je u veljači 2001. Napster je bio prvi popularni klijent za razmjenu glazbe među ljudima, što je, naposljetku, dovelo do velikih gubitaka u glazbenoj industriji te tužbi za povredu autorskih prava (protiv Napstera). Iako je zbog tih tužbi Napster na kraju i ugašen, uvijek će biti pamćen kao prva aplikacija na polju P2P razmjene podataka.






3.2. Peer-to-peer aplikacije za IM & online chat


Ove peer-to-peer aplikacije služe za IM (eng. „instant messaging“ – slanje trenutačnih poruka) i online chat. Prema globalnoj popularnosti, navodimo tri najpopularnije:

  • Windows Live Messenger

  • Yahoo! Messenger

  • Tencent QQ (Kina)

Windows Live Messenger

Windows Live Messenger je IM klijent koji je prvi put ušao u korištenje 1999. godine kao MSN Messenger, a preimenovan u sadašnje ime 2005. Windows Live Messenger radi na gotovo svim Microsoftovim platformama: Windows XP, Windows Vista, Windows 7, Windows Server 2003, Windows Server 2008 i Windows Mobile. Osim standardnih funkcija za jednu IM aplikaciju Windows Live Messenger pruža još i usluge razmjene podataka među korisnicima, Windows Live Call (PC-to-phone uslugu) te interoperatibilnost sa Yahoo! Messengerom (u budućnosti i sa Google Talkom, ICQom, Jabberom itd...).

Slika 6. grafičko sučelje Windows Live Messengera-a



(Slika 6. preuzeta sa: Google pretgraga (30.04.2012.))

ICQ

ICQ je jedan od prvih IM klijenata ikad, pušten u rad, za IM pojmove, davne 1996. godine. Program je izradio Mirabilis, izraelska tvrtka iz Tel Aviva, a aktiviran je 1998. i to za 407 milijuna dolara. Ime ICQ potječe od engleske fraze "I seek you". Danas ICQ ima preko 31 milijuna korisnika diljem svijeta. Osim standarnih IM funkcija, ICQ nudi korisnicima multiplayer igre, transfere datoteka, SMS-to-Mobile phone uslugu te audio i video komunikaciju. Program se neprestano nadograđuje, stoga postoji mnogo verzija programa. Najnovija inačica je 7.6.


Slika 7. grafičko sučelje ICQ-a


(Slika 7. preuzeta sa: Google pretraga (30.04.2012.))

Tencent QQ

Tencent QQ, još zvan jednostavno QQ, je najpopularniji kineski IM klijent, te treći najpopularniji IM klijent u svijetu. Osim IM dijela, QQ nudi usluge poput multiplayer igara, online ljubimaca (online Tamagochi), servis za download melodija za mobitel itd... QQ pruža odličnu podršku, te je kompatibilan sa Microsoftovim Windowsima, Mac OS X, Linuxom te ga je odnedavno moguće pokrenuti (u beta verziji) na mobitelima sa trećim izdanjem Symbian S60 platforme. QQ je ujedno zanimljiv i zbog fenomena koji ga okružuje. Naime, QQ je iznimno popularan u Kini, čak do te mjere da je s QQ Coin-ovima (virtualna valuta unutar QQ) moguće kupovati u raznim kineskim online shopovima zbog čega je u tijeku istraga Centralne Narodne Banke Kine zbog korištenja QQ Coin-ova kao regularne valute.


Slika 8. Grafičko sučelje Tencet QQ-a


(Slika 8. preuzeta sa: Google pretraga (30.04.2012.))


3.3. Peer-to-peer aplikacije za glasovnu i pisanu komunikaciju (VoIP)


VoIP je skraćenica od engleske složenice Voice over Internet Protocol i ime je za komunikacijsku tehnologiju koja omogućava prijenos zvučne komunikacije preko internetske mreže. Tehnologija je postala popularna razvojem širokopojasnog interneta, jer u većini slučajeva omogućava besplatno telefoniranje s računala na računalo te jeftinije telefoniranje s računala na mobitele i fiksnu liniju. Neke (već spomenute) od peer-to-peer aplikacija koje podržavaju VoIP su Skype, ICQ te Windows Live Messenger.

Skype
Skype je glavni i najpopularniji predstavnik aplikacija za VoIP. Skype, kao i sve VoIP sposobne aplikacije, dopušta korisniku "telefoniranje" preko Interneta. Dodatne usluge koje nudi su IM, prijenos datoteka, video telefoniju te video konferencije. Kreatori Skypea su Niklas Zennström, Janus Friis i tim programera s bazom u Tallinnu, u Estoniji. Skype danas ima preko 310 milijuna korisnika te i dalje, kao i na početku svog postojanja, bilježi ogroman rast u popularnosti koji je rezultirao kupnjom Skypea 2005. od strane eBaya za 2.6 milijarde dolara, te kasnije i Microsofta 2011. za 8.5 milijardi dolara. Skype je dostupan u verzijama za Linux, Mac OS X, Microsoft Windows sustave (2000, XP, Vista, 7, Windows Mobile), pa čak i za Sonyev PSP.



Slika 9. Grafičko sučelje Skype-a
(Slika 9. preuzeta sa: Google pretraga (30.04.2012.))

3.4. Peer-to-peer aplikacije za multimediju


Iako se peer-to-peer aplikacije za razmjenu datoteka često povezuju sa ilegalnom razmjenom datoteka te povredom autorskih prava, programi za razmjenu datoteka mogu se koristiti i za legalnu distribuciju softvera i multimedije. Npr. nezavisni umjetnici mogu svoje uratke te software nuditi preko nekih od P2P mreža. Jedan od primjera je Američka vlada, koja je razvila igricu America's Army i za jedan od načina distribucije koristila BitTorrent. Također, popularni Blizzard Downloader, koji služi za preuzimanje raznih datoteka (dopune igara, video isječci i najave budućih projekata itd...), koristi Bittorent protokol. Blizzard također pruža i individualan klijent za svaki download umjesto samo torrent datoteke. Dok Downloader radi, osim skidanja željene datoteke on ju ujedno i distribuira korisnicima koji je trebaju.

3.5. Peer-to-peer aplikacije za suradnju i grupe za diskusiju


U ovu kategoriju spadaju aplikacije koje su namijenjene lakšoj suradnji i komunikaciji među ljudima koji rade na istom projektu i pomaže im u postizanju zajedničkog cilja, pri tome olakšavajući međusobnu komunikaciju i dajući im pregled nad radom i napretkom ostalih članova tima. Glavni predstavnik ove grupe aplikacija je Microsoft Groove.
Microsoft Groove

Microsoft Office Groove je aplikacija dizajnirana da olakša suradnju između pripadnika jednog tima koji rade na projektima zajedno, te su često nedostupni (offline). Groove je inicijalno dizajnirao i izradio Ray Ozzie, još poznat kao tvorac Lotus Notesa, te dalje razvijan od strane Groove Networks-a sve do akvizicije 2005. g. od strane Microsofta u čijem je vlasništvu i danas. Najnovija radna verzija je poznata pod imenom Groove 2010 te se može kupiti samostalno ili kao dio Office paketa.

Sam Groove baziran je na konceptu "radnih okruženja" (eng. workspaces). Korisnici ih sami mogu kreirati te pozivati nove korisnike. Također, postoji prostor za datoteke u okruženju koji se u slučaju promjena nadopuni uz pomoć peer-to-peer tehnologije. Kada su neki od korisnika nedostupni u trenutku promjena, Groove promjene sprema na Office Groove server te ih stavlja u red (eng. queue) koji se puni dok nedostupni korisnici ne postanu dostupni. Osim toga postoji i prostor za diskusiju te IM usluga.

4. Programiranje socketa s TCP i UDP

4.1. Socket programiranje s TCP-om


TCP (Transmission Control Protocol) omogućuje da dva veća računala priključena na mrežu uspostave izravnu vezu i razmjenjuju podatke. Ovaj protokol jamči isporuku podataka na odredište, ali isto tako i isporuku paketa ispravnim redosljedom, tj. redosljedom njihova slanja.

Ako svaki proces zamislimo kao kuću, sockete procesa možemo promatrati kao vrata između procesa i protokola (npr. TCP ili UDP) – proces šalje poruku u socket i dobija poruke iz socketa.



Slika 10. Komunikacija procesa kroz TCP sockete


(Slika 10. preuzeta s: http://www.cs.umd.edu/~shankar/417-F01/Slides/chapter2b-aus/sld012.htm (30.4.2012.))
Proces komunikacije klijenta i servera ćemo prikazati kroz primjer u Pythonu. Ići ćemo korak po korak i tako pisati dijelove koda da odmah dobijete osjećaj kako to izgleda u Pythonu. Cijeli kod bez objašnjenja možete pronaći u poglavlju 5. Primjeri. U primjeru ćemo napisati kod za jednostavnog servera i klijenta. Nakon uspostave konekcije server šalje klijentu poruku „Dobro dosli!“. Nakon toga klijent treba serveru poslati poruku, i dobiti odgovor od klijenta. Radi jednostavnosti, neka serverov odgovor bude: „Server primio poruku: poruka_klijenta“, gdje je poruka_klijenta poruka koju je klijent poslao.

Prikažimo prvo kod servera:



Gornji dio prikazuje stvaranje socketa. Prvo moramo uključiti posebnu biblioteku za sockete: socket. Nakon toga, pomoću funkcije socket(), kreiramo socket. Atribut socket.AF_INET znači da je to socket iz adresne familije internet protokola (IPv4), dok atribut socket.SOCK_STREAM označava da se radi o TCP socketu. Ovaj dio koda je isti i za servera i za klijenta. U njemu za sada još uvijek nemamo uspostavljenu vezu.

Sada bi bilo dobro odlučiti se za port na kojemu će server čekati konekcije. Taj port mora biti isti i za servera i za klijenta da bi se mogla uspostaviti veza. Neka to kod nas bude port 54321.

Dalje se kod klijenta razlikuje od koda servera. Pogledajmo prvo kako povezati serverov socket sa mrežnim sučeljem i postaviti ga kao pasivnog:



U 5. i 6. retku koda smo samo odredili adresu i port na kojem server čeka klijente. Port kod servera klijentu mora biti poznat da zna „na koja vrata treba pokucati“. Naš server čeka klijente samo na portu port, pa se klijent neće moći spojiti ako ode na neki drugi port. Adresa 127.0.0.1 je localhost, tj. adresa lokalnog računala.

U 7. retku postavljamo opcije socketa. socket.SO_REUSEADDR znači da možemo koristiti lokalni socket nakon korištenja prije bez čekanja da istekne njegovo prirodno vrijeme za ponovno korištenje. Funkcijom bind((host, port)) povezujemo socket s uređenim parom adrese i porta. Prije poziva ove funkcije socket ne smije već biti povezan.

Naredbom s.listen(1) smo odredili socket s kao pasivni. On sada čeka zahtjeve klijenata za uspostavom konekcije. Argument u zagradi je broj klijenata koji mogu čekati za uspostavu veze ako niti jedan aktivni socket nije slobodan. Taj broj treba biti barem nula.

Sada, kada smo to napravili, možemo preći na dio koda u kojem čekamo klijente, i stavaramo aktivne sockete:

Kako server treba stalno čekati na klijente, konekcije čekamo u beskonačnoj petlji. Dijelovi koda koji počinju naredbom print nam u objašnjavanju socketa nisu bitni. Oni su tu samo da nama, kao programerima, bude jasnije što se događa. Na kraju, kada budemo imali i kod za klijenta, ćemo pokazati i što dobijemo u ispisu, pa će tamo ti dijelovi dobiti smisao.

Funkcija accept() je blocking naredba koja prima konekcije. Kao rezultat accept() daje par client_sock, client_addr, gdje je client_sock novi, aktivni, socket koji koristimo za slanje i primanje podataka, a client_addr adresa klijenta.

Funkcijom sendall(arg) šaljemo sve podatke arg. Ona šalje podatke na drugu stranu konekcije sve dok ne pošalje sve, ili ne dođe do greške. Ako dođe do greške, nije moguće odrediti koliko podataka je poslano. Za razliku od funkcije za slanje, Python nema ugrađenu funkciju za primanje podataka koja će primiti sve podatke. Zašto? Vjerojatno zato što su poruke s fiksnom veličinom vrlo rijetke. Mnogi protokoli imaju puno složenija pravila od toga da je poruka uvijek veličine 64 bytea (kao što je to u našem primjeru). Naša funkcija recv(64) prima najviše 64 bytea od socketa s druge stranje konekcije. Funkcija recv() je, kao i accept(), blocking funkcija. Ona čeka i blokira program sve dok druga strane ne pošalje podatke.

Na kraju rada s klijentom nam preostaje još samo zatvoriti aktivni socket, i čekati na druge klijente. To smo napravili u 19. retku koda: client_sock.close().

Sada možemo pogledati kod klijenta. Stvaranje socketa je isto kao kod servera, pa ćemo odmah prijeći na spajanje:



Kao i kod servera, naredili smo fiksni port na koji se klijent spaja. Klijent se na server spaja funkcijom connect(addr). addr je uređeni par adrese i porta na koji se spajamo, u našem slučaju (host, port). Ovdje počinje komunikacija između servera i klijenta. Klijent je taj koji započinje komunikaciju. To se događa kroz tzv. handshake. (Slika 11.)



Slika 11. Otvaranje TCP veze (handshake)


(Slika 11. preuzeta s: http://www.itmanage.info/technology/linux/statefull_fireall/Concept_of_State.htm (30.4.2012.))
Da bi bilo moguće uspostaviti konekciju, u trenutku kada se klijent javi serveru, proces na serveru već mora biti aktivan. Server ima poseban socket, tzv. pasivni socket koji čeka na klijente. Klijent pošalje serveru obavijest da želi uspostaviti konekciju, pasivni socket to primi, i nakon handshakea, stvara novi – aktivni socket za komunikaciju s tim klijentom.

Sada imamo konekciju između klijenta i servera, pa možemo slati i primati poruke:



Kao što vidimo, naredbe su iste kao i kod servera, pa ih nije potrebno dodatno objašnjavati.

Kao i kod uspostave konekcije tako i na kraju komunikacije TCP socketa postoji određena formalnost, tj. razmjena paketa prije zatvaranja socketa (Slika 11.)

Slika 12. Zatvaranje TCP veze


(Slika 12. preuzeta s: http://www.itmanage.info/technology/linux/statefull_fireall/Concept_of_State.htm (30.4.2012.))
Pogledajmo rezultat našeg programa:

Kao što smo već napomenuli, da bi mogli uspostaviti vezu, prvo moramo pokrenuti servera:



Server je sada spreman i čeka na klijente. Tek sada možemo pokrenuti i klijenta:



Nakon što smo ga pokrenuli, primio je poruku od servera. Sada je na klijentu red da pošalje poruku. Tada se dogodi sljedeće:



Server je primio poruku, ispisao je na ekran, poslao odgovor klijentu, i završio komunikaciju s tim klijentom. Sada može čekati druge klijente. Pogledajmo što imamo kod klijenta:



Nakon što je poslao poruku, primio je poruku od servera, i završava s radom. Primjetimo da je server nastavio raditi, a klijent potpuno završio s radom. Razlog tome je beskonačna petlja kod servera. Recimo, npr., da smo stavili neku datoteku na server tako da bude svima dostupna. Klijentu je dovoljno jednom doći i skinuti je, ali server bi trebao stalno raditi tako da svi klijenti koji žele tu datoteku mogu doći do nje. Da nema beskonačne petlje, server bi dopustio jednom klijentu da skine datoteku, i prestao s radom. Drugi klijenti onda ne bi mogli doći do datoteke preko tog servera.


4.2. Socket programiranje s UDP-om


Uz TCP protokol, postoji još jedan, ali mnogo manje zastupljen u praksi, a to je UDP (User Data Protocol) protokol. Jednostavniji je od TCP-a jer ne vodi računa o izgubljenim paketima, kojim redom će sami paketi stići na odredište, te ne čuva informacije o stanju veze (radi na principu pošalji i zaboravi). Zapravo, sve što vam je potrebno za uspostavu komunikacije između dva računala putem UDP protokola su IP adresa i port. Komunikacija započinje tako što jedno od računala (klijent) pošalje prvi paket na unaprijed poznatu IP adresu i port (servera). U slučaju da klijent ne zna točan port na koji treba poslati paket, a zna ime odredišta, može ga saznati pozivom funkcije getservbyname() iz standardnog Python socket modula:

Pri stvaranju socketa, moramo obratiti pozornost na to da socket stvaramo za UDP protokol pa će tada kod izgledati ovako:



pri čemu po atributu SOCK_DGRAM prepoznajemo da se radi o UDP socketu.

U ovom trenutku nastao je tzv. nul-socket gdje su IP adresa i port postavljeni na nul vrijednosti što možemo vidjeti pozivom funkcije getsockname(). Čim odlučimo nešto poslati (u slučaju klijenta), novim pozivom već spomenute funkcije vrijednost porta će se promjeniti, tj. više neće imati nul vrijednost nego neki konkretan port iz baze slobodnih portova.

S druge strane pri stvaranju socketa server mora korisiti funkciju bind() gdje jedan socket odmah povezuje sa IP adresom i portom koji su prije definirani. Primjer:





Slika 13. Komunikacija između UDP servera i UDP klijenta


(Slika 13. preuzeta sa: http://msdn.microsoft.com/en-us/library/aa916134.aspx (02.05.2012.))
Kako se socket koristi u programu nakon što smo ga stvorili pokazuje nam sljedeći primjer: (kod za server)

Nakon što smo spojili socket sa adresom lokalnog računala i portom 2764 (ako program pokaže error to je stoga što je taj port možda već zauzet), pokrenuli smo jednu beskonačnu petlju. U toj petlji očekujemo konekcije, tj. da nam se jave određeni klijenti. Također, odredili smo maksimalan broj bitova (65535) koje možemo primiti. To je ujedno i najveća duljina koju UDP paket može imati, a u ovom primjeru to znači da ćemo zaprimiti sve podatke koje nam klijent šalje. U suprotnom, kada bi broj bitova koji možemo primiti smanjili, postoji mogućnost da ne bi primili cijelu poruku od klijenta. Kada primamo podatke koristimo funkciju recvfrom() koja, osim podataka, daje i adresu s koje su podaci poslani, tj. adresu klijenta. Nakon što smo zaprimili podatke, program će ih ispisati na ekran, a zatim klijentu poslati povratnu poruku. To činimo funkcijom sendto() u koju upisujemo poruku i adresu na koju šaljemo.

Treba spomenuti da kod funkcije sendto() nije moguće znati je li je onaj drugi primio poruku koju smo mu poslali. UDP nema nikakav mehanizam koji će podići error ako se npr. paket zagubio i nije stigao na odredište.

Pogledajmo kako isti program izgleda sa strane klijenta:


Odmah primjećujemo kako kod klijenta nismo koristili funkciju bind() nego ostavili da računalo samo odabere koji port će koristiti za slanje podataka sa lokalnog računala. Zato će se pri pokretanju programa na ekran prvi ispisati vrijednosti nul-socketa:



 

No, čim počnemo nešto slati, računalo će, kako je već spomenuto, samo odabrati neki od slobodnih portova. Primjetimo da se zbog toga adresa nakon slanja promjenila:



Kada nam server vrati poruku, zaprimit ćemo je i to također cijelu jer je broj mogućih bitova za primanje i sada postavljen na maksimalan broj bitova. Nakon zaprimanja, poruka servera prikazat će se na ekranu. Kad primamo poruku koristimo funkciju recvfrom(), ali mogli smo koristiti i recv() jer (zasad) znamo da će poruka koju će klijent primiti biti od servera s kojim smo prethodno stupili u komunikaciju.

Sve to izgleda vrlo jednostavno, ali kako smo već spomenuli da ovaj protokol ne vodi računa o izgubljenim paketima, nepouzdan je, i može doći do raznih problema. To nismo mogli primjetiti u prethodno napisanom kodu jer su i server i klijent pokrenuti s istog računala pa i nije bilo stvarne komunikacije putem mreže. Mogući problemi nastaju ako se paketi izgube zbog nekakvih problema sa mrežom, ili je mrežni segment prezauzet. Zbog toga sam klijent mora voditi računa o takvim stvarima, tako da bude u mogućnosti ponovno slati zahtjev sve dok ne dobije odgovor.

Na primjer, što bi se dogodilo kada bi umjesto funkcije recvfrom() iz socket modula u kodu klijenta koristili funkciju recv()? Možemo li tada biti sigurni da su podaci zaprimljeni od servera stvarno od onog servera kojem smo uputili zahtjev? Ne možemo. Vrlo lako se može dogoditi da nam neki drugi server upadne. To je moguće ako ima naš aktivan port i adresu koje je npr. mogao pokupiti iz prvog paketa koji je klijent poslao pravom serveru. Kod takvih i drugih stvari pomaže nam funkcija connect() umjesto bind() za neku prije definiranu adresu i port:

s.connect((adresa, port))

Zašto je ona korisnija od funkcije bind()? Jer dopušta operacijskom sustavu da unaprijed zna na koju adresu želimo poslati podatke. Na taj način ne moramo svaki put slati adresu servera, pa podatke šaljemo funkcijom send() (ne više sendto()). No, još je važnije da, kada pokrenemo poziv connect(), operacijski sustav automatski odbacuje sve dolazne poruke čija se adresa ne poklapa sa onom koju smo koristili pri connect() pozivu. Također, klijent u svakom trenutku može provjeriti koju je adresu koristio za spajanje UDP socketa koristeći socket metodu getpeername().

Dakle, pri komunikaciji između dva računala uz korištenje UDP protokola treba paziti na povratne adrese na koje šaljemo pakete. To možemo na dva načina:


  • Korištenjem sendto() i recvfrom()
    Sa sendto() za svaki izlazni paket specificiramo odredište, a sa recvfrom() primamo adresu s koje nam stižu podaci, ali tada moramo sami provjeriti podudara li se s onom na koju smo poslali.

  • Korištenjem connect()
    Tada umjesto sendto() i recvfrom() koristimo send() i recv(), a operacijski sustav se umjesto nas pobrine da adrese dolazećih paketa budu jednake onoj na koju smo poslali. Treba napomenti da ovo vrijedi za istovremenu komunikaciju samo sa jednim serverom.

Za kontroliranje specifičnih ponašanja mrežnih socketa stvorenih za UDP protokol koriste se razne opcije. Kada postavljamo opcije socketa, prvo moramo navesti grupu opcija u kojoj opcija živi, a zatim kao argument imenujemo pravu opciju koju želimo postaviti. Za to se treba konzultirati sa operacijskim sustavom. Kako to izgleda na primjeru?

 

Neke od najčešćih opcija za UDP protokol su:



  • SO_BROADCAST – omogućava slanje broadcast paketa. Naime, UDP protokol omogućava da se neki paket odjednom pošalje ne samo jednom već svim računalima u nekoj određenoj podmreži, bez da se kopira odvojeno i šalje svakom od tih računala.

  • SO_DONTROUTE – paketi se šalju samo onim računalima koji su u podmreži na koju je izvršno računalo direktno spojeno

  • SO_TYPE – vraća kojeg je tipa socket, TCP ili UDP, tj.vraća SOCK_DGRAM za UDP, a SOCK_STREAM za TCP

5. Primjeri


Ovo poglavlje služi kao dodatak seminaru. U njemu možete pronaći kodove objašnjene u poglavlju 3. Programiranje socketa s TCP i UDP.

# TCP_server.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


host = '127.0.0.1'

port = 54321

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

s.bind((host, port))

s.listen(1)
while True:

print "Cekam konekcije..."

client_sock, client_addr = s.accept()

print "Spojio se ", client_addr

client_sock.sendall("Dobro dosli!")

data = client_sock.recv(64)

print "Klijent salje poruku:", data

client_sock.sendall("Server primio poruku: " + data)

client_sock.close()

print "Klijent", client_addr, "otisao."



# TCP_klijent.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '127.0.0.1'

port = 54321

s.connect((host, port))
data = s.recv(64)

print data

message = raw_input("Vasa poruka serveru:\n\r>>")

s.sendall(message)

data = s.recv(64)

print data

print "Kraj rada..."
s.close()

# UDP_server.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
MAX = 65535

port = 54321
s.bind(('127.0.0.1' ,port))

print 'Cekam konekcije na...', s.getsockname()

while True:

data, address = s.recvfrom(MAX)

print 'Klijent na', address, 'kaze', repr(data)

s.sendto('Vasa poruka ima %d bitova' %len(data), address)
# UDP_klijent.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
MAX = 65535

port = 54321
print 'Adresa prije slanja:', s.getsockname()

s.sendto('Ovo je moja poruka', ('127.0.0.1', port))

print 'Adresa poslije slanja:', s.getsockname()

data, address = s.recvfrom(MAX)

print 'Server', address, 'kaze:', repr(data)
6. Zaključak

U originalnoj ideji, kod P2P mreže nije postojao glavni server. Sva računala umrežena u tu mrežu bila su hijerarhijski jednaka. To je u praksi teško izvedivo, pa, kao što smo vidjeli u prethodnim poglavljima, postoji više izvedbi P2P mreža. Ovakve mreže koristimo npr. kod chat aplikacija, ili kod razmjene podataka, gdje klijenti međusobno razmjenjuju podatke. U tom slučaju često je upitna legalnost sadržaja.



Da bi klijenti mogli međusobno komunicirati (ili komunicirati sa serverom), mora postojati nekakav program, ili aplikacija preko koje jedni drugima šalju podatke, i preko kojih isto tako i primaju podatke jedni od drugih. Kada programiramo mrežne aplikacije, svjesni smo da se ta komunikacija najviše odvija preko socketa. Socketi su ti koji i primaju, i šalju podatke. Također, bitno je pri tome znati koji protokol koristimo u komunikaciji, pa prema njemu, i pravilima kojima je određen, programiramo sockete za naše aplikacije. U ovom seminaru smo pokazali kako programiramo sockete za servera i klijenta za dva protokola: TCP i UDP. Vidjeli smo da TCP ima ugrađene mehanizme koji nam osiguravaju sigurnu isporuku podataka na odredište, i to pravilnim redoslijedom. Kod UDP protokola takvi mehanizmi ne postoje, pa o tome moramo brinuti sami (ako nam je potrebno).

Literatura


  1. B. Rhodes, J. Ghoerzen, Foundations of Python Network Programming, 2Ed, Apress, 2009

  2. J. F. Kurose, K. W. Ross, Computer Networking: A Top Down Approach, 5ed, Pearson, 2010

  3. Wikipedia

  4. http://docs.oracle.com/javase/tutorial/networking/sockets/index.html (30.4.2012.)

  5. http://docs.python.org/library/socket.html (30.4.2012.)

  6. http://hr.wikipedia.org/wiki/IP (01.05.2012.)

  7. http://msdn.microsoft.com/en-us/library/windows/desktop/ms740506%28v=vs.85%29.aspx (30.4.2012.)

  8. http://www.buyya.com/java/Chapter13.pdf (30.4.2012.)

  9. http://www.cert.hr/sites/default/files/NCERT-PUBDOC-2009-11-282.pdf (02.05.2012.)

  10. http://www.cs.umd.edu/~shankar/417-F01/Slides/chapter2b-aus/sld011.htm (30.4.2012.)

  11. http://www.fer.unizg.hr/_download/repository/p2p_aplikacije.pdf (02.05.2012.)

  12. http://www.itmanage.info/technology/linux/statefull_firewall/Concept_of_State.htm (30.4.2012.)



База данных защищена авторским правом ©shkola.of.by 2016
звярнуцца да адміністрацыі

    Галоўная старонка