350 likes | 548 Views
Sockets. i. Threads. Lorena Alvarez Montiel – D8854711 Jordi Brínquez Jiménez – E6334930 Jonathan Lafuente Castillo – D8105261. en JAVA. Sockets i threads en JAVA. Sockets: Classe InetAddress. Classe Socket. Classe ServerSocket. Classe DatagramSocket. Threads:
E N D
Sockets i Threads Lorena Alvarez Montiel – D8854711 Jordi Brínquez Jiménez – E6334930 Jonathan Lafuente Castillo – D8105261 en JAVA
Sockets i threads en JAVA • Sockets: • Classe InetAddress. • Classe Socket. • Classe ServerSocket. • Classe DatagramSocket. • Threads: • Què són els Threads i per què serveixen. • Classe Thread • Classe ThreadGroup. • Sockets i Threads en JAVA: • Un exemple.
InetAddress : Aquesta classe conté les funcions que s’utilitzen per resoldre noms en @ IP i viceversa. Operacions byte[] getAddress () Retorna l'adreça IP d'aquest objecte. static InetAddress getByName (String host) Determina (resol) l'adreça IP del host especificat. String getHostAddress () Retorna l'adreça IP amb la forma xxx.xxx.xxx.xxx String getHostName () Retorna el nom del host per aquesta adreça IP. static InetAddress getLocalHost () Retorna el nom del host local. String toString () Converteix l'adreça IP en una cadena.
Socket : • Un socket és un punt final de comunicació. • Les aplicacions client/servidor fan servir aquests mecanisme per comunicar-se entre ells. • Depenent del tipus de connexió es farà servir : • Orientat a connexió : • La classe Socket (per al client) i ServerSocket (per al servidor). • Orientat a no-connexió : • La classe DatagramSocket (tant pel client com pel servidor).
Socket : Operacions constructores Socket () Crea un socket sense connectar. Socket (InetAddress address, int port) Crea un socket i el connecta a l'adreça address i al port port. Socket (String host, int port) Crea un socket i el connecta al host host i al port port. Socket (InetAddress address, int port, InetAddress localAddr, int localPort) Crea un socket i el connecta a l'adreça i port remots (address, port) amb l'adreça i port locals localAddr, localPort). Socket (String host, int port, InetAddress localAddr, int localPort) Idem que l'anterior pero el host ve donat com un String.
Socket : Mètodes de informació del socket InetAddress getInetAddress () Retorna l'adreça a la que el socket esta connectat. InetAddress getLocalAddress () Recupera l'adreça local on el socket està connectat. int getLocalPort () Retorna el port locat on el socket està connectat. int getPort () Retorna el port remot on el socket està connectat. String toString () Converteix aquest en una cadena que el representa.
Socket : Mètodes de comunicació void close () Tanca el socket. InputStream getInputStream () Retorna un input stream per aquest socket. OutputStream getOutputStream () Retorna un output stream per aquest socket. Mètodes d'opcions del socket int getSoTimeout () Retorna la configuració del timeout. void setSoTimeout (int timeout) Activa/desactiva el timeout d'aquest socket. El temps està en milisegons.
ServerSocket : Constructores ServerSocket (int port) Crea un server socket en el port especificat. ServerSocket (int port, int backlog) Crea un server socket en el port especificat, fa el bind i accepta fins a backlog clients. ServerSocket (int port, int backlog, InetAddress bindAddr) Crea un server socket en el port especificat, fa el bind a l'adreça bindAddr i accepta fins a backlog clients. Mètodes de comunicació Socket accept () Escolta el socket esperant connexions i les acepta. void close () Tanca el socket.
ServerSocket : Mètodes de informació del socket InetAddress getInetAddress () Retorna l'adreça del server socket. int getLocalPort () Retorna el port en el que el socket està escoltant. int getSoTimeout () Retorna la configuració del timeout. void setSoTimeout (int timeout) Activa/desactiva el timeout d'aquest socket. El temps està en milisegons. String toString () Converteix aquest en una cadena que el representa.
DatagramSocket : Constructores DatagramSocket () Crea un datagram socket i fa un bind a qualsevol port disponible en la màquina local. DatagramSocket (int port) Crea un datagram socket i fa un bind al port especificat de la màquina local. DatagramSocket (int port, InetAddress laddr) Crea un datagram socket, associat a l'adreça local especificada. Mètodes de comunicació void close () Tanca el datagram socket. void connect (InetAddress address, int port) Connecta el socket a l'adreça remota. void disconnect () Tanca el socket. void receive (DatagramPacket p) Reb un paquet de datagram des del socket. void send (DatagramPacket p) Envia un paquet de datagram pel socket.
DatagramSocket : Mètodes de informació del socket InetAddress getInetAddress () Retorna l'adreça a la qual el socket està connectat. InetAddress getLocalAddress () Retorna l'adreça local a la qual el socket està associat. int getLocalPort () Retorna el port d'on escolta el socket. int getPort () Retorna el port del socket. int getSoTimeout () Retorna la configuració del timeout. void setSoTimeout (int timeout) Activa/desactiva el timeout d'aquest socket. El temps està en milisegons.
Què són els Threads i per què serveixen. Un thread és un flux d’execució d’un programa, és a dir unes instruccións que s’executen de forma continuada, un PC i un SP. Els threads es fan servir per aprofitar el paral·lelísme i la concurrència que els ordinadors multiprocessador poden oferir, així com també facilitar la programació (per exemple, el FTP fet al laboratori). El gran aventatge que tenen respecte dels processos és que permeten canvis de context (de thread) de forma menys costosa que si fossin diferents processos.
Thread : Operacions constructores Thread () Crea un nou objecte de tipus Thread . Thread (Runnable target) Crea un nou objecte target de tipus Thread. Thread (Runnable target, String name) Crea un nou objecte target de tipus Thread amb nom name. Thread (String name) Crea un nou objecte de tipus Thread de nom name. Thread (ThreadGroup group, Runnable target) Crea un nou objecte target de tipus Thread dins d'un ThreadGroup anomenat group. Thread (ThreadGroup group, Runnable target, String name) Crea un nou objecte target de tipus Thread amb nom name dins d'un ThreadGroup anomenat group. Thread (ThreadGroup group, String name) Crea un nou objecte de tipus Thread amb nom name dins d'un ThreadGroup anomenat group.
Thread : Mètodes relacionats amb les propietats String getName () Retorna el nom del thread. int getPriority () Retorna la prioritat del thread. ThreadGroup getThreadGroup () Retorna el grup de threads al qual pertany. void setName (String name) Cambia el nom del thread. void setPriority (int newPriority) Cambia la prioritat del thread. Valors de la prioritat static int MAX_PRIORITY static int MIN_PRIORITY static int NORM_PRIORITY
Thread : Mètodes relacionats amb l'estat void destroy () Destrueix el thread, sense alliberar memòria. boolean isAlive () Comproba que el thread estigui viu. void join () Espera fins que el thread mor. void join (long millis) Espera com a molt millis milisegons fins que el thread mor. void join (long millis, int nanos) Espera com a molt millis milisegons i nanos nanosegons fins que el thread mor. void run () Comença l'execució d'un thread. static void sleep (long millis) Adorm el thread durant millis milisegons. static void sleep (long millis, int nanos) Adorm el thread durant millis milisegons i nanos nanosegons. void start () Engega l'execució del thread. static void yield () Para l'execució del thread actual i permet a altres threads la seva execució.
Thread : Mètodes relacionats amb les interrupcions void interrupt () Interrumpeix el thread. static boolean interrupted () Comproba si el trheat ha estat instarromput i borra el contingut de la variable d'estat. boolean isInterrupted () Comproba si el trheat ha estat instarromput. Mètodes relacionats amb el thread actual static int activeCount () Retorna el nombre de threads actius en aquests grup de threads. static Thread currentThread () Returna una referència al thread que s'està executant. static int enumerate (Thread[] tarray) Copia al vector tarray els threads actius en del seu grup i dels subgrups que el componen. Mètode descriptor String toString () Retorna una cadena que representa al thread, aquesta inclou el nom, la prioritat i el grup.
ThreadGroup : Operacions constructores ThreadGroup (String name) Construeix un nou grup de threads de nom name. ThreadGroup (ThreadGroup parent, String name) Construeix un nou grup de threads de nom name dintre del grup parent. Mètodes relacionats amb les propietats int getMaxPriority () Retorna la màxima prioritat del grup de threads. String getName () Retorna el nom del grup de threads. ThreadGroup getParent () Returns el grup pare d'aquest grup. void setMaxPriority (int pri) Cambia la prioritat dels elements del grup a la màxima possible.
ThreadGroup : Mètodes relacionats amb l'estat del grup int activeCount () Retorna una estimació del nombre de threads actius en aquest grup. int activeGroupCount () Retorna una estimació del nombre de grups actius en aquest grup. int enumerate (Thread[] list) Copia a la llista els threads actius d'aquest grup i dels seus subgrups. int enumerate (Thread[] list, boolean recurse) Copia a la llista els threads actius d'aquest grup i en cas que recurse valgui cert també dels seus subgrups. int enumerate (ThreadGroup[] list) Copia a la llista els subgrups actius d'aquest grup. int enumerate (ThreadGroup[] list, boolean recurse) Copia a la llista els subgrups actius d'aquest grup i en cas que recurse valgui cert també dels seus subgrups. boolean isDestroyed () comproba si el grup de threads ha estat destuït. void list () Llista per pantalla informació sobre el grup.
ThreadGroup : Mètodes relacionats amb l'estat d'un grup de threads void destroy () Destrueix el grup i tots els seus subgrups. Mètodes relacionats amb la seguretat void checkAccess () Comproba si el thread en execució té permís per modificar aquest grup de threads. Mètodes relacionats amb les interrupcions void interrupt () Interromp tots els threads en aquest grup. Mètode descriptor String toString () Retorna una cadena que representa al grup de threads.
Seminari de CASO: Sockets i Threads en JAVA Exemple d’ús
Explicació de l’exemple • Tenim diversos processos que accedeixen a un vector circular concurrentment: uns processos llegint del vector i els altres escrivint-hi. • Quan es creen aquests processos, es connecten amb un servidor (de lectura o escriptura) que crea un thread i un socket per atendre'ls.
Thread d'escriptor Thread de lector Vector circular Lector Escriptor Servidor de lectors Servidor d'escriptors Explicació de l’exemple
Codi de l’escriptor public class Emisor{ publicstaticvoid main(String[] args)throwsIOException{ OutputStream skout; DataOutputStream dos; Socket sk = null; sk = newSocket("127.0.0.1",5502);//petició al servidor d’escriptors try{ skout = sk.getOutputStream(); dos = newDataOutputStream(skout); String missat = LlegirTeclat.LlegirLinea(); //Llegeixo de teclat while (missat.length() > 1){ dos.writeUTF(missat); missat = LlegirTeclat.LlegirLinea();} dos.writeUTF(missat); dos.close(); skout.close(); sk.close();} catch (IOException e){}}}
Codi del thread d’escriptor (I) publicclass EscriuPar extendsThread{ private CuaString cua; //vector compartit per tots els processos privateSocket sk; //socket per comunicar-se amb l’escriptor que atén public EscriuPar(CuaString h, Socket soc) {//constructora del thread cua = h; sk = soc;} publicvoid run() {//mètode que s’executa en fer start InputStream skin; DataInputStream dis; try{ skin = sk.getInputStream(); dis = newDataInputStream(skin); String st = newString (dis.readUTF()); //lectura del socket try{ cua.SetString(st);} //escriptura al vector catch(InterruptedException e){}
Codi del thread d’escriptor (II) while (st.length() > 0){//adormim el proces try{ sleep((int)(Math.random()*3000));} catch(InterruptedException e){} st = dis.readUTF(); try{cua.SetString(st);} catch(InterruptedException e){}} dis.close();//tanquem els canals skin.close(); sk.close();} catch(IOException e){}}}
Codi del lector publicclass Receptor{ publicstaticvoid main(String[] args)throwsIOException{ Socket sk = null; InputStream skin; DataInputStream dis; sk = newSocket("127.0.0.1", 5503);//petició al servidor de lectors. skin = sk.getInputStream(); dis = newDataInputStream(skin);//tenim una sortida de dades String st = newString (dis.readUTF()); //comencem a llegir System.out.println(st); // i a escriure per pantalla while (st.length() > 0){ st = dis.readUTF(); System.out.println(st);} dis.close(); //tanquem els canals oberts. skin.close(); sk.close();}}
Codi del thread de lector (I) class LlegeixPar extendsThread{ private CuaString cua;//vector compartit per tots els processos privateSocket sk;//socket per atendre el seu clien public LlegeixPar(CuaString h, Socket s){ //constructora cua = h; //valor inicial sk = s;} publicvoid run(){ OutputStream skout; DataOutputStream dos; try { skout = sk.getOutputStream(); dos = newDataOutputStream(skout);//tenim una entrada de dades String missat=""; try{missat = cua.GetString();}//llegim del vector catch(InterruptedException e){}
Codi del thread de lector (II) while (missat.length() > 1){ dos.writeUTF(missat); //escrivim al socket try{sleep((int)(Math.random()*3000));} //adormim el procés catch (InterruptedException e){} try{missat = cua.GetString(); } catch(InterruptedException e){}} dos.writeUTF(missat); dos.close(); skout.close(); sk.close();} catch (IOException e){}}}
Codi del servidor publicclass Servidors { publicstaticvoid main (String[] args) { CuaString cua = new CuaString(5); //creem el vector a compartir ServEscrip serE = new ServEscrip(cua); //creem el servidor escriptors serE.start(); //el posem en funcionament ServLec serL = new ServLec(cua); //creem el servidor de lectors serL.start(); //el posem en funcionament } } Els servidors de lectors i escriptors són dos threads perquè comparteixin el mateix vector.
Codi del servidor d’escriptors class ServEscrip extendsThread{ private CuaString cua; //vector compartit per tots els processos. staticint maxim = 2; //màxim de clients que acceptarem. public ServEscrip(CuaString c){//constructora cua = c;} publicvoid run (){ ServerSocket ss = null; Socket sk = null; int i = 0; try{ ss = newServerSocket(5502); //creem el ServerSocket per acceptar while (i < maxim){ // peticions dels clients sk = ss.accept(); //acceptem el client EscriuPar esc = new EscriuPar(cua, sk); //creem el thead per esc.start(); // atendre’l i el posem en funcionament. i++;}} catch (IOException e){}}}
Codi del servidor de lectors class ServLec extendsThread{ private CuaString cua;//vector compartit per tots staticint maxim = 2; // màxim de client per atendre public ServLec(CuaString c){ //constructora cua = c;} publicvoid run (){ ServerSocket ss = null; Socket sk = null; int i = 0; try{ ss = newServerSocket(5503); //Creem el ServerSocket per atendre while (i < maxim){ // les peticions dels lectors sk = ss.accept(); //acceptem la petició LlegeixPar lec = new LlegeixPar(cua, sk);//creem el thread per lec.start(); //atendre’l i el posem en funcionament. i++;}} catch (IOException e){}}}
Codi del vector (I) class CuaString { privateString[] cua; //cua de cadenes de caràcters; privateint p_llegit = 0; //apuntador al següent element a llegir; privateint p_escrit = 0; //apuntador al primer buit de la cua; privateint buits, plens; //nombre de pos. buides i ocupades de la cua; public CuaString(int n) //constructora { if (n < 1) n = 10; cua = newString[n]; buits = cua.length; plens = 0; }
Codi del vector (II) publicsynchronizedString GetString() throwsInterruptedException { while (plens == 0) { try { wait(); //Adormim el consumidor } catch(InterruptedException e){} } plens--; buits++; System.out.println("LECTOR: Llocs buits: " + buits + ", llocs plens: " + plens); String valor = cua[p_llegit]; p_llegit = (p_llegit + 1) % cua.length; notifyAll(); return valor; }
Codi del vector (III) publicsynchronizedvoid SetString(String val)throws InterruptedException { while (buits == 0) { try { wait(); } catch(InterruptedException e){} } buits--; plens++; System.out.println("ESCRIPTOR: Llocs buits: " + buits + ", llocs plens: " + plens); cua[p_escrit] = val; p_escrit = (p_escrit + 1) % cua.length; notifyAll(); //despertem tots els processos adormits per a que comprovin si poden continuar.}}
Bibliografia • The Java™ Class Libraries -- Second Edition – Volume 1 • Patrick Chan, Rosanna Lee, Douglas Kramer • Java 1.2 al descubierto • Jamie Jaworski, Ed. Prentice Hall • Java 2 -- Curso de programación • Francisco Javier Ceballos, Ed. Rama • http://java.sun.com • http://www.cybercursos.net (Java desde cero)