Vous êtes sur la page 1sur 40

Tema 3:

Interfaz de programación
en red: Los Sockets

Bibliografía:
● Kurose04, Apartados 2.1, 2.6, 2.7 y 2.8
● “El lenguaje de programación Java”, V. Alonso, M. Sánchez,
Redes: Tema 3 SPUPV-2003. Libro-Apunte nº 922, Capítulos 5, 6 y 7 1
Objetivos

Conocer:
● Qué interfaz ofrecen los sistemas operativos para
acceder a los servicios de red
● Cuál es la estructura básica de un cliente
● Cuál es la estructura básica de un servidor
● Cómo gestionar simultáneamente varios clientes

Redes: Tema 3 2
Índice

1. El modelo cliente-servidor
2. La abstracción de los sockets
3. Los sockets en Java
4. Sockets TCP
5. Sockets UDP
6. Servidores concurrentes
7. Ejemplos

Redes: Tema 3 3
1. El Modelo Cliente-Servidor

● Arquitectura de las aplicaciones en red



Cliente-servidor
● Los papeles de cada computador están claramente
diferenciados:
– Uno hace de cliente y el otro de servidor

Entre pares (P2P)
● Los computadores alternan el papel de cliente y de
servidor
● Sin embargo, para una transferencia determinada,
uno hace de cliente y el otro de servidor

Redes: Tema 3 4
Modelo Cliente-Servidor
Cuando dos procesos se comunican, siguen un
modelo cliente y servidor
1. Petición

cliente Internet servidor

2. Respuesta

Cliente: Servidor:
● Inicia la comunicación ● Espera peticiones
● Solicita un servicio al servidor ● Proporciona el servicio solicitado
● Ejemplo:
● Ejemplo:
● Un cliente web solicita una página
● El servidor web envía la página
solicitada por el cliente
● Un proceso P2P solicita un fichero a
otro proceso P2P
● El proceso P2P envía el fichero
solicitado por otro proceso P2P
Redes: Tema 3 5
Modelo cliente-servidor
● Los dos extremos dialogan siguiendo un protocolo
de aplicación

cliente Internet servidor

GET / HTTP/1.0
HTTP/1.0 200 OK
Content-type: text/html

<html> .... </html>

● Los RFC (Request For Comments) documentan los


protocolos de aplicación estándar
http://www.rfc-editor.org
Redes: Tema 3 6
Tipos de servidores

● Normalmente, un servidor debe estar preparado


para atender muchos clientes
● Se puede hacer de dos maneras:
● Secuencial: un cliente detrás de otro
● Concurrente: varios clientes al mismo tiempo

Redes: Tema 3 7
2. La abstracción de los sockets
● Clientes y servidores utilizan protocolos de transporte

Los procesos de las HTTP POP3


aplicaciones residen en
el espacio de usuario FTP DNS
API
Los procesos de los TCP UDP
protocolos de Red
transporte forman Enlace de datos
parte del S.O.
Físico

● Se necesita un mecanismo para ponerlos en contacto


● API (Application Programming Interface)

Redes: Tema 3 8
API socket
● Originalmente diseñado en BSD Unix
● Permite a las aplicaciones utilizar los protocolos de la
pila TCP/IP
● Define las operaciones HTTP POP3
permitidas y sus
argumentos FTP DNS
● Parecido a la forma de socket socket socket socket

acceder a los ficheros en Unix TCP UDP


● Operaciones: open, read, Red
write, close Enlace de datos
● Cuando se abre un fichero Físico
obtenemos un descriptor
● Es un estándar de facto
Redes: Tema 3 9
Socket
● Es una abstracción del sistema operativo (no Hw)
● Las aplicaciones los crean, los utilizan y los cierran cuando
ya no son necesarios
● Su funcionamiento está controlado por el sistema operativo
● Comunicación entre procesos
● Los procesos envían/reciben mensajes a través de su socket
● Los socket se comunican entre ellos

proceso proceso
socket socket
Transporte Transporte
Red Red
Enlace Enlace
Físico Internet Físico
Redes: Tema 3 10
Identificación de los sockets
● La comunicación en Internet es de socket a socket
● El proceso que está comunicándose se identifica por
medio de su socket
● El socket tiene un identificador
Identificador = dir. IP del computador + núm. puerto

cliente servidor IP:62.3.3.3


IP:128.1.1.1
socket socket
Puerto: 1245 Transporte Puerto: 80
Transporte
Red Red
Enlace Enlace
Físico Internet Físico

Redes: Tema 3 11
Tipos de sockets

Sockets TCP ● Sockets UDP
● Las aplicaciones piden al ● Las aplicaciones piden al
S.O. una comunicación S.O. una comunicación
controlada por TCP: controlada por UDP:
● Transferencia de bloques
● Orientada a la conexión
de datos
● Comunicación fiable y ● Sin conexión ni fiabilidad ni
ordenada entrega ordenada
Permite difusiones
También se denominan

sockets de tipo Stream


● También se denominan
sockets de tipo Datagrama

cliente servidor cliente servidor


socket socket socket socket
TCP TCP UDP UDP
bytes datagramas

Redes: Tema 3 12
3. Los sockets en Java

Dentro del paquete java.net existen tres clases de
sockets:

Socket Cliente TCP
● ServerSocket Servidor TCP
● DatagramSocket Cliente/Servidor UDP
● También hay otras clases auxiliares que facilitan la
programación de aplicaciones en red

http://java.sun.com/j2se/1.4.2/docs/api/index.html

Redes: Tema 3 13
Direcciones IP en Java
Clase InetAddress

InetAddress es la clase que se utiliza para
almacenar direcciones IP
● Algunos métodos
● InetAddress getByName(String nombre)
● Obtiene la dirección IP asociada a un nombre
● String getHostAddress()
● Devuelve la dirección IP en formato "aa.bb.cc.dd"
● String getHostName()
● Devuelve el nombre del host

Redes: Tema 3 14
4. Sockets TCP
● Cliente: ● Cuando un cliente se
● Inicia la conexión con el conecta con un servidor:
servidor ● El servidor crea un nuevo socket
● Especifica la dirección IP y el (2) para que el proceso servidor
puerto del proceso servidor se comunique con el cliente
● Cuando crea un socket ● De esta forma es posible que un
establece la conexión con el
servidor se comunique con
servidor
varios clientes simultáneamente
● Servidor:
● Ha de estar en ejecución
● Debe haber creado un socket
(1) donde recibir a los clientes socket
que conectan con él 1
● Espera a que algún cliente se cliente servidor
conecte
socket socket
cliente 2
bytes
Redes: Tema 3 15
Gestión de los flujos de entrada
● InputStream proporciona un flujo de bytes
● Se puede leer un byte: read()
● O un grupo de bytes: read(byte[] b)
● InputStreamReader convierte un flujo de bytes en un
flujo de caracteres
● Se puede leer un carácter: read()
● O un grupo de caracteres: read(char[] text)
● BufferedReader añade un buffer al flujo
caracteres buffer strings

● Se puede leer una línea de texto: String readLine()

Redes: Tema 3 16
Gestión de los flujos de salida

● OutputStream admite un flujo de bytes


● Se puede escribir un byte: write(int b)
● O un grupo de bytes: write(byte[] b)
● PrintWriter permite enviar texto (caracteres)
● Tiene métodos que permiten escribir una línea de texto:
print(String s) y println(String s)

líneas bytes

Redes: Tema 3 17
Clientes TCP
Clase Socket
● Constructores
● Socket(InetAdress dirIP, int puerto)
● Socket(String nombre, int puerto)
● Crea un socket y lo conecta con el servidor indicado
● Socket(InetAddress dirIP, int puerto,
InetAddress dirIPLocal, int puertoLocal)
● Socket(String nombre, int puerto,
InetAddress dirIPLocal, int puertoLocal)
● Crea un socket y lo conecta con el servidor indicado,
ligándolo a una dirección IP y puerto locales concretos

Redes: Tema 3 18
Clientes TCP
Clase Socket
● Algunos métodos importantes
● InputStream getInputStream()
● Proporciona un descriptor para leer del socket
● OutputStream getOutputStream()
● Proporciona un descriptor para escribir en el socket
● close()
● Cierra el socket

Redes: Tema 3 19
Cliente TCP básico
import java.net.*;
import java.io.*;

class ClienteTCP {

public static void main(String args[])


throws UnknownHostException, IOException {
Socket s=new Socket("zoltar.redes.upv.es",21);
BufferedReader in=new BufferedReader(new
InputStreamReader(s.getInputStream()));
System.out.println(in.readLine());
s.close();
}

● Este cliente se conecta al servidor FTP (puerto 21) y


visualiza la primera línea que recibe del servidor. Después
cierra la conexión
● Genera la siguiente salida:
220 (vsFTPd 1.2.1)

Redes: Tema 3 20
Segundo cliente TCP
import java.net.*;
import java.io.*;

class ClienteTCP2 {

public static void main(String args[]) throws UnknownHostException,IOException {


Socket s = new Socket("www.upv.es",80);
BufferedReader in =
new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
out.print("GET / HTTP/1.0" + "\r\n");
out.print("\r\n");
out.flush();
System.out.println(in.readLine());
s.close();
}

● Envía una petición HTTP al servidor www.upv.es


● Esta es la salida del programa:
HTTP/1.1 200 OK

Redes: Tema 3 21
Servidores TCP
Clase ServerSocket
● Constructores
● ServerSocket(int puerto)
● Abre un socket en el puerto indicado en modo de escucha
● Si port = 0, entonces se elige cualquier puerto libre
● ServerSocket(int puerto, int backlog)
● Abre un socket en el puerto indicado en modo de escucha
● backlog indica la longitud máxima de la cola de
conexiones en espera
● Cuando llega una solicitud de conexión y la cola está
llena, se rechaza la conexión

Redes: Tema 3 22
Servidores TCP
Clase ServerSocket
● Algunos métodos importantes
● Socket accept()
● Acepta una conexión de un cliente y devuelve un socket
asociado a ella
● El proceso se bloquea hasta que se realiza una conexión
● El diálogo con el cliente se hace por el nuevo socket
● El ServerSocket puede atender nuevas conexiones

● close()
● Cierra el socket servidor

Redes: Tema 3 23
Primer servidor TCP
import java.net.*;
import java.io.*;

class ServidorTCP {

public static void main(String args[]) throws UnknownHostException,IOException {


ServerSocket ss=new ServerSocket(7777);
Socket s=ss.accept(); // espero a que llegue un cliente
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
out.println("Bienvenido al servidor de prueba de Redes");
s.close();
ss.close();
}
}

● El servidor espera un cliente. Cuando éste se conecta, el


servidor le envía una cadena de bienvenida y acaba
zoltar:~/java> telnet localhost 7777
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Bienvenido al servidor de prueba de Redes
Connection closed by foreign host.

Redes: Tema 3 24
Segundo servidor TCP
import java.net.*;
import java.io.*;

class ServidorTCP2 {
public static void main(String args[]) throws UnknownHostException,IOException {
ServerSocket ss = new ServerSocket(7777);
int cliente=1;
while(true) {
Socket s = ss.accept(); // espera una conexión de un cliente
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
System.out.println("Eres el cliente " + cliente++);
s.close();
}
}
}

● Servidor iterativo: continúa atendiendo a nuevos


clientes
● A cada uno le envía una cadena con su número de cliente
y después cierra el socket

Redes: Tema 3 25
5. Sockets UDP

● Con UDP no se establece “conexión” entre cliente


y servidor
● El emisor indica explicitamente la dirección IP y el
puerto del origen y del destino en cada paquete
● El receptor ha de extraer del paquete recibido la
dirección IP y el puerto del emisor
● Los datos transmitidos pueden llegar fuera de
orden o incluso perderse

Redes: Tema 3 26
Comunicaciones UDP
Clase DatagramPacket
● Constructores
● DatagramPacket(byte buf[ ], int longitud)
● Crea un datagrama UDP a partir de ese buffer y con esa
longitud

● DatagramPacket(byte buf[ ], int longitud,


InetAddress dirIP, int puerto)
● Crea un datagrama UDP con ese buffer y de esa longitud
para enviarlo a la dirección IP y puerto que se indican

Redes: Tema 3 27
Comunicaciones UDP

Clase DatagramSocket
● Constructores
● DatagramSocket()
● Crea un socket UDP que escucha en un puerto libre
● DatagramSocket(int puerto)
● Crea un socket UDP que escucha en ese puerto

Redes: Tema 3 28
Comunicaciones UDP
Clase DatagramSocket
● Algunos métodos importantes
● send(DatagramPacket p)
● Envía un datagrama
● El DatagramPacket incluye los datos a enviar, su
longitud y la dirección IP y el puerto del destino
● receive(DatagramPacket p)
● Recibe datagramas. El método es bloqueante
● Cuando el método retorna, el buffer
DatagramPacket contiene los datos recibidos y la
dirección IP y puerto de quien envía el datagrama
● close()

Redes: Tema 3 29
Comunicaciones UDP
Clase DatagramPacket

Métodos
remoto

● getAddress( ) ● setAddress(InetAddress)
● getPort( ) ● setPort(int)
● getData( ) ● setData(byte[ ])
● getLength( ) ● setLength(int)

Redes: Tema 3 30
Cliente UDP
import java.net.*;
import java.io.*;

public class ClienteUDP{


public static void main(String[] args) throws IOException {
DatagramSocket s = new DatagramSocket();
InetAddress dir = InetAddress.getByName("zoltar.redes.upv.es");
String msg = "Hola, esto es un mensaje\n";
byte[] buf = new byte[256];
buf = msg.getBytes();
DatagramPacket p = new DatagramPacket(buf, buf.length, dir, 7777);
s.send(p);
s.receive(p); // se bloquea hasta que recibe un datagrama
System.out.write(p.getData());
s.close();
}
}

● El cliente envía un datagrama a un servidor e


imprime la respuesta

Redes: Tema 3 31
Servidor UDP
import java.net.*;
import java.io.*;

public class ServidorUDP{


public static void main(String[] args) throws IOException {
DatagramSocket s = new DatagramSocket(7777);
DatagramPacket p = new DatagramPacket(new byte[256], 256);
s.receive(p); // se bloquea hasta que recibe un datagrama
p.setAddress(p.getAddress());
p.setPort(p.getPort());
s.send(p);
s.close();
}
}

● Envía de vuelta el datagrama recibido, sin modificarlo, a


la dirección IP y puerto de origen
● Sólo procesa un cliente y acaba

Redes: Tema 3 32
6. Servidores concurrentes
En Java, la concurrencia la conseguimos
usando hilos de ejecución

Clase Thread
Ejemplo de uso:
● Se define una clase class Hilos extends Thread {
derivada de Thread int id;
public Hilos(int i) {id=i;}
public void run() {
● Código a ejecutar en for(int i=0;i<100;i++) {
cada hilo dentro del System.out.print(id);
try {sleep(100);}
método run() catch(InterruptedException e) {}
}
● Se lanza el hilo con }
start() public static void main(String args[]) {
for(int i=0;i<3;i++) new Hilos(i).start();
}
}

Redes: Tema 3 33
Servidores concurrentes
● Diversos hilos de ejecución:
● En el hilo principal se ejecuta permanentemente
el método accept()
● Espera el establecimiento de nuevas conexiones
● Para cada cliente que se conecta, se lanza un
nuevo hilo de ejecución para gestionar esa
conexión

Cliente 1 Maestro

Servidor 1
Cliente 2
Servidor 2

Cliente 3 Servidor 3

Redes: Tema 3 34
Identificación de los sockets
● Ahora tenemos varios sockets asociados al mismo puerto
● Para identificar al socket destino hay que tener en cuenta la
dirección (dir. IP + puerto) del socket origen

IP:62.3.3.3
Puerto: 80 IP:152.2.2.2
IP:62.3.3.3 Puerto: 2115
IP:128.1.1.1 Puerto: 80
Maestro servidor 1
servidor 2
Puerto: 1245 socket
socket
socket
Transporte
cliente 1 cliente 2
Red
socket socket
Transporte Enlace Transporte
Red Físico Red
Enlace Enlace
Físico Internet Físico

Redes: Tema 3 35
Servidor concurrente TCP
import java.net.*;
import java.io.*;

class SCTCP extends Thread {


Socket id;
public SCTCP(Socket s) {id=s;}
public void run() {
try {
PrintWriter out=new PrintWriter(id.getOutputStream(),true);
while(true){
out.println(System.currentTimeMillis());
sleep(100);
}
} catch(Exception e) {}
}

public static void main(String args[]) throws IOException{


ServerSocket ss=new ServerSocket(8888);
while(true) new SCTCP(ss.accept()).start();
}
}

● Le envía a cada cliente el tiempo transcurrido, en


milisegundos, desde medianoche de 1/1/1970 UTC
Redes: Tema 3 36
7. Ejemplos
Micro-servidor web iterativo
import java.net.*; import java.util.*; import java.io.*;

class ServidorWeb {
public static void main(String args[]) throws Exception{
byte[] buffer = new byte[1024]; int bytes;
ServerSocket ss=new ServerSocket(7777);
while(true) {
Socket s=ss.accept(); // espero a que llegue un cliente
BufferedReader in=new BufferedReader(new
InputStreamReader(s.getInputStream()));
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
StringTokenizer tokens = new StringTokenizer(in.readLine());
tokens.nextToken(); // esto debe ser el "GET"
String archivo = "."+tokens.nextToken(); // esto es el archivo
FileInputStream fis = null; boolean existe = true;
try {fis = new FileInputStream(archivo);} // comprobamos si existe
catch (FileNotFoundException e) {existe = false;}
if (existe && archivo.length()>2)
while((bytes = fis.read(buffer)) != -1 ) // enviar archivo solicitado
s.getOutputStream().write(buffer, 0, bytes);
else out.println("<html><body><h1>404 Not Found</h1></body></html>");
s.close();
}
}
}
Redes: Tema 3 37
Micro-servidor web iterativo

El servidor no implementa
el protocolo HTTP
correctamente

Funciona gracias a que el


navegador se adapta

Redes: Tema 3 38
Servidor multiprotocolo

● Un servidor que proporciona


diversos servicios:
● Ejemplo: servidor de eco
TCP y UDP en la misma Inicio

aplicación
● Se lanzan varios hilos de Servicio A Servicio B Servicio C
ejecución para que un
bloqueo en un accept() o
en un receive() no
bloquee el funcionamiento
de los otros servicios

Redes: Tema 3 39
Servidor multiprotocolo
import java.net.*; import java.io.*;

class ServicioA extends Thread {


static ServerSocket ss;
public ServicioA(ServerSocket s) {ss=s;}
public void run() {
try {
Socket id=ss.accept();
new ServicioA(ss).start();
PrintWriter salida=new PrintWriter(id.getOutputStream(),true);
while(true) {
salida.println(System.currentTimeMillis()+" milisegundos");
sleep(100);
} class Multiprotocolo {
}catch(Exception e) {} public static void main(String args[])
} throws IOException {
} ServerSocket ssA=new ServerSocket(7788);
ServerSocket ssB=new ServerSocket(8877);
class ServicioB extends Thread { new ServicioA(ssA).start();
static ServerSocket ss; new ServicioB(ssB).start();
public ServicioB(ServerSocket s) {ss=s;} }
public void run() { }
try{
Socket id=ss.accept();
new ServicioB(ss).start();
PrintWriter salida=new PrintWriter(id.getOutputStream(),true);
while(true) {
salida.println(System.currentTimeMillis()/1000+ " segundos");
sleep(100);
}
}catch(Exception e) {}
}
}
Redes: Tema 3 40

Vous aimerez peut-être aussi