240 likes | 349 Views
Christophe Fontano Julien Alagnou. Socket & Multithreading en Java. Socket. Cliente. Connexions. ServerSocket. Servidor. Socket - presentacion. Package java.net, 5 clases importantes: InetAddress Socket ServerSocket DatagramSocket DatagramPacket 2 tipos de conexi ó n:
E N D
Christophe Fontano Julien Alagnou Socket& Multithreading en Java
Socket Cliente Connexions ServerSocket Servidor Socket - presentacion • Package java.net, 5 clases importantes: • InetAddress • Socket • ServerSocket • DatagramSocket • DatagramPacket • 2 tipos de conexión: • Orientado a conexión • camino virtual entre servidor y cliente, sin pérdidas de información ni duplicados, la información es recibida en el mismo orden. • El cliente abre una sesión en el servidor y este guarda un estado del cliente.
DatagramPacket sender DatagramSocket receiver DatagramSocket Socket - presentacion • No orientado a conexión • Envío de datagramas de tamaño fijo. No es fiable, puede haber pérdidas de información y duplicados, y la información puede llegar en distinto orden del que se envía. • No se guarda ningún estado del cliente en el servidor, por ello, es más tolerante a fallos del sistema.
Socket - classe InetAddress • Obtener una InetAddress • public staticInetAdress getByName(String hostName) • public staticInetAdress getByAddress(byte[] addr) • public staticInetAdress getByAddress(String host, byte[] addr) • public staticInetAdress getLocalHost() • ex: para Solfoc.fib.upc.es 147.83.41.34 • hostName = “Solfoc.fib.upc.es” • addr[0]=147 addr[1]=83 addr[2]=41 addr[3]=34 • Servicios • public byte[] getAddress () • devuelve addr[0]=147 addr[1]=83 addr[2]=41 addr[3]=34 • public String getHostAddress () • devuelve “147.83.41.34” • public String getHostName () • devuelve “Solfoc.fib.upc.es”
Socket - classe Socket : constructores • Tcp: utilización de flujos de datos Java: • clase InputStream • clase OutputStream • Constructores • Socket(InetAdress address, int port) • Socket(InetAdress address, int port, InetAdress localAddr, int localPort) • Socket(String host, int port) • Socket(String host, int port, InetAdress localAddr, int localPort) • address, host, port: caracteristicas del servidor
Socket - classe Socket • Métodos de información del socket • InetAddress getInetAddress () Devuelve la InetAddress del servidor. • InetAddress getLocalAddress () Devuelve la InetAdress del cliente. • int getLocalPort () Devuelve el puerto local utlizado por el socket. • int getPort () Devuelve el puerto del servidor .
Socket - classe ServerSocket • Constructores • ServerSocket (int port) • ServerSocket (int port, int backlog) • ServerSocket (int port, int backlog, InetAddress bindAddr) • Métodos de comunicación • Socket accept () espera una conexión sobre el ServerSocket • void close ()
Socket - classe ServerSocket • Mètodos de información del socket • InetAddress getInetAddress () Devuelve la InetAdress del servidor. • int getLocalPort () Devuelve el puerto del servidor utlizado por el socket. • void setSoTimeout(int timeout) • 0 : accept bloqueando. • N (<>0): accept bloqueara durante n milisegundos • int getSoTimeout () Devuelve la corriente timeout
Socket - Ejemplo de servidor Server(){ ServerSocket listen=null; Socket service=null; try{ listen=new ServerSocket(5432,5); while(true){ service=listen.accept(); OutputStream os=service.getOutputStream(); InputStream is=service.getInputStream(); os.write(is.read()); service.close(); } } catch(Exception e){e.printStackTrace();} }
Socket - Ejemplo de cliente Client(){ Socket mySock=null; try{ mySock=new Socket(InetAddress.getLocalHost(),5432); OutputStream os=mySock.getOutputStream(); InputStream is=mySock.getInputStream(); os.write((int)'a'); System.out.println("receive:"+is.read()); mySock.close(); } catch(Exception e){e.printStackTrace();} }
Socket - classe DatagramSocket • UDP: Utilización de paquetes de datos para la comunicación • clase DatagramPacket • Constructores • DatagramSocket () • DatagramSocket (int port) • DatagramSocket (int port, InetAddress laddr) • Mètodos de comunicación • void receive (DatagramPacket p) • void send (DatagramPacket p) • void close ()
Socket - classe DatagramSocket • Mètodos de información del socket • InetAddress getLocalAddress () Devuelve la direccion al cual el socket ha hecho el bind. • int getLocalPort () Devuelve el puerto al cual el socket ha hecho el bind. • void setSoTimeout (int timeout) • 0: receive bloqueando. • N (n<>0): receive bloqueara durante n milisegundos • int getSoTimeout () Devuelve la corriente timeout
Socket - classe DatagramPacket • Constructores: • public DatagramPacket (byte[] buff, int length) • Construye un DatagramPacket para recibir paquetes en el buffer buff, de longitud length • public DatagramPacket (byte[] buff, int length, InetAddress address, int port) • Construye un DatagramPacket para enviar paquetes con datos del buffer buff, de longitud length, a la @IP address y el puerto port. • Servicios: • Para la manipulación de los diferentes campos de un DatagramPacket disponemos de los siguientes métodos: • set/getAddress • set/getData • set/getLength • set/getPort
Socket - Ejemplo sender receiver Sender(){ InetAddress address=InetAddress.getLocalHost(); String mess="message to send"; int messlength=mess.length(); byte[]message=new byte[messlength]; mess.getBytes(0,messlength,message,0); DatagramPacket packet=new DatagramPacket(message,messlength,address,4321); DatagramSocket sock=new DatagramSocket(); sock.send(packet); } Receiver(){ byte []buffer=new byte[1024]; String mess; DatagramPacket packet=new DatagramPacket(buffer,buffer.length); DatagramSocket sock=new DatagramSocket(4321); while(true){ sock.receive(packet); mess=new String(buffer,0,0npacket.getLength()); System.out.println("Packet receive: message="+mess+ "-sender="+packet.getAdress.getHostName()+"port="+packet.getPort()); } }
Thread - Atributos de un thread en JAVA • Un thread es un objeto Java que tiene: • Nombre • Prioridad • Ha de seguir la siguiente relación • MIN_PRIORITY=1 <= Prioridad <= MAX_PRIORITY = 10 • La prioridad por defecto es NORM_PRIORITY = 5 • se puede crear un Thread de 2 maneras: • extender la clase Thread y override el metodo run() • implementar la interfaz Runnable
Thread - la interfaz Runnable • Esta interfaz define solamente un método: run() • public void run() • “start” el Thread provocara la llamada de este método. • Cada objeto que intenta ejecutar un thread debe implementar la interfaz Runnable.
Thread - la clase Thread • La classe Thread implementa esta interfaz y define un thread que no hace nada. • Cuando se crea un thread no se pone en marcha, se lo hemos de indicar explícitamente por una llamada al método start(). • Constructores • public Thread () • public Thread (String name) • public Thread (Runnable target) • public Thread (Runnable target, String name) • name: nombre del Thread target: implementacion de una classe que define el metodo run()
Thread - Scheduling • void run() • Es el método que ejecutará un thread cuando este se ponga en marcha. • void start() • Inicia la ejecución del thread.Provoca la ejecucion de run(). • void join() • Espera a que un thread termine su ejecución. • Podemos especificar el tiempo de espera máximo. • void sleep(long milis) • Bloquea el thread milis milisegundos. • Hay otro parámetro que permite afinar más el tiempo de bloqueo en nanosegundos • void stop/destroy() • Destruye el thread sin eliminar estructuras, esto es tarea del método join.
Thread - Servicios generales de la clase Thread • public String getName() • Devuelve el nombre que identifica al thread. • public String setName(String name) • Cambia el nombre del thread. • public int getPriority() • Devuelve la prioridad del thread. • public void setPriority (int newPriority) • Cambia la prioridad del thread • static Thread currentThread() • Devuelve el thread que se está ejecutando actualmente. • boolean isAlive() • true si el Thread esta ejecutando, false si no.
Thread - Ejemplo public class Clock extendsAppletimplementsRunnable{ privateThread clockThread = null; publicvoid start() { if (clockThread == null) {//create Thread using this runnable clockThread = new Thread(this, "Clock"); clockThread.start(); } } public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try {//wait 1 second before refresh Thread.sleep(1000); }catch (InterruptedException e){ // the VM doesn't want us to sleep anymore } } } public void paint(Graphics g) { // get the time and convert it to a date Date date = Calendar.getInstance().getTime(); g.drawString(DateFormat.getTimeInstance().format(date),5,10); } //overrides Apllet ’s stop method publicvoid stop() { clockThread = null; } }
Thread - Sincronización • Ejemplo de problema : Acceso a una variable global • se solucionaría de la siguiente forma: synchronized (this) { x++; } (this es la clase que contiene la variable global) • Con esto se garantiza el acceso en exclusión mutua a la variable.
Thread - Sincronización(I) • Acceso a un método en exclusión mutua : tenemos las siguientes opciones • Igual que el ejemplo anterior : synchronized (this) { this.setValue(8); } • Declarando el método como sincronizado: • los metodos set() y get() seran ejecutados en exclusión mutua public class VarGlobal{ int valorCompartida=123; public synchronized int get(){ return valorCompartida; } public synchronized void set(int v){ valorCompartida=v; } }
Thread - Sincronización (II) • También se pueden sincronizar varios threads mediante los monitores, utilizando los métodos: • wait() espera que otro Thread llama notify() o notifyAll() • notify() despierta uno sólo Thread que espera en este monitor. • notifyAll() despierta todos los Thread que espera en este monitor. • Ejemplo de un monitor:
Thread - Sincronización (III) - monitor public class ProductorConsumer { private int value; private boolean valueAvailable = false; public synchronized int get() { int ret; while (valueAvailable == false) { try { wait(); } catch (InterruptedException e) { } } valueAvailable = false; ret =value; notifyAll(); return ret; } public synchronized void put(int val) { while (valueAvailable == true) { try { wait(); }catch (InterruptedException e) { } } value = val; valueAvailable = true; notifyAll(); } }