El problema que se propone es la realización mediante socket de una aplicación con arquitectura cliente-servidor lo más sencilla posible para la mayor comprensión de este tipo de programación.
Para ello implementaremos un servidor ECHO multiprotocolo y con concurrencia aparente en el que podremos realizar conexiones con varios clientes que usen protocolo UDP o TCP, de forma simultanea.
Para aquellos que estén un poco perdidos, comentar que el servidor ECHO, es un servicio ya implementado en linux, el cual se limita a devolver el "string" que es enviado por un cliente, pero se realizará una implementación diferente.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "error.h"
#include "socket_utils.h"
#define MAX_BUFF_SIZE 128
int main(int argc, char *argv[]) {
struct sockaddr_in cli_addr;
unsigned int cli_size;
int ms, cs, auxsock, nfds, usock;/* sock. maestro, cliente y aux, y número total de descriptores en el sistema */
fd_set rfds; /* conjunto de sockets para lectura */
fd_set afds; /* conjunto de sockets activos */
char buff[MAX_BUFF_SIZE];
int n;
/* obtenemos número máximo de descriptores en el sistema */
nfds = getdtablesize();
FD_ZERO(&afds);
ms = passiveTCP("echo", 5);
usock = passiveUDP("echo");
FD_SET(ms, &afds);
while (1) {
FD_SET(usock,&afds);
memcpy(&rfds, &afds, sizeof(rfds));
if (select(FD_SETSIZE, &rfds, (fd_set*)0, (fd_set*)0, (struct timeval *) 0) == -1)
errexit("select: %s\n", strerror(errno));
/* Cliente TCP */
if (FD_ISSET(ms, &rfds)) {
/* hay actividad sobre el socket maestro*/
cli_size = sizeof (cli_addr);
cs = accept (ms, (struct sockaddr *)&cli_addr, &cli_size);
if (cs != -1)
FD_SET(cs, &afds);
}
/* Cliente UDP */
if (FD_ISSET(usock, &rfds)) {
cli_size = sizeof(cli_addr);
if (recvfrom(usock, buff, sizeof(buff), 0,(struct sockaddr *)&cli_addr, &cli_size) < auxsock="0;" if="" auxsock="" n="recv"> 0))
send (auxsock, buff, n, 0);
if (n == 0) {
close(auxsock);
FD_CLR(auxsock, &afds);
}
}
}
(void) close(ms);
}
0 comentarios:
Publicar un comentario