GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué no veo MSG_EOR para SOCK_SEQPACKET en Linux?

Con SOCK_SEQPACKET sockets de dominio unix, la única forma de que el mensaje se interrumpa es si el búfer que le da a recvmsg() no es lo suficientemente grande (y en ese caso obtendrá MSG_TRUNC).

POSIX dice que los sockets SOCK_SEQPACKET deben establecer MSG_EOR al final de un registro, pero los sockets de dominio Linux unix no lo hacen.

(Referencias:POSIX 2008 2.10.10 dice que SOCK_SEQPACKET debe admitir registros, y 2.10.6 dice que los límites de registro son visibles para el receptor a través del indicador MSG_EOR).

Lo que significa un 'registro' para un protocolo determinado depende de la implementación para definirlo.

Si Linux implementara MSG_EOR para los sockets de dominio de Unix, creo que la única forma sensata sería decir que cada paquete era un registro en sí mismo y, por lo tanto, siempre establecía MSG_EOR (o tal vez siempre lo establecía cuando no configuraba MSG_TRUNC), por lo que sería No será informativo de todos modos.


Cuando leas los documentos, SOCK_SEQPACKET difiere de SOCK_STREAM de dos maneras distintas. En primer lugar -

Ruta de transmisión de datos secuenciada, fiable y bidireccional basada en conexión para datagramas de longitud máxima fija; se requiere que un consumidor lea un paquete completo con cada llamada al sistema de entrada .

-- socket(2) del proyecto de páginas de manual de Linux

alias

Para sockets basados ​​en mensajes, como SOCK_DGRAM y SOCK_SEQPACKET, el mensaje completo debe leerse en una sola operación. Si un mensaje es demasiado largo para caber en los búfer proporcionados y MSG_PEEK no está configurado en el argumento de banderas, los bytes sobrantes se descartarán y MSG_TRUNC se configurará en el miembro msg_flags de la estructura msghdr.

-- recvmsg() en el estándar POSIX.

En este sentido es similar a SOCK_DGRAM .

En segundo lugar, cada "datagrama" (Linux) / "mensaje" (POSIX) lleva una bandera llamada MSG_EOR .

Sin embargo Linux SOCK_SEQPACKET para AF_UNIX no implementa MSG_EOR . Los documentos actuales no coinciden con la realidad :-)

Supuestamente algunos SOCK_SEQPACKET las implementaciones hacen el otro. Y algunos implementan ambos. Eso cubre todas las diferentes combinaciones posibles :-)

[1] Los protocolos orientados a paquetes generalmente usan lecturas de nivel de paquete con semántica de truncamiento/descarte y sin MSG_EOR. Los sockets de dominio X.25, Bluetooth, IRDA y Unix usan SOCK_SEQPACKET de esta manera.

[2] Los protocolos orientados a registros generalmente usan lecturas de flujo de bytes y MSG_EOR

  • sin visibilidad a nivel de paquete, sin truncamiento/descarte. DECNet e ISO TP usan SOCK_SEQPACKET de esa manera.

[3] Los híbridos de paquete/registro generalmente usan SOCK_SEQPACKET con semántica de truncamiento/descarte en el nivel de paquete, y paquetes de terminación de registro marcados con MSG_EOR. SPX y XNS SPP usan SOCK_SEQPACKET de esta manera.

https://mailarchive.ietf.org/arch/msg/tsvwg/9pDzBOG1KQDzQ2wAul5vnAjrRkA

Has mostrado un ejemplo del párrafo 1.

El párrafo 2 también se aplica a SOCK_SEQPACKET como se define para SCTP. Aunque por defecto pone MSG_EOR en cada sendmsg() . La opción para deshabilitar esto se llama SCTP_EXPLICIT_EOR .

El párrafo 3, el más consistente con los documentos, parece ser el caso más oscuro.

E incluso los documentos no son coherentes con ellos mismos.

El tipo de socket SOCK_SEQPACKET es similar al tipo SOCK_STREAM y también está orientado a la conexión. El único La diferencia entre estos tipos es que los límites de registro se mantienen utilizando el tipo SOCK_SEQPACKET . Un registro puede enviarse mediante una o más operaciones de salida y recibirse mediante una o más operaciones de entrada, pero una sola operación nunca transfiere partes de más de un registro. Los límites de registro son visibles para el receptor a través del indicador MSG_EOR en los indicadores de mensajes recibidos devueltos por la función recvmsg(). -- Estándar POSIX


Eso no es para lo que sirve MSG_EOR.

Recuerde que la API de sockets es una abstracción de varios protocolos diferentes, incluidos los sockets del sistema de archivos UNIX, los pares de sockets, TCP, UDP y muchos protocolos de red diferentes, incluido X.25 y algunos completamente olvidados.

MSG_EOR es para señalar el final del registro cuando eso tiene sentido para el protocolo subyacente. Es decir. es pasar un mensaje a la siguiente capa hacia abajo que "esto completa un registro". Esto puede afectar, por ejemplo, al almacenamiento en búfer, provocando el vaciado de un búfer. Pero si el protocolo en sí no tiene un concepto de "registro", no hay razón para esperar que la bandera se propague.

En segundo lugar, si usa SEQPACKET debe lee todo el mensaje de una vez. Si no lo hace, el resto será descartado. Eso está documentado. En particular, MSG_EOR no una bandera para decirle que esta es la última parte del paquete.

Consejo:obviamente está escribiendo una versión que no es SEQPACKET para usar en MacOS. Le sugiero que descargue la versión SEQPACKET, ya que solo duplicará la carga de mantenimiento y codificación. SOCK_STREAM está bien para todas las plataformas.


Linux
  1. ¿Por qué Linux? – Algunas razones para convertir a Linux

  2. Linux:¿por qué usamos Su y no solo Su?

  3. Linux:¿por qué el USB no funciona en Linux cuando funciona en Uefi/bios?

  4. ¿Por qué pr_debug del kernel de Linux no da ningún resultado?

  5. ¿Por qué esta expresión regular no funciona en Linux?

Por qué me encanta usar bspwm para mi administrador de ventanas de Linux

¿Por qué elegir Xfce para su escritorio ligero de Linux?

Por qué elegir Budgie para su escritorio Linux

Por qué usar el escritorio Pantheon para Linux Elementary OS

El propio "GNOME OS" de GNOME no es una distribución de Linux para todos [Revisión]

¿Por qué ve el error:no se encontró el complemento "xyz"?