Tema 4
El paradigma cliente-servidor
F. García-Carballeira, Mª. Soledad Escolar,
Luis Miguel Sánchez, Fco. Javier García
Contenido
Conceptos básicos
Tipo de servidores
Servidores
secuenciales
y
concurrentes
Servidores
orientados a conexión y sin conexión
Servidores
con/sin información de estado
Sesión:
interacción entre cliente y servidor
Ejemplo:
Cliente-servidor con
paso de mensajes
Una definición
simple
…
“El software del
servidor
acepta
peticiones de
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
“El software del
servidor
acepta
peticiones de
servicio
desde el software del cliente, calcula el
resultado y lo devuelve al
cliente
”
Participantes
Elementos de computación:
Cliente
Servidor
Red de interconexión
Red de interconexión
Máquina
cliente
Máquina del
servidor
Ejemplo: HTTP
Cliente
Servidor
1) Petición:
http://www.arcos.inf.uc3m.es
2) Respuesta
1)
Petición:
2)
Respuesta:
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
5
1)
Petición:
GET
/index.html HTTP/1.1
Host: www.example.com
User-Agent: nombre-cliente
[Línea en blanco]
2)
Respuesta:
HTTP/1.1 200 OK
Date: Fri, 31 Dec 2003 23:59:59 GMT
Content-Type: text/html
Content-Length: 1221
<html>
<body>
<h1>Página www.uc3m.es</h1>
(Contenido) . . .
Acceso distribuido vs.
computación distribuida
La computación de tipo
cliente-servidor
es
acceso distribuido
Cliente-Servidor
Asigna roles diferentes a los procesos que comunican:
cliente
y
servidor
Servidor:
Ofrece un servicio
Elemento
pasivo
: espera la llegada de peticiones
Cliente:
Solicita el servicio
Elemento
activo: invoca
peticiones
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Elemento
activo: invoca
peticiones
..
.
Petición de servicio
Proceso servidor
Proceso cliente
Servicio
Servidor
Cliente 1
Cliente 2
Conceptos previos
El modelo
cliente-servid
or
es una
abstracción
eficiente para
facilitar los servicios de red
La asignación de
roles
a
simétricos
simplifica la sincronización
Implementación mediante:
Sockets
Llamada a procedimientos remotos (
RPC
)
Llamada a procedimientos remotos (
RPC
)
Invocación de
métodos remotos
(RMI, CORBA, …).
Paradigma principalmente adecuado para
servicios
centralizados
Tipos de servidores de aplicaciones
En función del
número de peticiones
que es capaz de atender:
Secuencial: una petición
Concurrente: múltiples peticiones atendidas al mismo tiempo
En función de si existe una
conexión
preestablecida con el cliente
Servidores orientados a conexión
Servidores NO orientados a conexión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Servidores NO orientados a conexión
En función de si almacena o no el
estado
de la comunicación
Servidores con estado
Servidores sin estado
Modelo de servidor secuencial
El servidor sirve las peticiones
de forma secuencial
Mientras está atendiendo a un cliente
no
puede aceptar
peticiones de más clientes
petición
Cliente
petición
respuesta
Flujo de ejecución de un servidor
secuencial
Inicio de servicio
Aceptar petición de
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
11
Aceptar petición de
sesión
Procesar la petición del
cliente
Flujo de ejecución de un servidor
secuencial
Obtener el
resultado
Inicio de servicio
Aceptar petición de
resultado
+
Devolver la
respuesta al cliente
Aceptar petición de
sesión
Cliente-Servidor secuencial
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
servicio
while(){
aceptar_peticion()
tratar_peticion()
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
13
Cliente n
Cliente-Servidor secuencial
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
servicio
while(){
aceptar_peticion()
tratar_peticion()
}
Cliente n
Cliente-Servidor secuencial
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
servicio
while(){
aceptar_peticion()
tratar_peticion()
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
15
Cliente n
Modelo de servidor concurrente
El servidor crea un hijo que atiende la petición y envía la
respuesta al cliente
Se pueden atender múltiples peticiones
de forma concurrente
petición
servidor
Cliente
respuesta
Crea un proceso
hijo
Flujo de ejecución de un servidor
concurrente
Servidor concurrente
Inicio de servicio
Aceptar petición de
sesión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
17
Procesar la petición
del cliente 1
Crear thread
Trabajador 1
Procesar la petición
del cliente 2
Crear thread
Trabajador 2
Procesar la petición
del cliente n
Crear thread
Trabajador n
fin
fin
Flujo de ejecución de un servidor
concurrente
Servidor concurrente
Inicio de servicio
Aceptar petición de
sesión
Obtener el
resultado
+
Devolver la
respuesta al cliente
Procesar la petición
del cliente 1
Crear thread
Trabajador 1
Procesar la petición
del cliente 2
Crear thread
Trabajador 2
fin
Cliente-Servidor concurrente
while(){
aceptar_peticion()
pthread_create()
}
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
19
Cliente n
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
Cliente n
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
21
Hilo 1
Cliente n
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
Hilo 1
Cliente n
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
23
Hilo 1
Cliente n
Sesión de
servicio
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
Hilo 1
Cliente n
Sesión de
servicio
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
25
Hilo 1
Cliente n
Sesión de
servicio
Hilo 2
Cliente-Servidor concurrente
Servidor
Cliente 1
Cliente 2
Solicitud de
conexión
Sesión de
while(){
aceptar_peticion()
pthread_create()
}
Hilo 1
Cliente n
Sesión de
servicio
Hilo 2
Distintas
arquitecturas de SW
para construir servidores paralelos:
Un proceso
distribuidor
que acepta peticiones y las distribuye entre un
pool
de
procesos ligeros
Cada proceso ligero realiza las mismas tareas:
aceptar peticiones, procesarlas y
devolver su resultado
Segmentación
: cada trabajo se divide en una serie de fases, cada una de ellas se
procesa por un proceso ligero especializado
Diseño de servidores concurrentes
mediante
threads
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Trabajador
Núcleo
S
o
li
c
it
u
d
e
s
Núcleo
S
o
li
c
it
u
d
e
s
E/S
Núcleo
Distribuidor
S
o
li
c
it
u
d
e
s
E/S
E/S
27
Servidores orientados a conexión
En un servicio
orientado a conexión
, el cliente y el
servidor
establecen una conexión
(que puede ser lógica),
posteriormente
insertan o extraen datos
desde esa
conexión, y finalmente
la liberan
El flujo de tráfico se representa mediante un
identificador de
conexión
conexión
Los datos
no
incluyen información sobre la conexión
establecida
Direcciones origen y destino
Servidores sin conexión
En un protocolo
no orientado a conexión
los datos
son intercambiados usando paquetes
independientes
,
auto-contenidos
, cada uno de los cuales necesita
explícitamente la información de conexión
No existe acuerdo previo
Ejemplo:
IP
,
UDP
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Ejemplo:
IP
,
UDP
Concepto de sesión
Sesión
:
Interacción entre cliente y servidor
Cada
cliente
entabla una sesión separada e independiente
con el servidor
El cliente conduce
un diálogo
con el servidor hasta obtener el
servicio deseado
El
servidor
ejecuta indefinidamente:
El
servidor
ejecuta indefinidamente:
Bucle continuo para aceptar peticiones de las sesiones de los
clientes
Protocolo de servicio
Se necesita un
protocolo
para especificar las reglas que
deben observar el cliente y el servidor
durante una
sesión de servicio
En cada sesión el diálogo sigue un patrón especificado por el
protocolo
Los protocolos de Internet están publicados en las RFCs
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
31
Los protocolos de Internet están publicados en las RFCs
Definición del
protocolo de servicio
:
Localización del servicio
Tipos de servidores
Servidores
sin estado:
Cada mensaje de petición y respuesta es independiente de las
demás
Ejemplo:
HTTP
Servidores
con estado:
Servidores
con estado:
Debe mantener
información de estado
(por ej. anteriores
conexiones de clientes) para proporcionar su servicio
Información de estado
Información de
estado global
El servidor mantiene información
para todos los clientes
durante la vida del servidor
Ejemplo: servidor de tiempo
Información de
estado de sesión
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
33
Información de
estado de sesión
El servidor mantiene
información específica
para cada sesión
iniciada por los clientes
Arquitectura de SW
La
arquitectura de SW
de una aplicación cliente-servidor
consta de tres niveles:
Nivel de presentación:
cliente y servidor precisan una interfaz de usuario
Nivel de lógica de aplicación:
en
el lado del servidor
necesita procesarse
la petición del cliente, calcular el resultado y devolverlo al cliente. En el
lado del cliente
se necesita enviar al servicio la petición del usuario y
procesar el resultado (por ejemplo, mostrarlo por pantalla)
procesar el resultado (por ejemplo, mostrarlo por pantalla)
Nivel de servicio:
los servicios requeridos para dar soporte a la
Interfaz de usuario
Lógica de presentación
Arquitectura de las aplicaciones
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Lógica de aplicación
Lógica de servicio
¿Donde se ejecutan las tareas?
En el software del cliente (lado del cliente)
Responsabilidades en el cliente
Cliente:
Genera un mensaje de petición de servicio
Se conecta al servidor (dirección IP y puerto)
[Solo orientado
a conexión]
Envía el mensaje de petición de servicio
Espera por la respuesta
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Espera por la respuesta
Procesa la respuesta: imprimir, almacenar, etc.
Desconexión
[Solo orientado a conexión]
Responsabilidades en el servidor
Servidor:
1.
Espera conexiones entrantes de los clientes
Una conexión entrante es una petición de servicio
2.
Por cada conexión:
Genera un
thread
de servicio
[Solo servidores concurrentes]
El proceso principal:
El proceso principal:
Vuelve a esperar por nuevas conexiones entrantes
El
thread
de servicio:
1.
Procesa la petición
2.
Calcula el resultado
3.
Devuelve la respuesta al cliente
Aplicaciones cliente-servidor usando colas
de mensajes
Modelo proceso ligero distribuidor:
Cada petición al proceso ligero distribuidor supone la creación de un
proceso
ligero trabajador
El proceso ligero trabajador responde al proceso cliente
Procesa la petición
Envía la respuesta al servidor
Una vez finalizada la sesión con el cliente, el proceso ligero se destruye
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
39
Una vez finalizada la sesión con el cliente, el proceso ligero se destruye
Modelo
concurrente:
Los procesos distribuidor y trabajador ejecutan de
forma concurrente
Modelo
secuencial:
Ejemplo: sumar dos números
cliente
sumar(5,2)
5+2
servidor
Máquina A
Máquina B
NÚCLEO
5+2
Resultado = 7
NÚCLEO
RED
Ejemplo: Definición de tipos
#define
MAXSIZE
256
struct peticion
{
int a;
/*
operando 1
*/
int b;
/*
operando 2
*/
char q_name[MAXSIZE];
/*
nombre de la cola
cliente
donde debe enviar la respuesta
el servidor */
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
el servidor */
};
Ejemplo: Proceso servidor secuencial
#
include
“mensaje.h”
#
include
<
mqueue.h
>
void
main
(void) {
mqd_t
q_servidor;
/* cola de mensajes del servidor */
mqd_t
q_cliente;
/* cola de mensajes del cliente */
struct peticion
pet;
int
res;
struct mq_attr
attr;
attr.mq_maxmsg = 20;
attr.mq_msgsize = sizeof(struct peticion);
attr.mq_msgsize = sizeof(struct peticion);
q_servidor =
mq_open
(“SERVIDOR_SUMA”, O_CREAT|O_READ, 0700, &attr);
while(1
) {
mq_receive(
q_servidor, &pet, sizeof(pet), 0);
res = pet.a + pet.b;
/* se responde al cliente abriendo previamente su cola */
q_cliente =
mq_open
(pet.q_name, O_WRONLY);
Ejemplo: Proceso cliente
#
include
“mensaje.h”
#
include
<
mqueue.h
>
void
main
(void) {
mqd_t
q_servidor;
/* cola de mensajes del proceso servidor */
mqd_t
q_cliente;
/* cola de mensajes para el proceso cliente */
struct peticion
pet;
int
res;
struct mq_attr
attr;
attr.mq_maxmsg = 1;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(int);
q_cliente =
mq_open
(“CLIENTE_UNO”, O_CREAT|O_RDONLY, 0700, &attr);
q_servidor =
mq_open
(“SERVIDOR_SUMA”, O_WRONLY);
/* se rellena la petición */
pet.a = 5;
pet.b = 2; strcpy(pet.q_name, “CLIENTE_UNO”);
mq_send
(q_servidor, &pet, sizeof(struct petiticion), 0);
mq_receive
(q_cliente, &res, sizeof(int), 0);
mq_close
(q_servidor);
mq_close
(q_cliente);
mq_unlink
(“CLIENTE_UNO”);
}
Ejemplo II: Servidor concurrente
NÚCLEO
cliente
sumar(5,2)
5+2
Resultado = 7
servidor
Máquina A
Máquina B
RED
5+2
NÚCLEO
RED
Estructura de un servidor multihread
Proceso cliente
Cola del clienteProceso cliente
Cola del cliente Cola delProceso servidor
petición petición respuestaF. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
Cola del servidor respuesta respuesta Creación del thread Creación del thread
Thread que
sirve la petición
Thread que
sirve la petición
Cliente-servidor con colas de mensajes
Proceso cliente
Proceso servidor
Cola del cliente respuesta petición mensaje Proceso ligero principal while (1) { mq_receive Copia del mensaje principal mq_receivese crea el proceso ligero esperar la copia del mensaje }
Servidor multithread con colas de mensajes
(I)
#include “mensaje.h”
#include <
mqueue.h
>
#include <pthread.h>
#include <stdio.h>
/* mutex y variables condicionales para proteger la copia del mensaje*/
pthread_mutex_t
mutex_mensaje;
int
mensaje_no_copiado = TRUE;
/* TRUE con valor a 1 */
pthread_cond_t
cond_mensaje;
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
pthread_cond_t
cond_mensaje;
int main(void)
{
mqd_t
q_servidor;
/* cola del servidor */
struct peticion mess;
/* mensaje a recibir */
struct mq_attr q_attr;
/* atributos de la cola */
pthread_attr_t
t_attr;
/* atributos de los threads */
attr.mq_maxmsg = 20;
attr.mq_msgsize = sizeof(struct peticion));
Servidor multithread con colas de mensajes
(II)
q_servidor =
mq_open
(“SERVIDOR”, O_CREAT|O_RDONLY,
0700, &attr);
if (q_servidor == -1) {
perror(”No se puede crear la cola de servidor”);
return 1;
}
pthread_mutex_init(&mutex_mensaje, NULL);
pthread_cond_init(&cond_mensaje, NULL);
pthread_cond_init(&cond_mensaje, NULL);
pthread_attr_init(&attr);
/* atributos de los threads */
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
Servidor multithread con colas de mensajes
(III)
while
(TRUE) {
mq_receive
(q_servidor, &mess, sizeof(struct mensaje), 0);
pthread_create
(&thid, &attr,
tratar_mensaje
, &mess);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
}
}
Servidor multithread con colas de mensajes
(IV)
while
(TRUE) {
mq_receive
(q_servidor, &mess, sizeof(struct mensaje), 0);
pthread_create
(&thid, &attr,
tratar_mensaje
, &mess);
}
}
Servidor multithread con colas de mensajes
(V)
while
(TRUE) {
mq_receive
(q_servidor, &mess, sizeof(struct mensaje), 0);
pthread_create
(&thid, &attr,
tratar_mensaje
, &mess);
/* se espera a que el thread copie el mensaje */
pthread_mutex_lock
(&mutex_mensaje);
Sección crítica
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
pthread_mutex_lock
(&mutex_mensaje);
while
(mensaje_no_copiado)
pthread_cond_wait
(&cond_mensaje, &mutex_mensaje);
mensaje_no_copiado = TRUE;
pthread_mutex_unlock
(&mutex_mensaje);
} /* FIN while */
} /* Fin main */
Servidor multithread con colas de mensajes
(VI)
void
tratar_mensaje
(struct mensaje *mes){
struct peticion
mensaje;
/* mensaje local */
struct mqd_t
q_cliente;
/* cola del cliente */
int
resultado;
/* resultado de la operación */
/* el thread copia el mensaje a un mensaje local */
pthread_mutex_lock
(&mutex_mensaje);
memcpy
((char *) &mensaje, (char *)&mes, sizeof(struct
peticion));
peticion));
/* ya se puede despertar al servidor*/
mensaje_no_copiado = FALSE;
/* FALSE con valor 0 */
pthread_cond_signal
(&cond_mensaje);
Servidor multithread con colas de mensajes
(VII)
/* ejecutar la petición del cliente y preparar respuesta */
resultado = mensaje_local.a + mensaje_local.b;
/* Se devuelve el resultado al cliente */
/* Para ello se envía el resultado a su cola */
q_cliente =
mq_open
(mensaje_local.nombre, O_WRONLY);
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.
if (q_cliente == -1)
perror(”No se puede abrir la cola del cliente */
else {
mq_send(q_cliente, (char *) &resultado, sizeof(int), 0);
mq_close(q_cliente);
}
pthread_exit
(0);
}
Proceso cliente
#include “mensaje.h”
#include <mqueue.h>
void main(void) {
mqd_t q_servidor;
/* cola de mensajes del proceso servidor */
mqd_t q_cliente;
/* cola de mensajes para el proceso cliente */
struct peticion pet;
int res;
struct mq_attr attr;
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(int);
q_cliente =
mq_open
(“CLIENTE_UNO”, O_CREAT|O_RDONLY, 0700, &attr);
q_cliente =
mq_open
(“CLIENTE_UNO”, O_CREAT|O_RDONLY, 0700, &attr);
q_servidor =
mq_open
(“SERVIDOR_SUMA”, O_WRONLY);
/* se rellena la petición */
pet.a = 5;
pet.b = 2; strcpy(pet.q_name, “CLIENTE_UNO”);
mq_send
(q_servidor, &pet, sizeof(struct petiticion), 0);
mq_receive
(q_cliente, &res, sizeof(int), 0);
Guía de desarrollo de aplicaciones
cliente-servidor con paso de mensajes
1.
Identificar el cliente y el servidor
Cliente: elemento activo, varios
Servidor: elemento pasivo
2.
Protocolo del servicio
Identificar los tipos mensajes y la secuencia de intercambios de
mensajes (peticiones y respuestas)
3.
Elegir el tipo de servidor
F. García-Carballeira, Mª. Soledad Escolar, Luis Miguel Sánchez, Fco. Javier García
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0 España.