udp - Protocolo UDP sobre IPv4
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
Ésta es una implementación del protocolo UDP (User Datagram
Protocol) descrito en RFC 768. Implementa un servicio de paquetes de
datagramas no fiable y sin conexión. Los paquetes pueden ser
reordenados o duplicados antes de que lleguen. UDP genera y comprueba sumas de
verificación (checksums) para detectar errores de transmisión.
Cuando se crea un conector (socket) UDP, sus direcciones local y remota
están sin especificar. Se pueden enviar datagramas inmediatamente
usando
sendto(2) o
sendmsg(2) con una dirección de
destino válida como argumento. Cuando se llama a
connect(2)
sobre el conector, se envía la dirección de destino por defecto
y a partir de ese momento se pueden enviar datagramas usando
send(2) o
write(2) sin especificar una dirección de destino.
Todavía es posible realizar envíos a otros destinos pasando una
dirección a
sendto(2) o
sendmsg(2). Para poder recibir
paquetes, se debe ligar primero el conector a una dirección local
usando
bind(2). De otra manera la capa de conector asignará
automáticamente un puerto local libre fuera del rango definido por
/proc/sys/net/ipv4/ip_local_port_range y ligará el conector a
INADDR_ANY.
Todas las operaciones de recepción sólo devuelven un paquete.
Cuando el paquete es más pequeño que el buffer pasado,
sólo se devuelven los datos del paquete y, cuando es mayor, el paquete
se trunca y la bandera
MSG_TRUNC se activa.
MSG_WAITALL no
está soportada.
Se pueden enviar o recibir opciones IP usando las opciones de conectores
descritas en
ip(7). Estas son procesadas por el núcleo
sólo cuando está activado el parámetro adecuado de
/proc (pero todavía se pasan al usuario incluso cuando
está desactivada). Vea
ip(7).
Cuando en un envío está activa la opción
MSG_DONTROUTE, la dirección de destino debe referirse a la
dirección de una interfaz local y el paquete sólo se
envía a esa interfaz.
Por defecto, la implementación UDP de Linux averigua el MTU (siglas en
inglés de 'unidad máxima de transmisión') de la ruta. Por
lo tanto, el núcleo hace un seguimiento del MTU para una IP concreta
emitiendo
EMSGSIZE cuando un paquete UDP lo sobrepasa, en cuyo caso la
aplicación debería reducir el tamaño de sus paquetes. Es
posible deshabilitar esta opción mediante la opción
IP_MTU_DISCOVER en el archivo
/proc/sys/net/ipv4/ip_no_pmtu_disc
, consulte
ip(7), en cuyo caso UDP fragmentará los paquetes
emitidos si sobrepasan el MTU de la interfaz. No es recomendable
deshabilitarlo ya que podría afectar negativamente al rendimiento y a
la fiabilidad.
UDP usa el formato de dirección
sockaddr_in de IPv4 descrito en
ip(7).
Todos los errores fatales serán pasados al usuario como un resultado de
error incluso cuando el conector no esté conectado. Ésto incluye
errores asíncronos recibidos de la red. Puede obtenerse un error por un
paquete anterior que fue enviado por el mismo conector. Este comportamiento
difiere de muchas otras implementaciones de BSD que no pasan ningún
error al menos que el conector esté conectado. El comportamiento de
Linux viene dado por el
RFC 1122.
Por compatibilidad con código anterior es posible activar la
opción
SO_BSDCOMPAT de
SOL_SOCKET para recibir errores
remotos (excepto
EPROTO y
EMSGSIZE) sólo cuando el
conector se ha conectado. Siempre se obvian los errores generados localmente.
En versiones posteriores del núcleo se quitó esta opción
del conector. Consulte
socket(7).
Cuando se activa la opción
IP_RECVERR todos los errores se
almacenan en la cola de errores de conector y se pueden recibir mediante
recvmsg(2) con la opción
MSG_ERRQUEUE activa.
Los parámetros de configuración de UDP en un equipo pueden verse
en los archivos del directorio
/proc/sys/net/ipv4/.
-
udp_mem (desde Linux 2.6.25)
- Es un vector con tres valores que gestiona la cantidad de
páginas que los conectores UDP pueden tener a la cola.
- min
- Por debajo de esa cantidad de páginas, UDP no se
preocupa de la cantidad de memoria que necesita. Si se sobrepasa, UDP
comenzará a limitar su uso.
- pressure
- Este valor se introdujo para seguir el formato de
tcp_mem. Consulte tcp(7).
- max
- Cantidad de paǵinas que pueden tener en cola todos
los conectores UDP.
- Los valores por defecto se calculan durante el inicio del
equipo en base a la cantidad de memoria disponible.
-
udp_rmem_min (número entero; valor por
defecto: TAMAÑO_PÁGINA; desde la versión 2.6.25 de
Linux)
- Tamaño minimo, en bytes, de los buffers de
recepción empleados por los conectores UDP en la moderación.
Cada uno de los conectores podrá emplear este tamaño para
recibir datos, aunque el total de páginas de los conectores UDP
exceda el valor 'pressure' de udp_mem.
-
udp_wmem_min (número entero; por defecto:
TAMAÑO_PÁGINA; a partir de la versión 2.6.25 de
Linux)
- Tamaño mínimo, en bytes, del buffer de
envío empleado por los conectores UDP en la moderación. Cada
conector puede emplear este tamaño para enviar datos aunque la
cantidad total de páginas de los conectores UDP sobrepase el valor
de 'pressure' para udp_mem.
Para definir u obtener la opción de un conector UDP deberá invocar
getsockopt(2) para obtenerla o
setsockopt(2) para definir la
opción con el argumento de la opción definido como
IPPROTO_UDP. Salvo que se indique lo contrario,
optval es un
puntero a un número
int.
A continuación se incluye una lista con las opciones de los conectores
específicas para UDP. Si desea ver otras opciones de los conectores
también aplicables a UDP: consulte
socket(7).
-
UDP_CORK (desde Linux 2.5.44)
- Si se activa esta opción, todos los datos de salida
de ese conector se juntan en un único datagrama que se tansmite
cuando la opción está deshabilitado. No debe emplearse esta
opción si desea que el código fuente sea portable.
Estos ioctls pueden ser utilizados con
ioctl(2). La sintaxis correcta es:
int value;
error = ioctl(udp_socket, ioctl_type, &value);
-
FIONREAD (SIOCINQ)
- Obtiene un puntero hacia un entero como argumento. Devuelve
el tamaño del siguiente datagrama, en bytes, pendiente del entero o
el valor 0 si no hay ninguno pendiente. Aviso: con FIONREAD
no es posible saber si no hay ningún datagrama pendiente o si el
siguiente datagrama contiene zero bytes de datos. Para distinguir ambos
casos, es preferible el uso de select(2), poll(2) o
epoll(7).
-
TIOCOUTQ (SIOCOUTQ)
- Devuelve el número de bytes de datos en la cola de
envío local. Sólo disponible en Linux 2.4 o superior.
Además todos los ioctls documentados en
ip(7) y
socket(7)
están soportados.
Una operación de enviar o recibir sobre un conector UDP puede devolver
cualquier error documentado en
socket(7) o
ip(7).
- ECONNREFUSED
- No se ha asociado un receptor a la dirección de
destino. Esto podría ser provocado por un paquete anterior enviado
por el conector.
IP_RECVERR es una nueva característica de la versión 2.2 de
Linux.
ip(7),
raw(7),
socket(7),
udplite(7)
Documentación del código fuente del núcleo
Documentation/networking/ip-sysctl.txt.
RFC 768 para el protocolo UDP.
RFC 1122 para los requisitos del anfitrión (host).
RFC 1191 para una descripción del descubrimiento de la MTU de la
ruta.
La traducción al español de esta página del manual fue
creada por Juan Piernas <
[email protected]>, Miguel Pérez Ibars
<
[email protected]> y Marcos Fouces <
[email protected]>
Esta traducción es documentación libre; lea la
GNU
General Public License Version 3 o posterior con respecto a las
condiciones de copyright. No existe NINGUNA RESPONSABILIDAD.
Si encuentra algún error en la traducción de esta página
del manual, envíe un correo electrónico a
[email protected]