<div class="page"> <div class="cover text-center"> <img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo"> # Comunicació en xarxa <div class="text-end fit-content ms-auto my-3 mt-auto pt-3"> <p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p> <p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p> <p><strong>Curs:</strong> 2024/2025</p> </div> <div> <p class="fw-bold mb-0">Llicència: BY-NC-SA</p> <p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p> <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank"> <img class="mx-auto" src="/itb/images/license.png" alt="Licence"/> </a> </div><!--license--> </div><!--cover--> </div><!--page--> {:toc} ## Introducció L’objectiu principal de les xarxes és el d’interconnectar diversos dispositius per tal de compartir totalment o parcialment els seus recursos.{.box} Les __aplicacions distribuïdes__ són aquelles que s’executen en diversos dispositiu a la vegada. La __comunicació__ és un procés complex en el qual es produeix una transferència d’informació entre agents independents. La forma més clàssica de comunicar dispositius digitals és aplicant el model de __client-servidor__. El __servidor__ és un dispositiu que conté informació a compartir amb altres agents anomenats __clients__. Sovint les aplicacions treballen amb recursos al núvol o extreuen les dades d’un SGBD situat en un servidor remot. Gràcies a la connectivitat dels nostres dispositius podem veure pel·lícules sense haver d’emmagatzemar-les en un disc local, podem sincronitzar els rellotges amb l’hora oficial, comprar entrades per anar al teatre sense moure’ns de casa o fer una partida en línia del nostre videojoc preferit. Tota aquesta capacitat de comunicació només és possible gràcies a les xarxes. ## Comuniació entre aplicacions Als sistemes distribuïts, les aplicacions es comuniquen entre si per aconseguir un objectiu. Per exemple, quan visitem una pàgina web el navegador del nostre equip es comunica amb el servei http del servidor web. Es produeix un procés comunicatiu que involucra una sèrie d'elements fonamentals que cal tenir presents: ![](/itb/DAM-PSP/UD3/img/canal.png){.center} - __Emissor__: aplicació que envia el missatge. - __Receptor__: aplicació que rep el missatge. - __Missatge__: la informació a transmetre. - __Paquet__: el missatge es dividirà en trossos més petits abans de ser enviat. Aquests trossos són la unitat bàsica dinformació i sels anomena paquet. - __Canal__: és el medi físic pel qual es transmeten els missatges i és el que connecta al receptor ia l'emissor. - __Protocol__: conjunt de regles que fixen el comportament a l'hora d'enviar un missatge. En un protocol es defineixen tant el format dels missatges com la manera d'enviar-los. Generalment durant una transmissió d'informació l'emissor i el receptor canvien de funció per compartir informació en els dos sentits. ## Protocols de comunicació: IP, TCP i UDP ![](/itb/DAM-PSP/UD3/img/capes.png){.center} A les xarxes d'ordinadors i internet, la pila de protocols usada és __TCP/IP__, aquest nom ve dels dos protocols més importants que la componen. Quan es va definir l'estàndard de protocols de comunicacions __OSI__, es van crear les capes de sessió i transport, que a TCP/IP es troben dins de la capa aplicació. ### Funcionament de la pila de protocols Les aplicacions que es comuniquen es troben al nivell superior, __capa d'aplicació__, tant de l'emissor com del receptor. L'aplicació crea el missatge que cal transmetre, que es passa a la capa següent. A la __capa transport__ se separa el missatge en paquets i aquests es passen a la capa següent. A la __capa de xarxa__ es calcula la ruta que seguiran els paquets per la xarxa per arribar a la destinació, sigua final o intermitja, que conega com arribar al receptor. Amb aquesta informació, els paquets es passen a la següent capa. A la __capa nivell__ es preparen els datagrames per al canal de comunicació que s'utilitzarà i es passa el paquet al següent nivell que és el canal. Una vegada els datagrames arriben al receptor, es produeix el procés invers. ### TCP **T**ransmission**C**ontrol**P**rotocol és un protocol de la capa de transport: - Garanteix que les dades no es perden, sempre que la comunicació siga possible. - Garanteix que els missatges arriben en ordre, sempre que la comunicació siga possible. - És __orientat a connexió__. Això significa que la connexió està activa mentre s'envien els missatges i segueix activa fins que l'emissor o receptor la tanquen. ### UDP **U**ser**D**atagram**P**rotocol és un protocol de la capa de transport: - No garanteix que els missatges arriben. - No garanteix que els missatges arriben. - Permet enviar com a màxim 64KB per missatge. - __No__ és orientat a connexió. Això ho converteix en un protocol més ràpid que TCP. - Els paquets en UDP se'ls coneix com a datagrames. ## Sockets Els __sockets__ van aparèixer l'any 1981, a la versió 4.2 d'UNIX BSD. Des d'aleshores, s'han convertit en el mecanisme estàndard de comunicació entre processos distribuïts a la majoria d'entorns. Actualment, la majoria de llenguatges d'alt nivell ofereixen interfícies de programació per a sockets. Els sockets permeten fer transferències d'informació entre aplicacions oferint abstracció sobre la pila de protocols. En anglès socket significa literalment _endoll_ i representa l'extrem d'un canal de comunicació establert entre emissor i receptor. Les dos aplicacions, l'emissor i el receptor respectivament, han de crear els seus propis sockets i connectar-los entre si. Una vegada connectats, els sockets creen una "canonada privada", on les aplicacions __escriuen__ (_write_) al socket per enviar informació i __llegeixen__ (_read_) per rebre'n. ### Adreces i ports Igual que amb una comunicació tradicional, com és l'enviament de cartes per correu on l'emissor ha de conèixer l'adreça exacta del receptor (carrer, número, porta, codi postal, país), en els sistemes distribuïts les aplicacions han de saber on estan ubicades entre si per poder enviar missatges. En el protocol TCP/IP s'usen les __adreces IP__ assignades a cada equip a la xarxa. Es possible que en una mateixa màquina amb adreça IP pròpia hi haja diverses aplicacions funcionant que utilitzen sockets per communicar-se. Per distingir-les, s'usen els ports. Un __port__ és un número entre 0 i 65535 que identifica cada socket a la màquina. Quan es crea un socket cal especificar el número de port. Normalment se sol dir que un socket __escolta__ (_listen_) un port. ### Tipus de sockets Hi ha dos tipus bàsics de sockets: - __Stream socket__ - __Datagram socket__ #### Stream socket Són sockets orientats a connexió. Si s'utilitzen sobre IP, ho faran mitjançant el protocol TCP, oferint totes les característiques d'aquest protocol. Un socket stream s'utilitza per comunicar-se sempre amb el mateix receptor, mantenint el canal obert fins que finalitza la connexió. Per establir la connexió mitjançant un socket stream s'han de seguir una sèrie de passos tant a l'emissor com al receptor. Un farà el paper de __procés servidor__ i l'altre el paper de __procés client__. El servidor serà el primer a crear el socket i esperarà que el client es connecte. El client crearà el seu socket i es connectarà al servidor creant el canal de comunicació. En qualsevol moment algun dels dos processos pot tancar el socket, destruint el canal i acabant la connexió. ##### Client - __Creació del socket__: Es crea i assigna un port. Generalment el port al client no és important així que es deixa que el sistema ho assigne automàticament. - __Connexió del socket (connect)__: Es localitza el socket del servidor mitjançant l'adreça IP del servidor i el port i es crea el canal. - __Enviament i recepció de missatges__: Mitjançant operacions de lectura i escriptura (read i write) s'envia i rep informació. - __Tancament de la connexió (close)__: El client pot tancar la connexió. ##### Servidor - __Creació del socket__: Es crea el socket de la mateixa manera que al client, però en aquest cas és important assignar el port. Mitjançant l'operació __bind__ es realitza aquesta assignació. - __Escolta (listen)__: Es configura el socket perquè quede preparat per acceptar connexions des del client. - __Acceptació de connexions (accept)__: Quan arriba una petició de connexió al servidor, es crea un nou socket i aquest serà el que quedarà connectat al socket client i pel qual s'enviarà i rebrà la informació. El socket servidor quedarà lliure escoltant, a l'espera de noves connexions. - __Enviament i recepció de missatges__: Mitjançant operacions de lectura i escriptura (read i write) s'envia i rep informació. - __Tancament de la connexió (close)__: El servidor pot tancar la connexió. El socket servidor continuarà escoltant com s'ha indicat anteriorment. #### Datagram socket Són sockets __no__ orientats a connexió. Si es fan servir sobre IP, ho faran mitjançant el protocol UDP, oferint totes les característiques d'aquest protocol. Un datagram socket s'utilitza per enviar missatges a múltiples receptors ja que es fa servir un canal temporal per a cada enviament. Amb aquests sockets no hi ha distinció entre client i servidor, totes les aplicacions usen sockets datagram. - __Creació del socket__: Es crearà el socket de la mateixa manera que al servidor amb els sockets stream. - __Enviament i recepció de missatges__: Mitjançant operacions enviar (send) i rebre (receive) s'enviaran els datagrames. L'operació send necessita una adreça IP i un port per enviar el datagrama. - __Tancament de la connexió (close)__: Es pot tancar la connexió. ## Programació de Sockets la majoria de llenguatges de programació d'alt nivell disposen de llibreries per crear, destruir i operar amb sockets sobre TCP/IP. A __Java__ els podem trobar al package __java.net__ i tenim les següents classes: - [__`java.net.Socket`__](https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html): Per crear sockets que actuen com a clients. - [__`java.net.ServerSocket`__](https://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html): Per crear sockets que actuen com a servidor. - __java.net.DatagramSocket__: Per crear sockets que treballen amb el protocol __UDP__. ### Classe Socket Els mètodes més importants de la classe [__`Socket`__](https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html) són: - `Socket()`: Constructor de la classe `Socket` desconnectat. - `Socket(String host, int port)`: Constructor de la classe `Socket` que es connecta a l'addreça IP i el port especificat. - `connect(SocketAddress endpoint)`: Connecta el `Socket` al `endpoint` especificat. - `getInputStream()`: Obté el `InputStream` que permet llegir del `Socket`. - `getOutputStream()`: Obté el `OutputStream` que permet escriure al `Socket`. - `close()`: Acaba la connexió i tanca el `Socket`. ### Classe ServerSocket Els mètodes més importants de la classe [__`ServerSocket`__](https://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html) són: - `ServerSocket()`: Constructor de la classe `Socket` que no està lligat a cap port. - `ServerSocket(int port)`: Constructor de la classe `Socket` que no està lligat al port especificat. - `bind(SocketAddress endpoint)`: Lliga el `ServerSocket` al `endpoint` especificat. - `accept()`: Espera a rebre una nova connexió i l'accepta. Aquest mètode retorna un `Socket` per communicar-se amb el client. - `close()`: Acaba la connexió i tanca el `ServerSocket`. ## Exemples - [__Exemple de creació d'una estructura client-servidor en Sockets__](/itb/DAM-PSP/UD3/examples/01_creacio_sockets.html) - [__Exemple servidor multiclient en Sockets__](/itb/DAM-PSP/UD3/examples/02_multiclient.html)