Este repositorio contiene una práctica de comunicación tipo publish/subscribe implementada en C, utilizando los protocolos TCP y UDP. El propósito del laboratorio es comprender cómo se implementan mecanismos básicos de publicación y suscripción en la capa de aplicación, y observar las diferencias prácticas entre un protocolo orientado a conexión (TCP) y uno no orientado a conexión (UDP).
El repositorio incluye implementaciones de broker, publisher y subscriber para cada protocolo:
- TCP/
broker_tcp.c: actúa como intermediario central; acepta conexiones, gestiona suscripciones y reenvía mensajes a los clientes suscritos.publisher_tcp.c: se conecta al broker y envía mensajes con el formatotopic|message.subscriber_tcp.c: se conecta al broker, envíaSUBSCRIBE <topic>y muestra los mensajes reenviados.
- UDP/
broker_udp.c: recibe datagramas, registra las direcciones de los suscriptores y reenvía los mensajes.publisher_udp.c: envía datagramas en formatotopic|message.subscriber_udp.c: enlaza un puerto efímero, envíaSUBSCRIBE <topic>al broker y espera datagramas entrantes.
TCP
El broker TCP crea un socket de escucha con socket(..., SOCK_STREAM, ...), seguido de bind(), listen() y select()
para manejar múltiples conexiones simultáneas. Los clientes se conectan con connect().
Un suscriptor envía la cadena SUBSCRIBE <topic> al broker, quien registra su socket y el tema en una estructura Subscriber.
Cuando un publicador envía un mensaje en formato topic|message, el broker lo separa en ambos campos y lo reenvía
mediante send() a todos los suscriptores cuyo tema coincida.
Encabezados utilizados:
<sys/socket.h>: declara las funciones principales de la API de sockets (socket, bind, listen, accept, send, recv).<arpa/inet.h>: define estructuras y funciones de conversión comostruct sockaddr_in,htons()einet_pton().<sys/select.h>: permite el uso deselect()y los conjuntos de descriptoresfd_set, utilizados para multiplexar sockets.
UDP
En este caso, el broker UDP usa socket(..., SOCK_DGRAM, ...) y bind().
No existe una conexión persistente: el broker utiliza recvfrom() para recibir datagramas y conocer la dirección del remitente.
Si el mensaje recibido comienza con SUBSCRIBE <topic>, almacena la dirección del remitente junto con el tema.
Cuando un publicador envía topic|message, el broker utiliza sendto() para reenviar el datagrama a todos los suscriptores registrados.
Encabezados (librerías) utilizados:
<sys/socket.h>: proporciona las funcionessendto()yrecvfrom(), necesarias para enviar y recibir datagramas.<arpa/inet.h>: nuevamente usada para manipular direcciones IPv4 y conversiones de red.
TCP:
- El broker escucha en un puerto definido.
- Los suscriptores se conectan y envían su comando de suscripción (
SUBSCRIBE <topic>). - Los publicadores se conectan y envían mensajes con el formato
topic|message. - El broker reenvía los mensajes a todos los suscriptores registrados en el mismo tema.
UDP:
- El broker escucha datagramas en el puerto configurado.
- Los suscriptores envían
SUBSCRIBE <topic>al broker y registran su dirección local. - Los publicadores envían datagramas
topic|message. - El broker reenvía los datagramas a los suscriptores que coincidan con el tema.
-
Creación de socket:
- Servidor TCP:
server_fd = socket(AF_INET, SOCK_STREAM, 0); - Socket UDP:
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
- Servidor TCP:
-
Configuración de dirección:
serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr);
-
Recepción de datagrama UDP:
recvfrom(sockfd, buffer, BUFFER_SIZE - 1, 0, (struct sockaddr *)&client_addr, &addr_len);
-
Reenvío UDP a suscriptores:
sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&subs[i].addr, sizeof(subs[i].addr));
Compilar y ejecutar cada módulo en terminales separadas:
# Broker TCP
gcc TCP/broker_tcp.c -o broker_tcp
./broker_tcp
# Broker UDP
gcc UDP/broker_udp.c -o broker_udp
./broker_udpLuego, iniciar los clientes:
# Suscriptor TCP
gcc TCP/subscriber_tcp.c -o subscriber_tcp
./subscriber_tcp
# Publicador TCP
gcc TCP/publisher_tcp.c -o publisher_tcp
./publisher_tcp
# Suscriptor UDP
gcc UDP/subscriber_udp.c -o subscriber_udp
./subscriber_udp
# Publicador UDP
gcc UDP/publisher_udp.c -o publisher_udp
./publisher_udpEl código demuestra de forma práctica las diferencias entre comunicación confiable (TCP) y no confiable (UDP) dentro de un modelo de publicación/suscripción. Cada implementación hace uso directo de las llamadas al sistema POSIX para manejo de sockets, reforzando los conceptos de programación en red a bajo nivel.