Las redes de estilo TCP/IP proporcionan un flujo serializado, predecible y confiable de paquetes de datos. Esto no es sin su costo, sin embargo. TCP incluye algoritmos para manejar el control de la congestión en redes saturadas, así como las expectativas pesimistas sobre la pérdida de paquetes. Esto conduce a una forma ineficiente de transportar datos.
Los clientes y servidores que se comunican a través de un canal confiable, como un socket TCP, tienen un canal punto a punto dedicado entre ellos. Para comunicarse, establecen una conexión, transmiten los datos y luego cierran la conexión. Todos los datos enviados por el canal se reciben en el mismo orden en que se enviaron. Esto está garantizado por el canal.
Por el contrario, las aplicaciones que se comunican a través de datagramas envían y reciben paquetes de información completamente independientes. Estos clientes y servidores no tienen ni necesitan un canal punto a punto dedicado. No se garantiza la entrega de datagramas a sus destinos. Tampoco lo es el orden de su llegada.
datagrama
Un datagrama es un mensaje autónomo e independiente enviado a través de la red cuya llegada, hora de llegada y contenido no están garantizados.
- Los datagramas juegan un papel vital como alternativa.
- Los datagramas son paquetes de información que se pasan entre máquinas. Una vez que el datagrama se ha enviado a su destino previsto, no hay garantía de que llegue o incluso de que alguien estará allí para atraparlo.
- Asimismo, cuando se recibe el datagrama, no hay seguridad de que no se haya dañado en el tránsito o que quien lo envió todavía esté allí para recibir una respuesta y es un punto crucial a tener en cuenta.
Java implementa datagramas sobre el protocolo UDP (Protocolo de datagramas de usuario) mediante el uso de dos clases:
- El objeto DatagramPacket es el contenedor de datos.
- DatagramSocket es el mecanismo utilizado para enviar o recibir DatagramPackets.
Clase DatagramSocketDatagramSocket Class
DatagramSocket define cuatro constructores públicos. Se muestran aquí:
- DatagramSocket( ) lanza SocketException: crea un DatagramSocket vinculado a cualquier puerto no utilizado en la computadora local.
- DatagramSocket (puerto int) lanza SocketException: crea un DatagramSocket vinculado al puerto especificado por puerto.
- DatagramSocket(int port, InetAddress ipAddress) lanza SocketException: Construye un DatagramSocket enlazado al puerto e InetAddress especificados.
- DatagramSocket(SocketAddress address) lanza SocketException: Construye un DatagramSocket vinculado a la SocketAddress especificada.
SocketAddress es una clase abstracta implementada por la clase concreta InetSocketAddress. InetSocketAddress encapsula una dirección IP con un número de puerto. Todos pueden lanzar una SocketException si ocurre un error al crear el socket. DatagramSocket define muchos métodos. Dos de los más importantes son enviar() y recibir(), que se muestran aquí:
- envío vacío (paquete DatagramPacket) lanza IOException
- void recibir (paquete DatagramPacket) lanza IOException
El método send( ) envía el paquete al puerto especificado por paquete. El método de recepción espera a que se reciba un paquete desde el puerto especificado por el paquete y devuelve el resultado.
Otros métodos le dan acceso a varios atributos asociados con un DatagramSocket. Aquí hay una muestra:
Función | Uso |
---|---|
InetAddress getInetAddress( ) | Si el socket está conectado, se devuelve la dirección. De lo contrario, se devuelve nulo. |
int obtenerPuertoLocal( ) | Devuelve el número del puerto local. |
int obtenerPuerto( ) | Devuelve el número del puerto al que está conectado el socket. Devuelve –1 si el socket no está conectado a un puerto. |
booleano isBound( ) | Devuelve verdadero si el socket está vinculado a una dirección. Devuelve falso en caso contrario. |
booleano está conectado( ) | Devuelve verdadero si el socket está conectado a un servidor. Devuelve falso en caso contrario. |
void setSoTimeout(int millis) arroja SocketException | Establece el período de tiempo de espera en el número de milisegundos transcurridos en milisegundos. |
Clase de paquete de datagramas
DatagramPacket define varios constructores. Cuatro se muestran aquí:
- DatagramPacket(byte data[ ], int size) : Especifica un búfer que recibirá datos y el tamaño de un paquete. Se utiliza para recibir datos a través de un DatagramSocket
- DatagramPacket(byte data[ ], int offset, int size) : Le permite especificar un desplazamiento en el búfer en el que se almacenarán los datos.
- DatagramPacket(byte data[ ], int size, InetAddress ipAddress, int port): especifica una dirección y un puerto de destino, que utiliza un DatagramSocket para determinar dónde se enviarán los datos del paquete.
- DatagramPacket(byte data[ ], int offset, int size, InetAddress ipAddress, int port): Transmite paquetes comenzando en el desplazamiento especificado en los datos.
Piense en los primeros dos formularios como si estuvieran construyendo una «caja de entrada», y los dos segundos formularios como si estuvieran rellenando y dirigiendo un sobre.
DatagramPacket define varios métodos, incluidos los que se muestran aquí, que brindan acceso a la dirección y el número de puerto de un paquete, así como a los datos sin procesar y su longitud. En general, los métodos get se usan en los paquetes que se reciben y los métodos set se usan en los paquetes que se enviarán.
Función | Uso |
---|---|
InetAddress getAddress( ) | Devuelve la dirección de origen (para los datagramas que se reciben) o de destino (para los datagramas que se envían). |
byte[ ] obtenerDatos( ) | Devuelve la array de bytes de datos contenidos en el datagrama. Se utiliza principalmente para recuperar datos del datagrama después de haberlo recibido. |
int obtenerLongitud() | Devuelve la longitud de los datos válidos contenidos en la array de bytes que devolvería el método getData( ). Esto puede no ser igual a la longitud de toda la array de bytes. |
int getOffset( ) | Devuelve el índice inicial de los datos. |
int obtenerPuerto( ) | Devuelve el número de puerto. |
void setAddress(InetAddress IPAddress) | Establece la dirección a la que se enviará un paquete. La dirección se especifica mediante ipAddress. |
void setData(byte[ ] datos) | Establece los datos en datos, el desplazamiento en cero y la longitud en el número de bytes en los datos |
void setData(byte[ ] data, int idx, int size) | Establece los datos en datos, el desplazamiento en idx y la longitud en tamaño. |
void setLength(tamaño int) | Establece la longitud del paquete al tamaño. |
void setPort(puerto int) | Establece el puerto a puerto. |
Un ejemplo de datagrama
El siguiente ejemplo implementa un cliente y servidor de comunicaciones en red muy simple. Los mensajes se escriben en la ventana del servidor y se escriben a través de la red hacia el lado del cliente, donde se muestran.
// Java program to illustrate datagrams import java.net.*; class WriteServer { // Specified server port public static int serverPort = 998; // Specified client port public static int clientPort = 999; public static int buffer_size = 1024; public static DatagramSocket ds; // an array of buffer_size public static byte buffer[] = new byte[buffer_size]; // Function for server public static void TheServer() throws Exception { int pos = 0; while (true) { int c = System.in.read(); switch (c) { case -1: // -1 is given then server quits and returns System.out.println("Server Quits."); return; case '\r': break; // loop broken case '\n': // send the data to client ds.send(new DatagramPacket(buffer, pos, InetAddress.getLocalHost(), clientPort)); pos = 0; break; default: // otherwise put the input in buffer array buffer[pos++] = (byte)c; } } } // Function for client public static void TheClient() throws Exception { while (true) { // first one is array and later is its size DatagramPacket p = new DatagramPacket(buffer, buffer.length); ds.receive(p); // printing the data which has been sent by the server System.out.println(new String(p.getData(), 0, p.getLength())); } } // main driver function public static void main(String args[]) throws Exception { // if WriteServer 1 passed then this will run the server function // otherwise client function will run if (args.length == 1) { ds = new DatagramSocket(serverPort); TheServer(); } else { ds = new DatagramSocket(clientPort); TheClient(); } } }
Este programa de muestra está restringido por el constructor de DatagramSocket para ejecutarse entre dos puertos en la máquina local. Para utilizar el programa, ejecute
java WriteServer
en una ventana; este será el cliente. Entonces corre
java WriteServer 1
Este será el servidor. Cualquier cosa que se escriba en la ventana del servidor se enviará a la ventana del cliente después de que se reciba una nueva línea.
Publicación traducida automáticamente
Artículo escrito por Mayukh Mukherjee y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA