Jak naprogramovat internetovou komunikaci?
Připomenutí IP paket v. 4
TCP protokol transportní protokol RFC 793 spojovaná spolehlivá služba zajišťuje číslování paketů a potvrzování příjmu mezi koncovými stanicemi na počátku komunikace je potřeba navázat spojení chová se jako plně duplexní virtuální kanál řízení toku
TCP paket pseudohlavička
číslování paketů SEQ number, ACK number control bits: URG příznak urgentních dat ACK- platnost hodnoty ACK number PSH požadavek na bezprostř. předání RST žádost o okamžité ukončení spojení SYN otevírání spojení FIN uzavření spojení v jednom směru
Navazování spojení 3 fázové potvrzovací schéma three way handshake využívají se řídící bity pole CODE a čísla SEQ number a ACK number vytvoří se dva jednosměrné kanály (duplex)
1 2 SYN seqno=x SYN seqno=y, ACK ackno=x+1 ACK ackno=y+1 SYN seqno=x SYN seqno=y, ACK ackno=x+1 ACK ackno=y+1
Uzavírání spojení každý jednosměrný kanál se uzavírá samostatně
1 2 FIN seqno=x ACK ackno=x+1 FIN seqno=x ACK ackno=x+1 FIN seqno=y, ackno=x+1 FIN seqno=y, ackno=x+1 ACK ackno=y+1 ACK ackno=y+1
Porty přípojné místo aplikace proces proces vyšší vrstva port port? transportní vrstva
Dobře známé porty (vyhrazené) některé porty mohou existovat trvale a jejich čísla (adresy) jsou vyhrazeny tzv. dobře známé porty (well-known ports) slouží např. k přijímání žádostí o konkrétní služby např. na portu 80 se přijímají požadavky na WWW stránky jiné porty mohou vznikat dynamicky a dostávat dynamicky přidělovaná čísla od OS takovéto porty jsou zřizovány pro potřeby již navázaných komunikací např. pro vlastní přenos souborů, přičemž žádost je směrována na vyhrazený port
1/tcp tcpmux TCP Port Service Multiplexer 2/tcp compressnet Management Utility 3/tcp compressnet Compression Process 5/tcp rje Remote Job Entry 7/tcp echo Echo 9/tcp discard Discard 11/tcp systat Active Users 13/tcp daytime Daytime (RFC 867) 17/tcp qotd Quote of the Day 18/tcp msp Message Send Protocol 19/tcp chargen Character Generator 20/tcp ftp-data File Transfer [Default Data] 21/tcp ftp File Transfer [Control] 22/tcp ssh SSH Remote Login Protocol 23/tcp telnet Telnet 24/tcp any private mail system any private mail system 25/tcp smtp Simple Mail Transfer 27/tcp nsw-fe NSW User System FE 29/tcp msg-icp MSG ICP 31/tcp msg-auth MSG Authentication 33/tcp dsp Display Support Protocol 35/tcp any private printer server any private printer server 37/tcp time Time 38/tcp rap Route Access Protocol 39/tcp rlp Resource Location Protocol 41/tcp graphics Graphics 42/tcp nameserver Host Name Server 43/tcp nicname Who Is 44/tcp mpm-flags MPM FLAGS Protocol 45/tcp mpm Message Processing Module [recv] 46/tcp mpm-snd MPM [default send] 47/tcp ni-ftp NI FTP 48/tcp auditd Digital Audit Daemon 49/tcp tacacs Login Host Protocol (TACACS) 50/tcp re-mail-ck Remote Mail Checking Protocol 51/tcp la-maint IMP Logical Address Maintenance 52/tcp xns-time XNS Time Protocol 53/tcp domain Domain Name Server 54/tcp xns-ch XNS Clearinghouse 55/tcp isi-gl ISI Graphics Language 56/tcp xns-auth XNS Authentication 57/tcp any private terminal access any private terminal access 58/tcp xns-mail XNS Mail 59/tcp any private file service any private file service 60/tcp Unassigned Unassigned 61/tcp ni-mail NI MAIL 62/tcp acas ACA Services 63/tcp whois++ whois++ 64/tcp covia Communications Integrator (CI) 65/tcp tacacs-ds TACACS-Database Service 66/tcp sql*net Oracle SQL*NET 67/tcp bootps Bootstrap Protocol Server 68/tcp bootpc Bootstrap Protocol Client 69/tcp tftp Trivial File Transfer 70/tcp gopher Gopher 71/tcp netrjs-1 Remote Job Service 72/tcp netrjs-2 Remote Job Service 73/tcp netrjs-3 Remote Job Service 74/tcp netrjs-4 Remote Job Service 75/tcp any private dial out service any private dial out service 76/tcp deos Distributed External Object Store 77/tcp any private RJE service any private RJE service 78/tcp vettcp vettcp 79/tcp finger Finger 80/tcp http-www World Wide Web HTTP 81/tcp hosts2-ns HOSTS2 Name Server 82/tcp xfer XFER Utility 83/tcp mit-ml-dev MIT ML Device 84/tcp ctf Common Trace Facility 85/tcp mit-ml-dev MIT ML Device 86/tcp mfcobol Micro Focus Cobol 87/tcp any private terminal link any private terminal link 88/tcp kerberos Kerberos 89/tcp su-mit-tg SU/MIT Telnet Gateway 90/tcp dnsix DNSIX Securit Attribute Token Map 91/tcp mit-dov MIT Dover Spooler 92/tcp npp Network Printing Protocol 93/tcp dcp Device Control Protocol 94/tcp objcall Tivoli Object Dispatcher 95/tcp supdup SUPDUP 96/tcp dixie DIXIE Protocol Specification 97/tcp swift-rvf Swift Remote Virtural File Protocol 98/tcp tacnews TAC News 99/tcp metagram Metagram Relay 101/tcp hostname NIC Host Name Server 102/tcp iso-tsap ISO-TSAP Class 0 103/tcp gppitnp Genesis Point-to-Point Trans Net 104/tcp acr-nema ACR-NEMA Digital Imag. & Comm. 300
UDP protokol nadstavba protokolu IP RFC 768 nepotvrzovaná datagramová služba rozšiřuje IP protokol o porty
UDP paket
ICMP Internet Control Message Protocol služební (řídicí) protokol internetu musí jej implementovat každé zařízení zprávy ICMP jsou zabaleny do IP paketu příklady zpráv (pole Type): 0 Echo reply (odpověď na požadavek, při PINGu) 3 Destination unreachable (dále se větví dle pole CODE) 5 Redirect 6 Alternate host address 8 Echo Request 11 Time Exceeded (TTL k 0)
ICMP paket
Co nám nabízejí některé programátorské nástroje? nižší úroveň programování programování pomocí tzv. socketů UNIX, Linux, Windows, Python, JAVA vyšší úroveň zapouzdření služeb (socketů) do tříd v rámci objektově orientovaného programování JAVA,.NET (Microsoft), Python MFC třída CSocket Code Gear: TBaseSocket, TCPClient,...
Rozhraní socketů Je sice nejstarší, na nízké úrovni, ale stále se používá
Rozhraní socket BSD (Berkley Socket Distribution) jde o standardní softwarové rozhraní pro zasílání dat pomocí rodiny IP protokolů vymyšleno a poprvé implementováno na univerzitě v Berkley do OS UNIX umožňuje programátorům používat TCP/IP, resp. UDP, obdobným způsobem, jako se pracuje se soubory
Charakteristika poprvé implementováno v jazyce C implementace do operačních systémů UNIX (Linux) - knihovna socket.h MS Windows knihovna winsock.h programátorské funkce jsou navrženy tak, aby bylo snadné naprogramovat aplikaci klient -server
Princip práce se soubory v jazyce C nejprve se soubor otevře ; informace o otevřeném souboru se uloží do specální datové struktury OS (file descriptor) zde proměnná f (ukazatel na typ FILE*) f = fopen( text.doc, rb ) jméno souboru mód otevření r čtení, w zápis b binární mód
ze souboru čteme data pomocí funkce fread( ), zapisujeme data pomocí funkce fwrite( ) zde v ukázce např. do pole data přečteme 10 bloků po 1 bytu ze souboru f, který jsme předtím otevřeli fread(data,1,10,f) po skončení práce uzavřeme soubor voláním funkce fclose( ) fclose(f)
návrháři přenesli tento jednoduchý princip do programování komunikace sítí Je to ale přece o trochu složitější programujeme aplikaci klient/server server čeká na příchod požadavku klienta TCP je orientované na spojení funkce navazující spojení musíme znát mnoho údajů IP adresu vlastní a partnera, port
Co je to socket? učeně koncový komunikační uzel (endpoint) méně učeně datová struktura (data), nesoucí informaci o stavu síťového spojení; musíme jej vytvořit voláním speciální funkce podobně jako fopen pro otevření souboru komunikujeme pomocí funkcí write() a read(), jejichž parametr je otevřený socket (kam se posílají data)
Základní funkce rozhraní socket() vytvoří strukturu socket používá jej klient i server argumentem je rodina a typ protokolu (TCP,UDP), typ služby (spojovaná/nespojovaná) vrací nový socket closesocket() dealokuje (zavírá) socket
Funkce používané serverem bind() připojí do socketu identifikaci lokálního uzlu, tj. moji IP adresu a port listen() spojovaná služba pasivuje socket, vytvoří frontu pro požadavky na spojení (přes rezervovaný port) accept() - spojovaná služba přijde-li požadavek, accept vytvoří nový socket, pomocí něhož server komunikuje s klientem; původní socket je nadále v pasivním stavu a očekává příchod nového požadavku (na rezervovaném portu)
Funkce používané klientem connect() - spojovaná služba vytvoří spojení ke vzdálenému serveru v případě TCP 3-fázový potvrzovací protokol parametrem je adresa a port vzdáleného serveru po vytvoření spojení lze zahájit výměnu dat se serverem
Funkce přenosu dat read(), write() - spojovaná služba recv(), recvfrom(), recvmsg send(), sendto(), sendmsg() čtení a zápis dat do socketu recvfrom zaznamená i příjemce
Spojované služby Klient socket connect write read close Server socket bind listen accept read write close
Nespojované služby Klient socket connect write Server socket bind recvfrom recvmsg read close sendto sendmsg close
Konkurentní TCP server Server (proces) Vlákno (syn) Vlákno (syn) Aplikace rezervovaný port individuální sockety a porty Operační systém
Ukázky, jak se to programuje 1. Vytvoření socketu s=socket(pf_inet,sock_stream, IPPROTO_TCP) rodina protokolů spojovaná služba protokol TCP
Ukázky, jak se to programuje 2. Bind server: vložení vlastní IP adresy a portu k socketu naplním datovou strukturu pro adresu a port addr.sin_family = AF_INET; port, kde poslouchám addr.sin_port = hston(3434); addr.sin_addr.s_un.s_addr = INADDR_ANY; bind(s,(sockaddr*)&addr,sizeof(addr)) moje adresa (0.0.0.0)
Ukázky, jak se to programuje 3. listen server: čeká na příchod požadavku listen (s,somaxcon); socket max. délka fronty
Ukázky, jak se to programuje 4. accept server: po příchodu požadavku vytvoří nový socket a zpravidla vytvoří nový proces, který dále komunikuje nový socket //vytvoření nového procesu sx=accept (s, adresa,délka); read(sx,data,vel); write(sx,data,vel);
algoritmičtěji (Linux) listen(s,somaxcon); while (není_konec) { SOCKET sx = accept (s,addr,&delka); fork() //vytvoření syn. procesu { read(s,data,vel); write(s,data,vel); } }
k dispozici je mnoho pomocných funkcí pro získání informací o počítači: gethostbyname() GetAddressByName - ve winsock2.h čtení a změna parametrů socketu getsockopt(), setsockopt() převodní funkce getservbyport() zjistí informace o serveru, např. voláme z řetězcem FTP, vrátí port 21 přidělení náhodného čísla portu
Princip socketů je stále využíván i v nových programátorských prostředcích!
Programování pomocí OOP (objektově orientovaného programování)
JAVA sockety, třídy pro práci s adresami Microsoft MFC objektové prostředí pro tvorbu aplikací ve Windows pro síťové poskytuje zapouzdřený socket jako CSocket.NET definovány třídy na vyšší úrovni (TCPClient, WebClient)
Code Gear C++ Builder TCP spojení TBaseSocket TIpSocket TServerWinSocket TClientWinSocket aj.
Microsoft.NET
Prostředí.NET generace systému vývoje aplikací pro operační systémy Windows založeném na řízeném běhovém prostředí založeno na OOP je realizováno pomocí velkého počtu speciálních tříd podporuje více programovacích jazyků C++, C#, J++, Visual Basic
Třídy IPEndPoint TCP/UDP komunikace práce s IP adresou a port TcpClient, TcpListener spojovaná služba UdpClient nespojovaná služba
IPEndPoint nese informaci o adrese a portu atributy Address, AdressFamily, Port zajímavé metody ToString převede adresu na řetězec Create vytvoří objekt podle socketu
TCPClient zapouzdřuje kompletní TCP komunikaci pro stranu klienta zajímavé atributy ReceiveBufferSize, ReceiveTimeout, SendBufferSize zajímavé metody Connect(IPEndpoint endpoint) spojí se se serverem na adrese dané parametrem endpoint
NetworkStream GetStream() vrátí objekt typu Stream, pomocí jehož metod zasíláme/přijímáme data; zasílání dat se neprovádí přímo pomocí metod této třídy Close() uzavření spojení
TCPListener zapouzdřuje kompletní TCP komunikaci pro stranu serveru zajímavé atributy LocalEndpoint informace o mé adrese a portu zajímavé metody Start() začíná poslouchat na portu, ekvivalentní funkci listen()
Socket AcceptSocket(), TcpClient AcceptTcpClient() vrací nový socket nebo objekt typu klient, pomocí kterého se zajišťuje další komunikace NetworkStream GetStream() bool Pending() dotaz, zda není ve frontě nevyřízený požadavek na spojení
Ukázka v C++ //vytvorime instanci posluchace pro urcity //TCP port TCPListener *listener = new TCPListener(IPAddress.Loopback, 2000); TcpClient *client = NULL; //zacneme naslouchani na urcenem portu listener->start(); //pockame na pripojeni nejakeho klienta client = listener->accepttcpclient();
// po pripojeni si vyzvedneme proud a nacteme z nej data NetworkStream *clientstream = client->getstream(); StreamReader *reader = } new StreamReader(clientStream); String *content = reader->readtoend();
UDPClient zapouzdřuje kompletní UDP komunikaci; využívají jej obě strany zajímavé metody int Send(array<unsigned char>^ data, int velikost) zašle druhému počítači UDP paket array<unsigned char>^ Receive( IPEndPoint^% remoteep) čeká na příchod a přijme UDP paket data vrátí v poli bytů vedlejší efekt je adresa, odkud paket přišel
void Connect(IPEndPoind^ remoteep) do vlastních datových struktur uloží adresu a port cíle (spojení se ale nerealizuje, je to UDP!)
Přístup k www Třída WebClient implementuje kompletní www klient s možností stahování dat, souborů umožňuje download a upload ve formě souborů z/na server download a upload dat (tj. do pole) přistupovat k datům na serveru přímo jako k souboru
WebClient zajímavé atributy BaseAddress URI adresa serveru zajímavé metody DownloadData, DownloadFile UploadData,UploadFile OpenRead, OpenWrite otevře stream ke vzdálenému souboru
Ukázka v C++ WebClient ^client = gcnew WebClient(); Console::Write("Zadejte URI (napr. ) : "); //nacteme URI String ^uri = Console::ReadLine(); Console::Write("Zadejte nazev stazeneho souboru (napr. C:/new.txt) :"); //nacteme kam se ma soubor ulozit String ^filename = Console::ReadLine();
try { //stahneme soubor client->downloadfile(uri, filename); Console::WriteLine("Soubor byl stazen."); } catch(webexception ex) { Console::WriteLine("Pri stahovani souboru } doslo k vyjimce ");
Poznámky pro třídy z.net má Microsoft speciální označení reference (^ místo &) třídy se dynamicky alokují pomocí gcnew na hromadě se správou paměti pomocí CLR s garbage collectorem
Další třídy pro práci v síti Uri práce s řetězcem URI (porovnání, parsing) IPAddress Dns GetHostEntry, Resolve WebRequest, WebResponse podle URI umí posílat/přijímat protokoly HTTP, HTTPS, FILE, FTP
Podpora v jiných jazycích podporu IP sítí mají i jiné jazyky, např. Python sockety HTTP, FTP, SMTP
Úkol Napište hru hádáníčísel jako síťovou hru. Klient zašle serveru požadavek na počátek hry. Server vygeneruje náhodnéčíslo. Klient zasílá hádanéčíslo zadávané uživatelem, server odpovídá, zda je číslo větší, menší nebo rovno hádanému. Navrhněte vlastní komunikační protokol. Umožněte předčasně ukončit hru ze strany klienta.