¡Recomienda este blog!

miércoles, 23 de marzo de 2011

Programación de Socket en C: Servidor multiprotocolo ECHO.

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