packages/net/remotectrl/src/servselect.c
thepeople 7dfd14a763 commit package to go along with the last commit, thanks fofware
git-svn-id: svn://svn.openwrt.org/openwrt/packages@19589 3c298f89-4303-0410-b956-a3cf2f4a3e73
2010-02-12 00:36:12 +00:00

195 lines
5.6 KiB
C

/*
* Javier Abellán. 14 de Abril de 2003
*
* Ejemplo de como un servidor puede manejar varios clientes con select().
* Este programa hace de servidor.
*/
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <Socket_Servidor.h>
#include <Socket.h>
#define MAX_CLIENTES 10
/* Prototipos de las funciones definidas en este fichero */
void nuevoCliente (int servidor, int *clientes, int *nClientes);
int dameMaximo (int *tabla, int n);
void compactaClaves (int *tabla, int *n);
/*
* Programa principal.
* Crea un socket servidor y se mete en un select() a la espera de clientes.
* Cuando un cliente se conecta, le atiende y lo añade al select() y vuelta
* a empezar.
*/
main()
{
int socketServidor; /* Descriptor del socket servidor */
int socketCliente[MAX_CLIENTES];/* Descriptores de sockets con clientes */
int numeroClientes = 0; /* Número clientes conectados */
fd_set descriptoresLectura; /* Descriptores de interes para select() */
int buffer; /* Buffer para leer de los socket */
int maximo; /* Número de descriptor más grande */
int i; /* Para bubles */
/* Se abre el socket servidor, avisando por pantalla y saliendo si hay
* algún problema */
socketServidor = Abre_Socket_Inet ("cpp_java");
if (socketServidor == -1)
{
perror ("Error al abrir servidor");
exit (-1);
}
/* Bucle infinito.
* Se atiende a si hay más clientes para conectar y a los mensajes enviados
* por los clientes ya conectados */
while (1)
{
/* Cuando un cliente cierre la conexión, se pondrá un -1 en su descriptor
* de socket dentro del array socketCliente. La función compactaClaves()
* eliminará dichos -1 de la tabla, haciéndola más pequeña.
*
* Se eliminan todos los clientes que hayan cerrado la conexión */
compactaClaves (socketCliente, &numeroClientes);
/* Se inicializa descriptoresLectura */
FD_ZERO (&descriptoresLectura);
/* Se añade para select() el socket servidor */
FD_SET (socketServidor, &descriptoresLectura);
/* Se añaden para select() los sockets con los clientes ya conectados */
for (i=0; i<numeroClientes; i++)
FD_SET (socketCliente[i], &descriptoresLectura);
/* Se el valor del descriptor más grande. Si no hay ningún cliente,
* devolverá 0 */
maximo = dameMaximo (socketCliente, numeroClientes);
if (maximo < socketServidor)
maximo = socketServidor;
/* Espera indefinida hasta que alguno de los descriptores tenga algo
* que decir: un nuevo cliente o un cliente ya conectado que envía un
* mensaje */
select (maximo + 1, &descriptoresLectura, NULL, NULL, NULL);
/* Se comprueba si algún cliente ya conectado ha enviado algo */
for (i=0; i<numeroClientes; i++)
{
if (FD_ISSET (socketCliente[i], &descriptoresLectura))
{
/* Se lee lo enviado por el cliente y se escribe en pantalla */
if ((Lee_Socket1 (socketCliente[i], (char *)&buffer, 100) > 0))
printf ("Cliente %d envía %s\n", i+1, buffer);
else
{
/* Se indica que el cliente ha cerrado la conexión y se
* marca con -1 el descriptor para que compactaClaves() lo
* elimine */
printf ("Cliente %d ha cerrado la conexión\n", i+1);
socketCliente[i] = -1;
}
}
}
/* Se comprueba si algún cliente nuevo desea conectarse y se le
* admite */
if (FD_ISSET (socketServidor, &descriptoresLectura))
nuevoCliente (socketServidor, socketCliente, &numeroClientes);
}
}
/*
* Crea un nuevo socket cliente.
* Se le pasa el socket servidor y el array de clientes, con el número de
* clientes ya conectados.
*/
void nuevoCliente (int servidor, int *clientes, int *nClientes)
{
/* Acepta la conexión con el cliente, guardándola en el array */
clientes[*nClientes] = Acepta_Conexion_Cliente (servidor);
(*nClientes)++;
/* Si se ha superado el maximo de clientes, se cierra la conexión,
* se deja todo como estaba y se vuelve. */
if ((*nClientes) >= MAX_CLIENTES)
{
close (clientes[(*nClientes) -1]);
(*nClientes)--;
return;
}
/* Envía su número de cliente al cliente */
// Escribe_Socket1 (clientes[(*nClientes)-1], (char *)nClientes, sizeof(int));
char pepe[] = "Mensaje del server uno";
/*
char mensa[] = "Mensaje del server uno";
struct s_msg *pepe;
pepe = calloc(pepe,12+strlen(mensa)+2);
pepe->type = 1;
pepe->command = 0;
pepe->len = strlen(mensa);
strcpy(pepe->data,mensa);
printf("int=%d s_msg=%d pepe=%d\n",sizeof(int),sizeof(struct s_msg), sizeof((struct s_msg *)pepe));
printf("type=%d command=%d len=%d data=%s\n", pepe->type, pepe->command, pepe->len, pepe->data);
*///
// pepe.data = strcpy(pepe.data,"Mensaje del server uno");
Escribe_Socket (clientes[(*nClientes)-1], pepe, strlen(pepe));
int escribio;
// escribio = WriteTcpSocket (clientes[(*nClientes)-1], 0,0, "Connected Ok" );
/* Escribe en pantalla que ha aceptado al cliente y vuelve */
// printf ("Aceptado cliente %d %d\n", *nClientes, escribio);
return;
}
/*
* Función que devuelve el valor máximo en la tabla.
* Supone que los valores válidos de la tabla son positivos y mayores que 0.
* Devuelve 0 si n es 0 o la tabla es NULL */
int dameMaximo (int *tabla, int n)
{
int i;
int max;
if ((tabla == NULL) || (n<1))
return 0;
max = tabla[0];
for (i=0; i<n; i++)
if (tabla[i] > max)
max = tabla[i];
return max;
}
/*
* Busca en array todas las posiciones con -1 y las elimina, copiando encima
* las posiciones siguientes.
* Ejemplo, si la entrada es (3, -1, 2, -1, 4) con *n=5
* a la salida tendremos (3, 2, 4) con *n=3
*/
void compactaClaves (int *tabla, int *n)
{
int i,j;
if ((tabla == NULL) || ((*n) == 0))
return;
j=0;
for (i=0; i<(*n); i++)
{
if (tabla[i] != -1)
{
tabla[j] = tabla[i];
j++;
}
}
*n = j;
}