Sockets - cs.buap.mxmtovar/doc/PCP/Sockets.pdf · InetAddress getInetAddress() Devuelve la...

51
Sockets

Transcript of Sockets - cs.buap.mxmtovar/doc/PCP/Sockets.pdf · InetAddress getInetAddress() Devuelve la...

Sockets

2.4 Sockets

Ambas formas de comunicación (UDP y TCP) utilizan la abstracción de sockets, que proporciona los puntos extremos de la comunicación entre procesos.

Los sockets (conectores) están presentes en la mayoría de las versiones de UNIX, incluido Linux y también Windows.

Los sockets permiten conectar dos programas en red para que se puedan intercambiar datos.

Los sockets están basados en una arquitectura cliente/servidor.

En esta arquitectura uno de los programas debe estar siempre arrancado y pendiente de que alguien establezca conexión con él. Este programa se denomina servidor.

El otro programa lo arranca el usuario cuando lo necesita y es el programa que da el primer paso en el establecimiento de la

comunicación. Este programa se llama cliente.

Servidor

El servidor, está continuamente a la

escucha y a la espera de que alguien se

quiera conectar a él.

Si hacemos una comparación con un

teléfono, un servidor es una empresa 24

horas, 365 días al año, pendiente de recibir

llamadas de sus clientes.

Cliente

El cliente, en un momento dado decide conectarse a un servidor y hacerle alguna petición.

Cuando el cliente no necesita al servidor, cierra la conexión.

En la comparativa del teléfono, el cliente es el que llama por teléfono a la empresa cuando necesita algo de ella.

Por ejemplo, un servidor de páginas web está siempre en marcha y a la escucha.

El navegador es el cliente. Cuando arrancamos el navegador y ponemos la dirección del servidor web, el navegador establece la comunicación y le pide al servidor la página web que queremos ver. El servidor la envía y el navegador la muestra.

La comunicación entre procesos consiste en la transmisión de un mensaje entre un conector de un proceso y un conector de otro proceso.

Para los procesos receptores de mensajes, su conector debe estar asociado a un puerto local y a una de las direcciones Internet de la computadora donde se ejecuta.

Los mensajes enviados a una dirección de Internet y a un número de puerto concretos, sólo pueden ser recibidos por el proceso cuyo conector esté asociado con esa dirección y con ese puerto.

Los procesos pueden utilizar un mismo conector tanto para enviar como para recibir mensajes. Cada computadora permite un gran número de puertos posibles, que pueden ser usados por los procesos locales para recibir mensajes.

Cada proceso puede utilizar varios puertos para recibir mensajes, pero un proceso no puede compartir puertos con otros procesos de la misma computadora.

Cualquier cantidad de procesos puede enviar mensajes a un mismo puerto. Cada conector se asocia con un protocolo concreto, que puede ser UDP o TCP.

2.4.1 Sockets flujos (TCP)

Son un servicio orientado a la conexión, donde los datos se

transfieren sin encuadrarlos en registros o bloques.

Si se rompe la conexión entre los procesos, éstos serán informados de tal suceso para que tomen las medidas oportunas.

El protocolo de comunicaciones con flujos es un protocolo orientado a la conexión, ya que para establecer una comunicación utilizando el protocolo TCP, hay que establecer en primer lugar una conexión entre un par de sockets.

Mientras uno de los sockets atiende peticiones de conexión (servidor), el otro solicita una conexión (cliente).

Una vez que los dos sockets estén conectados, se pueden utilizar para transmitir datos en ambas direcciones.

El protocolo TCP (Transmission Control Protocol)

funciona en el nivel de trasporte, basándose en el

protocolo de red IP (Internet Protocol).

IP proporciona comunicaciones no fiables y no

basadas en conexión, muy dependientes de

saturación en la red, caídas de nodos, etc.

Por el contrario, TCP está orientado a conexión y

proporciona comunicaciones fiables basadas en

mecanismos de red que gestionan el control de flujo

de paquetes y de congestión en los nodos.

En Java, las comunicaciones TCP se realizan utilizando la clásica abstracción de socket.

Los sockets nos permiten establecer y programar comunicaciones sin tener que conocer los niveles inferiores sobre los que se asientan.

Para identificar el destino de los paquetes de datos, los sockets utilizan los conceptos de dirección y puerto.

Los valores numéricos de puertos 1 – 1023 se reservan a servicios de interés general, montados a menudo sobre protocolos de uso extendido:

Puerto Servicio

80 Para web con http

25 Para correo saliente con SMTP

110 Para correo entrante con POP3

119 Para el servicio de noticias con NNTP

Los valores de puertos entre 1024 y 49151 se usan para servicios específicos de uso no general, el resto (a partir de 49152) se emplean para designar servicios de uso esporádico.

Establecimiento de comunicaciones

Java proporciona dos clases de abstracción

de comunicaciones TCP: una para los

procesos cliente (socket) y otra para los

procesos servidor (ServerSocket).

La Figura 2.1 que es el esquema básico de

establecimiento de comunicaciones TCP.

Programa

Cliente

Programa Servidor

Nodo destino

Puerto destino

Socket

Puerto destino

ServerSocket

Socket

Puerto

2.accept

4. Instanciación

1. Instanciación

3. return del accept

5. Conexión TCP

(interno)

6. Comunicación

Figura 2.1 Comunicación TCP entre un cliente y un servidor.

Transmisión de datos

TCP es un protocolo especialmente útil cuando se desea

transmitir un flujo de datos en lugar de pequeñas

cantidades aisladas de información.

Debido a está característica, los sockets de Java están

diseñados para transmitir y recibir datos a través de los

Streams definidos en el paquete java.io.

La clase Socket contiene dos métodos importantes que se

emplean en el proceso de transmisión de flujos de datos:

InputStream getInputStream()

OutputStream getOutputStream()

Estas clases son abstractas, por lo que no podemos emplear directamente todos sus métodos.

En general se usan otras clases más especializadas que nos permiten trabajar con flujos de datos como: DataOutputStream, DataInputStream, FileOutputStream, FileInputStream, etc.

Ejemplo Hola Mundo Para esta versión necesitamos:

Un programa que se ejecute en el equipo cliente y envíe el texto “Hola mundo”: TCPClienteHolaMundo

Un programa que se ejecute en el equipo servidor y reciba e imprima el mensaje: TCPServidorHolaMundo

import java.net.Socket;

import java.io.*;

import java.net.UnknownHostException;

public class TCPClienteHolaMundo{

public static void main(String[] args){

OutputStream FlujoDeSalida;

DataOutputStream Flujo;

try{

Socket SocketCliente = new Socket("localhost",8000);

FlujoDeSalida = SocketCliente.getOutputStream();

Flujo = new DataOutputStream(FlujoDeSalida);

Flujo.writeBytes("Hola Mundo");

SocketCliente.close();

}catch (UnknownHostException e){

System.out.println("Referencia a host no resuelta");

}catch (IOException e){

System.out.println("Error en las comunicaciones");

}catch (SecurityException e){

System.out.println("Comunicacion no permitida por razones

de seguridad");

}

}

}

TCPClienteHolaMundo.java

import java.net.ServerSocket;

import java.net.Socket;

import java.io.*;

public class TCPServidorHolaMundo{

public static void main(String[] args){

byte[] Mensaje = new byte[80];

InputStream FlujoDeEntrada;

DataInputStream Flujo;

try{

ServerSocket SocketServidor = new ServerSocket(8000);

Socket ComunicaConCliente = SocketServidor.accept();

System.out.println("Comunicacion establecida");

FlujoDeEntrada = ComunicaConCliente.getInputStream();

Flujo = new DataInputStream(FlujoDeEntrada);

int BytesLeidos = Flujo.read(Mensaje);

System.out.println(new String(Mensaje));

ComunicaConCliente.close();

SocketServidor.close();

}catch (IOException e){

System.out.println("Error en las comunicaciones");

System.exit(0);

}catch (SecurityException e){ System.out.println("Comunicacion no permitida por razones de

seguridad");

System.exit(0);

}

}

}

TCPServidorHolaMundo

Ejemplos de lectura y escritura de un socket

A continuación se presenta un simple ejemplo que ilustra como un programa puede establecer la conexión a un programa servidor usando la clase Socket y como el cliente puede enviar datos y recibir datos del servidor a través del socket.

El ejemplo implementa un cliente, echoClient, que se conecta al echoServer. El echoServer simplemente recibe datos del cliente y hace echo hacia atrás.

import java.io.*;

import java.net.*;

public class echoClient {

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

Socket echoSocket = null;

PrintWriter out = null;

BufferedReader in = null;

try {

echoSocket = new Socket("taranis", 7);

out = new PrintWriter(echoSocket.getOutputStream(), true);

in = new BufferedReader(new InputStreamReader(

echoSocket.getInputStream()));

} catch (UnknownHostException e) {

System.err.println("Don't know about host: taranis.");

System.exit(1);

} catch (IOException e) {

System.err.println("Couldn't get I/O for "

+ "the connection to: taranis.");

System.exit(1);

}

BufferedReader stdIn = new BufferedReader(

new InputStreamReader(System.in));

String userInput;

while ((userInput = stdIn.readLine()) != null) {

out.println(userInput);

System.out.println("echo: " + in.readLine());

}

out.close();

in.close();

stdIn.close();

echoSocket.close();

}

}

Cliente, acciones

El programa cliente debe realizar los siguientes pasos:

1. Abrir un socket

2. Abrir un flujo de entrada y salida para el socket.

3. Leer desde y escribir al flujo de acuerdo al protocolo del servidor

4. Cerrar los flujos

5. Cerrar el socket Únicamente el paso 3 difiere de cliente a cliente,

dependiendo del servidor. Los otros pasos son los mismos.

Ejercicio: Construya el servidor.

TCP, continuación Configuración de las comunicaciones

Clase ServerSocket

Métodos principales Acción

socket accept() Espera a que se realice una conexión y devuelve un

socket para comunicarse con el cliente.

void bind(SocketAddress a) Asigna la dirección establecida al socket creado con

accept, si no se utiliza este método se asigna

automáticamente una dirección temporal.

void close() Cierra el socket

InetAddress getInetAddress() Devuelve la dirección a la que está conectada el socket

int getLocalPort() Devuelve el número de puerto asociado al socket

int getSoTimeout() Devuelve el valor en milisegundos que el socket espera

al establecimiento de comunicación tras la

ejecución de accept

void setSoTimeout(int ms) Asigna el número de milisegundos que el socket espera

al establecimiento de comunicación tras la

ejecución de accept

Clase Socket

Métodos principales Acción

void bind(SocketAddress a) Asigna la dirección establecida al socket creado con accept,

si no se utiliza este método se asigna automáticamente una

dirección temporal

void close() Cierra el socket.

void connect(SocketAddress a) Conecta el socket a la dirección de servidor establecida

void connect(SocketAddress a, int

ms)

Conecta el socket a la dirección de servidor establecida,

esperando un máximo de ms milisegundos.

InetAddress getInetAddress() Devuelve la dirección a la que está conectada el socket

InputStream getInputStream Devuelve el stream de entrada asociada al socket

Int gelLocalPort() Devuelve el número de puerto asociado al socket

OutputStream getOutputStream() Devuelve el stream de salida asociado al socket

int getPort() Devuelve el valor del puerto remoto al que está conectado

int getSoLinger() Devuelve el número de milisegundos que se espera a los

datos después de cerrar el socket.

ClienteTCP

import java.awt.*;

import java.net.*;

import java.io.*;

import java.awt.event.*;

class ClienteTCP extends Frame implements ActionListener

{ Panel panel;

Socket conexion;

TextField textent,textsal;

Button enviar,conectar,desconectar;

DataOutputStream salida;

DataInputStream entrada;

ClienteTCP(String nombre)

{

super(nombre);

setSize(350,200);

panel=new Panel();

textsal=new TextField(40);

textent=new TextField(40);

textent.setText("Pulsa el boton \"Conectar\" para conectarte");

textent.setEditable(false);

enviar=new Button("Enviar");

enviar.setEnabled(false);

conectar=new Button("Conectar");

desconectar=new Button("Desconectar");

desconectar.setEnabled(false);

panel.add(new Label("Datos a enviar"));

panel.add(textsal);

panel.add(new Label("Datos recibidos"));

panel.add(textent);

panel.add(enviar);

panel.add(conectar);

panel.add(desconectar);

enviar.addActionListener(this);

conectar.addActionListener(this);

desconectar.addActionListener(this);

addWindowListener(new Cerrar());

add(panel);

setVisible(true);

}

public void actionPerformed(ActionEvent e)

{

String com=e.getActionCommand();

if (com.equals("Enviar"))

{

try

{

textent.setText("");

salida.writeUTF(textsal.getText());

textent.setText(entrada.readUTF());

textsal.setText("");

}

catch(IOException excepcion){} }

else

try

{

salida.writeUTF("Salir");

conexion.close();

conectar.setEnabled(true);

desconectar.setEnabled(false);

enviar.setEnabled(false);

textent.setText("Pulsa el boton \"Conectar\" para conectarte");

}

catch(IOException excepcion){}

}

class Cerrar extends WindowAdapter

{ public void windowClosing(WindowEvent e)

{ dispose();

System.exit(0);

}

}

public static void main(String args[])

{ new ClienteTCP("Cliente Angel");

new ClienteTCP("Cliente Pepe");

}

}

ServidorTCP

import java.awt.*;

import java.net.*;

import java.io.*;

import java.awt.event.*;

class ServidorTCP extends Frame

{

TextArea entrada;

ServerSocket s;

int clientes;

ServidorTCP()

{

setTitle("Servidor");

setSize(350,400);

// entrada=new TextArea(20,40);

entrada=new TextArea(20,40);

entrada.setEditable(false);

add(entrada);

addWindowListener(new Cerrar());

setVisible(true);

clientes=0;

}

void lanzarServidor()

{

String cadena;

try

{

s=new ServerSocket(5001,50);

while (true)

new NuevoCliente(s.accept(),this,clientes++).start();

}

catch(IOException e){}

}

public void añadir(String texto)

{

entrada.append(texto);

}

class Cerrar extends WindowAdapter

{ public void windowClosing(WindowEvent e)

{ dispose();

System.exit(0);

}

}

public static void main(String args[])

{ ServidorTCP Servidor=new ServidorTCP();

Servidor.lanzarServidor();

}

}

class NuevoCliente extends Thread

{Socket conexion;

ServidorTCP serv;

int cliente;

DataInputStream entrada;

DataOutputStream salida;

NuevoCliente(Socket c,ServidorTCP s,int numero)

{ conexion=c;

serv=s;

cliente=numero;

try

{

entrada= new DataInputStream(conexion.getInputStream());

salida= new DataOutputStream(conexion.getOutputStream());

}

catch(IOException e){}

}

public void run()

{

boolean Salir=false;

serv.añadir("Cliente "+cliente+" se ha conectado\n");

while (!Salir)

{

try

{

String cadena=entrada.readUTF();

if (cadena.equals("Salir"))

Salir=true;

else

{

serv.añadir("El cliente "+cliente+" ha enviado:\n"+" "+cadena+'\n');

salida.writeUTF("Cadena \""+cadena+"\" recibida");

}

}

catch(IOException e){}

}

serv.añadir("Se ha ido el cliente "+cliente+"\n");

try

{

conexion.close();

}

catch(IOException e){}

} }

2.4.2 Sockets Datagrama (UDP)

Servicio de transporte sin conexión.

Más eficientes que TCP

Pero no está garantizada la fiabilidad.

Los datos se envían y reciben en paquetes,

cuya entrega no está garantizada.

Los paquetes pueden ser duplicados,

perdidos o llegar en un orden diferente al que

se envió.

El protocolo de comunicación con datagramas es un

protocolo sin conexión, es decir, cada vez que se

envíen datagramas es necesario enviar el descriptor

del socket local y la dirección del socket que debe

recibir el datagrama.

Hay que enviar datos adicionales cada vez que se

realice una comunicación, aunque tiene la ventaja

de que se pueden indicar direcciones globales y el

mismo mensaje llegará a muchas computadoras a

la vez.

Un datagrama enviado por UDP se transmite desde un proceso emisor a un proceso receptor sin acuse de recibo ni reintentos.

Si algo falla, el mensaje puede no llegar a su destino.

Se transmite un datagrama, entre procesos, cuando uno lo envía, y el otro lo recibe.

La comunicación de datagramas UDP utiliza operaciones de envío, no bloqueantes y recepciones, bloqueantes.

La operación send devuelve el control cuando ha dirigido el mensaje a las capas inferiores UDP e IP, que son las responsables de su entrega en el destino. A la llegada, el mensaje será colocado en una cola del conector que está enlazado con el puerto de destino.

El mensaje podrá obtenerse de la cola de recepción mediante una invocación pendiente o futura del método recibe sobre ese conector. Si no existe ningún proceso ligado al conector destino, los mensajes serán descartados.

El método recibe produce un bloqueo hasta que se reciba un datagrama, a menos que se haya establecido un tiempo límite (time out) asociado al conector.

Cualquier proceso que necesite enviar o recibir mensajes debe crear, primero, un conector asociado a una dirección Internet y a un puerto local.

Un servidor enlazará su conector a un puerto de servidor (uno que resulte con los clientes de modo que puedan enviarle mensajes).

Un cliente ligará su conector a cualquier puerto local libre.

El método recibe devolverá, además del mensaje, la dirección Internet y el puerto del emisor, permitiendo al receptor enviar la correspondiente respuesta.

Ejemplo, el Servicio de Nombres de Dominio en Internet (Domain Name Service, DNS) está implementado sobre UDP.

Los datagramas UDP son, en algunas ocasiones, una elección atractiva porque no padecen la sobrecarga asociadas a la entrega de mensajes garantizada.

Existen tres fuentes principales para esa sobrecarga: 1. La necesidad de almacenar información de estado en el

origen y en el destino.

2. La transmisión de mensajes extra.

3. La latencia para el emisor.

Establecimiento de comunicaciones

Programa cliente

DatagramSock

et

DatagramSocket

Puerto destino

2. new

DatagramPacket

1. new

DatagramSocket

4. new

DatagramSocket

5. new

DatagramPacket

6.send

3.receive Puerto

destino

Nodo destino

Programa servidor

Figura 2.2 Comunicación UDP

Programa servidor

1. El programa que proporciona el servicio (servidor) crea una instancia de la clase DatagramSocket, indicando el puerto asociado al servicio:

DatagramSocket MiSocket = new DatagramSocket(4000);

2. El programa servidor crea una instancia de la clase DatagramPacket, donde se guardarán los datos recibidos:

DatagramPacket(buffer, buffer.length);

3. hasta que llegan los datos: El programa servidor invoca el método receive sobre el socket de tipo DatagramSocket. Este método, por defecto, bloquea el programa MiSocket.receive(Paquete);

4. El programa cliente crea una instancia de tipo DatagramSocket; DatagramSocket MiSocket = new

DatagramSocket();

5. El programa cliente crea una instancia de tipo

DatagramPacket, proporcionándole los datos,

además de la dirección y puerto destino. DatagramPacket Paquete = new DatagramPacket(buffer,

Mensaje.length(),

InetAddress.getByName(“localhost”),4000)

6. El programa que utiliza el servicio (programa

cliente) invoca el método send sobre el socket de

tipo DatagramSocket: MiSocket.send(Paquete);

import java.net.*;

public class UDPEnvia{

public static void main(String args[]){

try{

DatagramSocket MiSocket = new DatagramSocket();

byte[] buffer= new byte[15];

String Mensaje = "Hola Mundo";

buffer = Mensaje.getBytes();

DatagramPacket Paquete = new DatagramPacket(buffer,

Mensaje.length(), InetAddress.getByName("localhost"),1400);

MiSocket.send(Paquete);

MiSocket.close();

}catch (Exception exc){

System.out.println("Error");

}//try

}

}//UDPEnvia

Ejemplo Hola Mundo

UPDEnvia.java

import java.net.*;

public class UDPRecibe{

public static void main(String args[]){

try{

DatagramSocket MiSocket = new DatagramSocket(1400);

byte[] buffer= new byte[15];

DatagramPacket Paquete = new

DatagramPacket(buffer, buffer.length);

MiSocket.receive(Paquete);

System.out.println(new String(Paquete.getData()));

MiSocket.close();

}catch (Exception e){

System.out.println("Error");

}//try

}//main

}//UDPRecibe

UDPRecibe.java

Otros ejemplos de datagramas en Java

El paquete java.net contiene tres clases para el uso

de datagramas, es decir, para enviar y recibir

paquetes en la red:

DatagramSocket,

DatagramPacket y

MulticastSocket.

Una aplicación puede enviar y recibir

DatagramPackets a través de un DatagramSocket.

También, se puede hacer un broadcast a múltiples

recipientes escuchando a un MulticastSocket.

DatagramPacket:

Esta clase proporciona un constructor que crea una instancia compuesta por:

una cadena de bytes que almacena el mensaje,

la longitud del mensaje y

la dirección Internet y

el número de puerto local del conector destino,

Las instancias de DatagramPacket podrán ser transmitidas entre procesos cuando uno las envía, y el otro las recibe .

La clase DatagramSocket proporciona varios métodos que incluyen los siguientes:

send y receive

estos métodos sirven para transmitir datagramas entre un par de conectores.

El argumento de send es una instancia de DatagramPacket conteniendo el mensaje y su destino.

El argumento de receive es un DatagramPacket vacío en el que se coloca el mensaje, su longitud y su origen.

Tanto el método send como receive pueden lanzar una excepción IOException.

setSoTimeout: este método permite establecer un tiempo de espera límite. Cuando se fija un límite, el método receive se bloquea durante el tiempo fijado y después lanza una excepción InterruptedIOException.

connect: este método se utiliza para conectarse a un puerto remoto y a una dirección Internet concretos, en cuyo caso el conector sólo podrá enviar y recibir mensajes de esa dirección.

import java.net.*;

import java.io.*;

public class UDPClient{

public static void main(String args[]){

// args give message contents and server hostname

DatagramSocket aSocket = null;

try {

aSocket = new DatagramSocket();

byte[] m = args[0].getBytes();

InetAddress aHost = InetAddress.getByName(args[1]);

int serverPort = 6789;

DatagramPacket request = new DatagramPacket(m, args[0].length(), aHost,

serverPort);

aSocket.send(request);

byte[] buffer = new byte[1000];

DatagramPacket reply = new DatagramPacket(buffer, buffer.length);

aSocket.receive(reply);

System.out.println("Reply: " + new String(reply.getData()));

}catch (SocketException e){

System.out.println("Socket: " + e.getMessage());

}catch (IOException e){

System.out.println("IO: " + e.getMessage());

}finally

{if(aSocket != null) aSocket.close();}

}

}

UDPClient.java

import java.net.*;

import java.io.*;

public class UDPServer{

public static void main(String args[]){

DatagramSocket aSocket = null;

try{

aSocket = new DatagramSocket(6789);

byte[] buffer = new byte[1000];

while(true){

DatagramPacket request = new DatagramPacket(buffer, buffer.length);

aSocket.receive(request);

DatagramPacket reply = new DatagramPacket(request.getData(),

request.getLength(), request.getAddress(), request.getPort());

aSocket.send(reply);

}

}catch (SocketException e){System.out.println("Socket: " + e.getMessage());

}catch (IOException e) {System.out.println("IO: " + e.getMessage());

}finally {if(aSocket != null) aSocket.close();}

}

}

UDPServer.java

Corrida:

Terminal 1 mtovar@linux-w7tc:~/programasTCP> java UDPServer

Terminal 2 mtovar@linux-w7tc:~/programasTCP> java UDPClient mireya 148.228.22.6

Reply: mireya

mtovar@linux-w7tc:~/programasTCP> java UDPClient mireya localhost

Reply: mireya

mtovar@linux-w7tc:~/programasTCP>

Configuración de las comunicaciones DatagramPacket

Métodos Acción

InetAddress getAddress() Dirección del nodo remoto en la

comunicación

byte[] getData() Devuelve el mensaje que contiene el

datagrama

int getLength() Devuelve la longitud del mensaje del

datagrama

int getOffset() Devuelve el desplazamiento que indica el

inicio del mensaje (dentro del array de

bytes)

int getPort() Devuelve el valor del puerto remoto

void setAddress(InetAddress d) Establece el nodo remoto en la

comunicación

void setData(byte[] Mensaje) Establece el mensaje que contiene el

datagrama

Void setData(byte[] Mensaje, int

Dezplazamiento, int Longitud)

Establece el mensaje que contiene el

datagrama, indicando su

desplazamiento en el array de bytes y

su longitud.

Void setLength(int Longitud) Establece la longitud del mensaje del

datagrama

void setPort() Establece el valor del puerto remoto

Void setSocketAddress(SocketAddress

d)

Establece la dirección (nodo+ puerto)

remota en la comunicación

DatagramSocket

Metódos Acción

void bind(SocketAddress a) Asigna la dirección establecida al

socket

void close() Cierra el socket

void connect(SocketAddress a) Conecta el socket a la dirección

remota establecida

void connect(InetAddress a, int

puerto)

Conecta el socket a la dirección

establecida y el puerto especificado

void disconnect() Desconecta el socket

InetAddress getInetAddress() Devuelve la dirección a la que está

conectada el socket.

int getLocalPort() Devuelve el número de puerto asociado al

socket

OutputStream getOutputStream() Devuelve el stream de salida asociado al socket

int getPort() Devuelve el valor del puerto remoto al que está

conectado

Int getSoTimeout() Devuelve el valor en milisegundos que el socket

espera al establecimiento de comunicación

Boolean isBound() Indica si el socket está vinculado

Boolean isClosed() Indica si el socket está cerrado

Boolean isConneted Indica si el socket está conectado

Void setSoTimeout(int ms) Indica el valor en milisegundos que el socket

espera al establecimiento de comunicación

2.4.3 Diferencias entre Sockets Stream

y Datagrama

En UDP, cada vez que se envía un datagrama, hay

que enviar también el descriptor del socket local y la

dirección del socket que va a recibir el datagrama,

luego los mensajes son más grandes que los TCP.

Como el protocolo TCP está orientado a conexión,

hay que establecer esta conexión entre los dos

sockets, lo que implica un cierto tiempo empleado

en el establecimiento de la conexión, que no es

necesario emplear en UDP.

En UDP hay un límite de tamaño de los datagramas, establecido en 64 kilobytes, que se pueden enviar a una localización determinada, mientras que TCP no tiene límite; una vez que se ha establecido la conexión, el par de sockets funciona como los streams: todos los datos se leen inmediatamente, en el mismo orden en que se van recibiendo.

UDP es un protocolo desordenado, no garantiza que los datagramas que se hayan enviado sean recibidos en el mismo orden por el socket de recepción. Al contrario, TCP es un protocolo ordenado, garantiza que todos los paquetes que se envíen serán recibidos en el socket destino en el mismo orden en que se han enviado.

En resumen, TCP parece más indicado para la

implementación de servicios de red como un control

remoto (rlogin, telnet) y transmisión de ficheros (ftp);

que necesitan transmitir datos de longitud

indefinida.

UDP es menos complejo y tiene una menor

sobrecarga sobre la conexión; esto hace que sea el

indicado en la implementación de aplicaciones

cliente/servidor en sistemas distribuidos montados

sobre redes de área local.