Mensajería

De Wiki de Sistemas Operativos
Saltar a: navegación, buscar

Es una unidad de información que se intercambia entre dos o más procesos.

Mediante los mensajes podemos transmitir información y sincronizar procesos (mediante la espera de un cierto mensaje).

Los sistemas operativos generalmente ofrecen dos llamadas al sistema (o primitivas básicas) para los procesos, enviar y recibir mensajes:

  • send(mensaje): Para enviar un mensaje
  • receive(mensaje): Para recibir un mensaje

Destino y fuente

  • Denominación Directa
    • Se emplea ID para identificar al destinatario.
    • Valores especiales: BROADCAST (a todos), MULTICAST (a un grupo).
  • Denominación Indirecta
    • Se emplea un elemento intermediario.
    • Recurso compartido especial en el sistema: BUZÓN.
    • Habiendo intermediarios, hay que comprobar las identidades pues pueden ser falsas/erróneas

Formas de transmisión

  • Transmisión por copia
    • Directa: el mensaje se copia de espacio de emisor a espacio de receptor.
    • Indirecta: el mensaje se copia de espacio de emisor a espacio (buzón) de SO, y de ahí a espacio de receptor.
  • Transmisión por referencia
    • Directa: lo que se copia es un puntero al mensaje
    • Global: el emisor crea mensaje en espacio de SO, y se copia a espacio de receptor un puntero al mismo.
  • Transmisión por copia de escritura: el mensaje sólo se copia si se modifica por emisor o receptor.

Formas de comunicación

  • Comportamiento del emisor, send()
    • Síncrona: el proceso emisor que realiza el send() queda bloqueado hasta que el receptor llama a recv()
    • Asíncrona: suponemos capacidad de almacenamiento en el destinatario o en el buzón. Allí acumulamos los mensajes entrantes y el receptor irá leyendo cuando pueda. Es más ágil pero el destinatario/buzón necesita capacidad de almacenamiento, la cual será limitada y los mensajes posteriores pueden caer en saco roto
  • Comportamiento del receptor, recv()
    • Bloqueante: un recv() sin mensajes a procesar pasa a estado bloqueado. Si se hace un send() vuelve a estado preparado
    • No bloqueante: recv() sin mensajes a procesar devuelve un "prueba más tarde"

Formato de los mensajes

Fijo

Los procesos acuerdan emplear un formato fijo para sus mensajes.

Ejemplo: Simple Network Time Protocol. Ver http://tools.ietf.org/html/rfc4330, sección 4, Message Format.

                          1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9  0  1
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |LI | VN  |Mode |    Stratum    |     Poll      |   Precision    |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                          Root  Delay                           |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                       Root  Dispersion                         |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                     Reference Identifier                       |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                                |
     |                    Reference Timestamp (64)                    |
     |                                                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                                |
     |                    Originate Timestamp (64)                    |
     |                                                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                                |
     |                     Receive Timestamp (64)                     |
     |                                                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                                |
     |                     Transmit Timestamp (64)                    |
     |                                                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                 Key Identifier (optional) (32)                 |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |                                                                |
     |                                                                |
     |                 Message Digest (optional) (128)                |
     |                                                                |
     |                                                                |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Variable

  • Type-Length-Value.

Ejemplo: Usado en Netlink para la codificación de atributos de un mensaje. Ver Communicating between the kernel and user-space in Linux using Netlink Sockets (1984.lsi.us.es/~pablo/docs/spae.pdf).

   0                   1                   2                   3   
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                Length         |            Type               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  /                                                               /
  /                             Value                             /
  /                                                               /
  /////////////////////////////////////////////////////////////////
  • Text-based human-readable.

Mixto

Los procesos acuerdan emplear mensaje con partes cuyo formato es fijo, como por ejemplo una cabecera inicial, seguido de partes de tamaño variable.

Ejemplo: Internet Protocol (IPv4). Ver http://www.ietf.org/rfc/rfc791.txt, sección 3.1.

   0                   1                   2                   3   
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |Version|  IHL  |Type of Service|          Total Length         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |         Identification        |Flags|      Fragment Offset    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Time to Live |    Protocol   |         Header Checksum       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                       Source Address                          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                    Destination Address                        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                    Options                    |    Padding    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  /                                                               /
  /                         Payload                               /
  /                                                               /
  /////////////////////////////////////////////////////////////////

Mensajería a través de la red

  • Unidad del destinatario
  • Fiabilidad en la transmisión
  • Formato de los datos (http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html): Enviar un entero a través de la red puede ser un problema debido a la forma en el que se representan los datos en la memoria dependiente de la arquitectura. Por ejemplo, un PC con arquitectura Intel x86 emplea formato little-endian, mientras que un SPARC de Sun Microsystems (ahora Oracle) emplea big-endian.
    • Little Endian: Bytes menos significativo al principio.
int main(void)
{
        int a = 10, i;
        char *p = &a;

        for (i=0; i<sizeof(a); i++) {
                printf("posición %d: %.2x\n", i, p[i]);
        }
}

Muestra el siguiente resultado en un PC:

posición 0: 0a (n+3)
posición 1: 00 (n+2)
posición 2: 00 (n+1)
posición 3: 00 (n)
    • Big Endian: Bytes menos significativo al final.
posición 0: 00 (n)
posición 1: 00 (n+1)
posición 2: 00 (n+2)
posición 3: 0a (n+3)

En Internet se sigue la convención de expresar datos en Big Endian, habría que hacer la conversión. Habría que usar ntohl (network to host long).

En little-endian, la implementación de ntohl es la siguiente:

  1. define __constant_ntohl(x) ___constant_swab32((__be32)(x)

Ver /usr/include/linux/byteorder/little_endian.h

mientras que en big-endian es:

  1. define __constant_ntohl(x) ((__u32)(__be32)(x))

Si empleamos formato textuales, como CSV, XML o JSON, que codifican la información en bytes, no tenemos este problema.