¿Qué es un paquete UDP?
El nombre completo del protocolo UDP es User Datagram, que se utiliza para procesar paquetes de datos en la red como el protocolo TCP. En el modelo OSI, la cuarta capa, la capa de transporte, es la capa superior del protocolo IP. UDP tiene la desventaja de no proporcionar agrupación y ensamblaje de datagramas y la incapacidad de ordenar paquetes de datos. En otras palabras, después de enviar un mensaje, es imposible saber si ha llegado de forma segura y completa.
Por qué usar UDP
A la hora de elegir un protocolo a utilizar, debes tener cuidado al elegir UDP. En un entorno donde la calidad de la red no es muy satisfactoria, la pérdida de paquetes del protocolo UDP será grave. Sin embargo, debido a las características de UDP: no es un protocolo de tipo conexión, por lo que tiene las ventajas de un bajo consumo de recursos y una rápida velocidad de procesamiento. Por lo tanto, el audio, el video y los datos ordinarios generalmente se transmiten mediante UDP, porque incluso si lo hacen. De vez en cuando, perder uno o dos paquetes de datos no tendrá mucho impacto en los resultados de la recepción. Por ejemplo, el ICQ y el OICQ que utilizamos para el chat utilizan el protocolo UDP.
Manipulación de UDP en Java
Utilizando las clases DatagramSocket y DatagramPacket ubicadas en el paquete Java.net en el JDK, puede controlar los mensajes de datos del usuario de manera muy conveniente.
Antes de describirlos, es necesario comprender la clase InetAddress ubicada en la misma ubicación. InetAddress implementa la interfaz Java.io Serializable y no permite herencia. Se utiliza para describir y encapsular una dirección IP de Internet y devuelve una instancia de InetAddress a través de tres métodos:
getLocalhost(): Devuelve una instancia que encapsula la dirección local.
getAllByName(String host): devuelve una matriz de instancias de InetAddress que encapsulan la dirección del host.
getByName(String host): Devuelve una instancia que encapsula la dirección del Host. Entre ellos, Host puede ser un nombre de dominio o una dirección IP legal.
La clase DatagramSocket se utiliza para crear instancias de Socket para recibir y enviar UDP. Al igual que la clase Socket se basa en la clase SocketImpl, la implementación de la clase DatagramSocket también se basa en la clase DatagramScoketImplFactory especialmente diseñada para ella. La clase DatagramSocket tiene 3 constructores:
DatagramSocket(): Crea una instancia. Este es un uso bastante especial, generalmente utilizado en la programación del cliente. No tiene un puerto de escucha específico, solo usa uno temporal.
DatagramSocket(int port): Crea una instancia y monitorea los paquetes del puerto Port.
DatagramSocket (puerto int, InetAddress localAddr): este es un constructor muy útil cuando una máquina tiene más de una dirección IP, la instancia creada por ella solo recibe mensajes de LocalAddr.
Vale la pena señalar que al crear una instancia de la clase DatagramSocket, si el puerto ya está en uso, se generará una excepción SocketException y hará que el programa finalice ilegalmente. Esta excepción debe detectarse. Hay 4 métodos principales de la clase DatagramSocket:
Recibir (DatagramPacket d): recibe paquetes de datos en d. El método de recepción crea un "bloqueo".
Enviar(DatagramPacket d): envía el paquete d al destino.
SetSoTimeout(int timeout): establece el tiempo de espera en milisegundos.
Cerrar(): Cierra DatagramSocket. Cuando la aplicación se cierra, normalmente libera recursos de forma activa y cierra el socket. Sin embargo, una salida anormal puede hacer que los recursos sean irrecuperables.
Por lo tanto, debe utilizar activamente este método para cerrar el Socket cuando se complete el programa, o cerrar el Socket después de detectar una excepción y lanzarla.
"Bloqueo" es un término profesional que genera un bucle interno donde el programa se suspende hasta que se activa una condición.
La clase DatagramPacket se utiliza para procesar paquetes. Empaqueta datos como matrices de bytes, direcciones de destino y puertos de destino en paquetes o desensambla paquetes en matrices de bytes. Las aplicaciones deben tener en cuenta al generar paquetes de datos que TCP/IP estipula que el tamaño del paquete de datos contenga hasta 65507 bytes. Normalmente el host recibe 548 bytes, pero la mayoría de las plataformas pueden admitir paquetes con un tamaño de 8192 bytes. Hay 4 constructores de la clase DatagramPacket:
DatagramPacket(byte[] buf, int length, InetAddress addr, int port): de la matriz Buf, tome los datos de Longitud para crear un objeto de paquete de datos, el El objetivo es la dirección Addr y el puerto.
DatagramPacket(byte[] buf, int offset, int length, dirección InetAddress, puerto int): de la matriz Buf, extraiga los datos comenzando desde Offset y con una longitud de Longitud para crear un paquete de datos. El objetivo es la dirección Addr y el puerto.
DatagramPacket (byte [] buf, int offset, int length): carga los datos comenzando desde Offset y la longitud de Longitud en el paquete de datos en la matriz Buf.
DatagramPacket (byte [] buf, int length): carga los datos de longitud del paquete de datos en la matriz Buf.
El método más importante de la clase DatagramPacket es getData(), que obtiene la codificación de la matriz de bytes del mensaje de la instancia.
★Descripción de ejemplo simple
{Servidor recibiendo datos}
byte[] buf = new byte[1000]
DatagramSocket ds; = new DatagramSocket(12345);
//Iniciar monitoreo del puerto 12345
DatagramPacket ip = new DatagramPacket(buf, buf.length
/ /Crear); una instancia para recibir datagramas
while (true)
{
ds.receive(ip
//Bloqueo, hasta); los datos se reciben y los datos se cargan en la IP
System.out.println(new String(buf)); client}
InetAddress target = InetAddress.getByName("www.xxx.com");
//Obtiene la instancia de dirección de la máquina de destino
DatagramSocket ds = new DatagramSocket(9999);
//Enviar datagrama desde el puerto 9999
String hello = "¡Hola, ya voy!";
/ /Datos a enviar
byte[] buf = hello.getBytes();
//Convertir datos a tipo Byte
op = new DatagramPacket(buf , buf.length, target, 12345);
//Empaquetar los datos en el búfer BUF
ds.send(op); datos
ds.close();
//Cerrar la conexión