commit package to go along with the last commit, thanks fofware
authorthepeople <thepeople@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Fri, 12 Feb 2010 00:36:12 +0000 (00:36 +0000)
committerthepeople <thepeople@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Fri, 12 Feb 2010 00:36:12 +0000 (00:36 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/packages@19589 3c298f89-4303-0410-b956-a3cf2f4a3e73

14 files changed:
net/remotectrl/Makefile [new file with mode: 0644]
net/remotectrl/src/Makefile [new file with mode: 0644]
net/remotectrl/src/Makefile.inc [new file with mode: 0644]
net/remotectrl/src/Socket.c [new file with mode: 0644]
net/remotectrl/src/Socket.h [new file with mode: 0644]
net/remotectrl/src/Socket_Cliente.c [new file with mode: 0644]
net/remotectrl/src/Socket_Cliente.h [new file with mode: 0644]
net/remotectrl/src/Socket_Servidor.c [new file with mode: 0644]
net/remotectrl/src/Socket_Servidor.h [new file with mode: 0644]
net/remotectrl/src/clientselect.c [new file with mode: 0644]
net/remotectrl/src/remotectrl.c [new file with mode: 0644]
net/remotectrl/src/remotectrl.h [new file with mode: 0644]
net/remotectrl/src/server_socket.c [new file with mode: 0644]
net/remotectrl/src/servselect.c [new file with mode: 0644]

diff --git a/net/remotectrl/Makefile b/net/remotectrl/Makefile
new file mode 100644 (file)
index 0000000..4fc66fd
--- /dev/null
@@ -0,0 +1,48 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=chillisocket
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+define Package/chillisocket
+  SECTION:=Testing
+  CATEGORY:=Testing
+#  DEPENDS:=
+  TITLE:=Socket library server client
+endef
+
+TARGET_CPPFLAGS := \
+       -I$(STAGING_DIR)/usr/include/ \
+       -I$(LINUX_DIR)/include \
+       -I$(PKG_BUILD_DIR) \
+       $(TARGET_CPPFLAGS)
+
+define Build/Prepare
+       mkdir -p $(PKG_BUILD_DIR)
+       $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+       CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+       $(MAKE) -C $(PKG_BUILD_DIR) \
+               $(TARGET_CONFIGURE_OPTS) \
+               LIBS="$(TARGET_LDFLAGS) -lm"
+endef
+
+define Package/chillisocket/install
+       $(INSTALL_DIR) $(1)/bin
+#      $(INSTALL_BIN) $(PKG_BUILD_DIR)/libChSocket.a $(1)/bin/libChSocket.a
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/servselect $(1)/bin/servselect
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/clientselect $(1)/bin/clientselect
+endef
+
+$(eval $(call BuildPackage,chillisocket))
diff --git a/net/remotectrl/src/Makefile b/net/remotectrl/src/Makefile
new file mode 100644 (file)
index 0000000..017fd83
--- /dev/null
@@ -0,0 +1,30 @@
+ifndef CFLAGS
+CFLAGS = -O2 -g -I ../src
+endif
+VERSION=0.1
+
+LIBS=-lnl 
+
+# Ficheros objeto que van dentro de la minilibrería.
+LIBCHSOCK=\
+       Socket_Servidor.o\
+       Socket_Cliente.o\
+       Socket.o
+
+all: servselect clientselect server_socket
+# clientselect libChSocket.a
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c -o $@ $^
+
+#libChSocket.a : libChSocket.a($(LIBCHSOCK))
+
+servselect: servselect.o Socket_Servidor.o Socket.o
+       $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clientselect: clientselect.o Socket.o Socket_Cliente.o
+       $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+#      cc clientselect.c -I$(LIBCHSOCKET) -L$(LIBCHSOCKET) -lChSocket -o clientselect
+
+server_socket: server_socket.o remotectrl.o
+       $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
diff --git a/net/remotectrl/src/Makefile.inc b/net/remotectrl/src/Makefile.inc
new file mode 100644 (file)
index 0000000..ca56ed8
--- /dev/null
@@ -0,0 +1,17 @@
+prefix=/usr\r
+DESTDIR=\r
+\r
+COPTS=-O2\r
+WOPTS=-pedantic -Werror -Wall\r
+FPIC=-fPIC\r
+CFLAGS=$(COPTS) $(WOPTS) -std=gnu99\r
+\r
+AR=ar\r
+CC=gcc\r
+RANLIB=ranlib\r
+INSTALL=install\r
+MKDIR=mkdir\r
+\r
+LINK=$(CC)\r
+SHLIB_EXT=so\r
+SHLIB_FLAGS=-shared -Wl,-soname,$(SHLIB_FILE)\r
diff --git a/net/remotectrl/src/Socket.c b/net/remotectrl/src/Socket.c
new file mode 100644 (file)
index 0000000..2c6bb49
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+* Javier Abellan, 20 Jun 2000
+*
+* Funciones de lectura y escritura en sockets
+*
+* MODIFICACIONES:
+* 4 Septiembre 2003: Añadidas funciones para sockets UDP.
+*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h> 
+#include <sys/un.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "Socket.h"
+
+#define BUFFER_SIZE 13
+
+int ReadTcpSocket (int fd, char **Datos)
+{
+       int Leido = 0;
+       struct head_t *head;
+       int Aux=0;
+       char buffer[BUFFER_SIZE];
+       char *message;
+       message = malloc(BUFFER_SIZE);
+       while (1){
+               bzero(buffer, BUFFER_SIZE);
+               Aux = read(fd, buffer, BUFFER_SIZE-1);
+               if (Leido==0){
+                       message = memcpy(message, buffer, Aux);
+                       head = malloc(sizeof(struct head_t));
+                       head = memcpy(head,buffer,Aux);
+               } else {
+                       message = realloc(message,(strlen(message)+Aux));
+                       if (Aux == BUFFER_SIZE-1)
+                               message = strcat(message,buffer);
+                       else
+                               message = strncat(message,buffer,Aux);
+               }
+               Leido += Aux;
+
+printf("msg=%s Leido=%d\n", message, Leido); 
+               if (Aux < BUFFER_SIZE-1 || Leido == head->len )
+                       break;
+       }
+       *Datos=realloc(*Datos,Leido+1);
+       memcpy(*Datos,head,sizeof(struct head_t));
+       memcpy(*Datos+12, message, Leido);
+       return Leido;
+}
+
+int WriteTcpSocket(int fd, int type, int command, char *data){
+       int Escrito = 0;
+       int Aux = 0;
+
+       int Longitud = (sizeof(int)*3)+strlen((char *)data);
+       struct s_msg *Datos;
+       Datos = malloc(Longitud);
+       Datos->type = type;
+       Datos->command = command;
+       Datos->len = Longitud;
+       strcpy(Datos->data, data);
+       printf("Longitud=%d convertido Type=%d Command=%d Len=%d Data=%s\n",Longitud, Datos->type, Datos->command, Datos->len, Datos->data);
+       printf("Longitud=%d int=%d\n", Longitud,sizeof(int));
+/*
+       if ((fd == -1) || (Datos == NULL) || (Longitud < 1))
+               return -1;
+
+*/
+//printf("Data:%s", *Datos);
+       while (Escrito < Longitud)
+       {
+               Aux = write (fd, Datos + Escrito, Longitud - Escrito);
+               if (Aux > 0)
+               {
+               Escrito = Escrito + Aux;
+               }
+               else
+               {
+                       if (Aux == 0)
+                               return Escrito;
+                       else
+                               return -1;
+               }
+       }
+       free(Datos);
+       return Escrito;
+}
+
+/*
+* Lee datos del socket. Supone que se le pasa un buffer con hueco 
+*      suficiente para los datos. Devuelve el numero de bytes leidos o
+* 0 si se cierra fichero o -1 si hay error.
+*/
+int Lee_Socket1 (int fd, char *Datos, int Longitud)
+{
+       int Leido = 0;
+       int Aux = 0;
+
+
+       /*
+       * Comprobacion de que los parametros de entrada son correctos
+       */
+       if ((fd == -1) || (Datos == NULL) || (Longitud < 1))
+               return -1;
+
+       /*
+       * Mientras no hayamos leido todos los datos solicitados
+       */
+
+       while (Leido < Longitud)
+       {
+               Aux = read (fd, Datos + Leido, Longitud - Leido);
+               if (Aux > 0)
+               {
+                       /* 
+                       * Si hemos conseguido leer datos, incrementamos la variable
+                       * que contiene los datos leidos hasta el momento
+                       */
+                       Leido = Leido + Aux;
+               }
+               else
+               {
+                       /*
+                       * Si read devuelve 0, es que se ha cerrado el socket. Devolvemos
+                       * los caracteres leidos hasta ese momento
+                       */
+                       if (Aux == 0) 
+                               return Leido;
+                       if (Aux == -1)
+                       {
+                               /*
+                               * En caso de error, la variable errno nos indica el tipo
+                               * de error. 
+                               * El error EINTR se produce si ha habido alguna
+                               * interrupcion del sistema antes de leer ningun dato. No
+                               * es un error realmente.
+                               * El error EGAIN significa que el socket no esta disponible
+                               * de momento, que lo intentemos dentro de un rato.
+                               * Ambos errores se tratan con una espera de 100 microsegundos
+                               * y se vuelve a intentar.
+                               * El resto de los posibles errores provocan que salgamos de 
+                               * la funcion con error.
+                               */
+                               switch (errno)
+                               {
+                                       case EINTR:
+                                       case EAGAIN:
+                                               usleep (100);
+                                               break;
+                                       default:
+                                               return -1;
+                               }
+                       }
+               }
+       }
+
+       /*
+       * Se devuelve el total de los caracteres leidos
+       */
+       return Leido;
+}
+
+/*
+* Escribe dato en el socket cliente. Devuelve numero de bytes escritos,
+* o -1 si hay error.
+*/
+int Escribe_Socket (int fd, char *Datos, int Longitud)
+{
+       int Escrito = 0;
+       int Aux = 0;
+
+       /*
+       * Comprobacion de los parametros de entrada
+       */
+       if ((fd == -1) || (Datos == NULL) || (Longitud < 1))
+               return -1;
+
+       /*
+       * Bucle hasta que hayamos escrito todos los caracteres que nos han
+       * indicado.
+       */
+       while (Escrito < Longitud)
+       {
+               Aux = write (fd, Datos + Escrito, Longitud - Escrito);
+               if (Aux > 0)
+               {
+                       /*
+                       * Si hemos conseguido escribir caracteres, se actualiza la
+                       * variable Escrito
+                       */
+                       Escrito = Escrito + Aux;
+               }
+               else
+               {
+                       /*
+                       * Si se ha cerrado el socket, devolvemos el numero de caracteres
+                       * leidos.
+                       * Si ha habido error, devolvemos -1
+                       */
+                       if (Aux == 0)
+                               return Escrito;
+                       else
+                               return -1;
+               }
+       }
+
+       /*
+       * Devolvemos el total de caracteres leidos
+       */
+       return Escrito;
+}
+
+/**
+ * Lee un mensaje de un socket udp. Los parámetros que se pasan son:
+ * - Descriptor fd del socket del que se quiere leer.
+ * - Estructura Remoto, en la que se devolverá los datos del que ha enviado el
+ * mensaje que acabamos de leer.
+ * - Longitud_Remoto de la estructura anterior. Debe pasarse relleno con el tamaño
+ * de Remoto y se devolverá rellena con el tamaño de los datos en Remoto.
+ * - Buffer de Datos donde se quiere que aparezca el mensaje.
+ * - Longitud_Datos del buffer anterior.
+ *
+ * Devuelve el número de bytes leidos o -1 en caso de error.
+ */
+int Lee_Socket_Udp (
+       int fd, struct sockaddr *Remoto, socklen_t *Longitud_Remoto,
+       char *Datos, int Longitud_Datos)
+{
+       int Leido = 0;
+       int Aux = 0;
+
+       /*
+       * Comprobacion de que los parametros de entrada son correctos
+       */
+       if ((fd == -1) || (Datos == NULL) || (Longitud_Datos < 1)
+                       || (Remoto == NULL) || (Longitud_Remoto == NULL))
+       {
+               return -1;
+       }
+
+       /*
+       * Mientras no hayamos leido todos los datos solicitados
+       */
+       while (Leido < Longitud_Datos)
+       {
+               Aux = recvfrom (fd, Datos + Leido, Longitud_Datos - Leido, 0,
+                       Remoto, Longitud_Remoto);
+
+               if (Aux > 0)
+               {
+                       /* 
+                       * Si hemos conseguido leer datos, incrementamos la variable
+                       * que contiene los datos leidos hasta el momento
+                       */
+                       Leido = Leido + Aux;
+               }
+               else
+               {
+                       /*
+                       * Si read devuelve 0, es que se ha cerrado el socket. Devolvemos
+                       * los caracteres leidos hasta ese momento
+                       */
+                       if (Aux == 0) 
+                               return Leido;
+                       if (Aux == -1)
+                       {
+                               /*
+                               * En caso de error, la variable errno nos indica el tipo
+                               * de error. 
+                               * El error EINTR se produce si ha habido alguna
+                               * interrupcion del sistema antes de leer ningun dato. No
+                               * es un error realmente.
+                               * El error EGAIN significa que el socket no esta disponible
+                               * de momento, que lo intentemos dentro de un rato.
+                               * Ambos errores se tratan con una espera de 100 microsegundos
+                               * y se vuelve a intentar.
+                               * El resto de los posibles errores provocan que salgamos de 
+                               * la funcion con error.
+                               */
+                               switch (errno)
+                               {
+                                       case EINTR:
+                                       case EAGAIN:
+                                               usleep (100);
+                                               break;
+                                       default:
+                                               return -1;
+                               }
+                       }
+               }
+       }
+
+       /*
+       * Se devuelve el total de los caracteres leidos
+       */
+       return Leido;
+}
+
+/**
+* Escribe dato en el socket cliente. Devuelve numero de bytes escritos,
+* o -1 si hay error.
+* - fd es el descriptor del socket.
+* - Remoto es el destinatario del mensaje, a quién se lo queremos enviar. 
+* - Longitud_Remoto es el tamaño de Remoto en bytes.
+* - Datos es el mensaje que queremos enviar.
+* - Longitud_Datos es el tamaño del mensaje en bytes.
+*/
+int Escribe_Socket_Udp (int fd, struct sockaddr *Remoto, 
+       socklen_t Longitud_Remoto, char *Datos, int Longitud_Datos)
+{
+       int Escrito = 0;
+       int Aux = 0;
+
+       /*
+       * Comprobacion de los parametros de entrada
+       */
+       if ((fd == -1) || (Datos == NULL) || (Longitud_Datos < 1) 
+                       || (Remoto == NULL) )
+   {
+               return -1;
+   }
+
+       /*
+       * Bucle hasta que hayamos escrito todos los caracteres que nos han
+       * indicado.
+       */
+       while (Escrito < Longitud_Datos)
+       {
+               Aux = sendto (fd, Datos + Escrito, Longitud_Datos - Escrito, 0,
+                       Remoto, Longitud_Remoto);
+
+               if (Aux > 0)
+               {
+                       /*
+                       * Si hemos conseguido escribir caracteres, se actualiza la
+                       * variable Escrito
+                       */
+                       Escrito = Escrito + Aux;
+               }
+               else
+               {
+                       /*
+                       * Si se ha cerrado el socket, devolvemos el numero de caracteres
+                       * leidos.
+                       * Si ha habido error, devolvemos -1
+                       */
+                       if (Aux == 0)
+                               return Escrito;
+                       else
+         {
+                               return -1;
+         }
+               }
+       }
+
+       /*
+       * Devolvemos el total de caracteres leidos
+       */
+       return Escrito;
+}
+
+
+/**
+ * Rellena una estructura sockaddr_in con los datos que se le pasan. Esta estrutura es
+ * útil para el envio o recepción de mensajes por sockets Udp o para abrir conexiones.
+ * Se le pasa el host. Puede ser NULL (para abrir socket servidor Udp o para recepción de
+ * mensajes de cualquier host).
+ * Se le pasa el servicio. Puede ser NULL (para abrir socket cliente Udp).
+ * Se le pasa una estructura sockaddr_in que devolverá rellena.
+ * Se le pasa una Longitud. Debe contener el tamaño de la estructura sockaddr_in y
+ * devolverá el tamaño de la estructura una vez rellena.
+ * Devuelve -1 en caso de error.
+ */
+int Dame_Direccion_Udp (char *Host, char *Servicio, struct sockaddr_in *Servidor,
+   int *Longitud_Servidor)
+{
+   struct servent *Puerto;
+   struct hostent *Maquina;
+  
+   /* Comprobación de parámetros */
+   if (Servidor == NULL) return -1;
+
+   /* Relleno del primer campo de la estructura */
+   Servidor->sin_family = AF_INET;
+
+   /* Si nos han pasado un host ... */
+   if (Host != NULL)
+   {
+      /* ... obtenemos la dirección del host y la ponemos en la estructura */
+      Maquina = gethostbyname (Host);
+      if (Maquina == NULL)
+         return -1;
+
+      Servidor->sin_addr.s_addr = ((struct in_addr *)(Maquina->h_addr))->s_addr;
+   }
+   else
+      /* Si no nos han pasado un host, ponemos cualquier host. */
+      Servidor->sin_addr.s_addr = INADDR_ANY;
+
+   /* Si servicio en NULL, hacemos que el puerto lo eliga el sistema operativo
+    libremente.*/
+   if (Servicio == NULL)
+      Servidor->sin_port = 0;
+   else
+   {
+      /* Si el servicio no es NULL, lo obtenemos. */
+      Puerto = getservbyname (Servicio, "udp");
+      if (Puerto == NULL)
+         return -1;
+      Servidor->sin_port = Puerto->s_port;
+   }
+}
diff --git a/net/remotectrl/src/Socket.h b/net/remotectrl/src/Socket.h
new file mode 100644 (file)
index 0000000..d83d62a
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * Javier Abellán, 20 Junio 2000
+ *
+ * Funciones de lectura y escritura de la librería de sockets.
+ *
+ * MODIFICACIONES:
+ * 4 de Septiembre de 2003. Añadidas funciones Lee_Socket_Udp(), 
+ *    Escribe_Socket_Udp() y Dame_Direccion_Udp()
+ */
+#ifndef _SOCKET_H
+#define _SOCKET_H
+
+#include <sys/socket.h>
+
+/*
+enum 
+{
+       MSG_OK = 0,
+       MSG_QRY,
+       MSG_START,
+       MSG_PART,
+       MSG_END,
+};
+int ReadTcpSocket(int fd, char **msg);
+int WriteTcpSocket(int fd, struct *Datos);
+*/
+struct head_t {
+       int type;
+       int command;
+       int len;
+};
+
+struct s_msg {
+       int type;
+       int command;
+       int len;
+       char data[30];
+};
+
+int ReadTcpSocket (int fd, char **Datos);
+int WriteTcpSocket (int fd, int type, int command, char *Datos);
+
+/** Lee Datos de tamaño Longitud de un socket cuyo descriptor es fd.
+ * Devuelve el numero de bytes leidos o -1 si ha habido error */
+int Lee_Socket1 (int fd, char *Datos, int Longitud);
+
+/** Envia Datos de tamaño Longitud por el socket cuyo descriptor es fd.
+ * Devuelve el número de bytes escritos o -1 si ha habido error. */
+int Escribe_Socket (int fd, char *Datos, int Longitud);
+
+/** Lee un mensaje de un socket UDP.
+ * Se le pasa el descriptor fd del socket que atiende los mensajes.
+ * Se le pasa uns estructura sockaddr que nos devolverá rellena con los datos del que nos
+ * ha enviado el mensaje, de forma que podamos responderle.
+ * Se le pasa el tamaño de la estructura Remoto. En la misma variable nos devolverá el
+ * tamaño de los datos devueltos.
+ * Se le pasa un buffer de datos para el mensaje y el tamaño en bytes que deseamos leer.
+ */
+int Lee_Socket_Udp (int fd, struct sockaddr *Remoto, socklen_t *Longitud_Remoto, 
+       char *Datos, int Longitud_Datos);
+
+/** Envia un mensaje por un socket UDP
+ * Se le pasa el descriptor de socket por el que debe enviar.
+ * Se le pasa el destinatario del mensaje en una estructura Remoto.
+ * Se le pasa el tamaño de dicha estructura en Longitud_Remoto.
+ * Se le pasa el buffer de datos que debe enviar en Datos.
+ * Se le pasa la longitud del buffer de datos en Longitud.
+ * Devuelve el número de bytes enviados o -1 si ha habido algún error.
+ */
+int Escribe_Socket_Udp (int fd, struct sockaddr *Remoto, 
+       socklen_t Longitud_Remoto, char *Datos, int Longitud);
+
+/**
+ * Rellena una estructura sockaddr_in con los datos que se le pasan. Esta estrutura es
+ * útil para el envio o recepción de mensajes por sockets Udp o para abrir conexiones.
+ * Se le pasa el host. Puede ser NULL (para abrir socket servidor Udp o para recepción de
+ * mensajes de cualquier host).
+ * Se le pasa el servicio. Puede ser NULL (para abrir socket cliente Udp).
+ * Se le pasa una estructura sockaddr_in que devolverá rellena.
+ * Se le pasa una Longitud. Debe contener el tamaño de la estructura sockaddr_in y
+ * devolverá el tamaño de la estructura una vez rellena.
+ * Devuelve -1 en caso de error.
+ */
+int Dame_Direccion_Udp (char *Host, char *Servicio, struct sockaddr_in *Servidor,
+   int *Longitud);
+#endif
diff --git a/net/remotectrl/src/Socket_Cliente.c b/net/remotectrl/src/Socket_Cliente.c
new file mode 100644 (file)
index 0000000..2919c72
--- /dev/null
@@ -0,0 +1,131 @@
+/* Javier Abellán, 20 Junio 2000
+ *
+ * Funciones para abrir/establecer sockets de un cliente con un servidor.
+ *
+ * MODIFICACIONES:
+ * 4 Septiembre 2003. Añadida función Abre_Conexion_Udp()
+ */
+
+
+/*
+* Includes del sistema
+*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+/*
+* Conecta con un servidor Unix, en la misma maquina.
+*      Devuelve descriptor de socket si todo es correcto, -1 si hay error.
+*/
+int Abre_Conexion_Unix (char *Servicio)
+{
+       struct sockaddr_un Direccion;
+       int Descriptor;
+
+       strcpy (Direccion.sun_path, Servicio);
+       Direccion.sun_family = AF_UNIX;
+
+       /* Se abre el descriptor del socket */
+       Descriptor = socket (AF_UNIX, SOCK_STREAM, 0);
+       if (Descriptor == -1)
+               return -1;
+
+       /* Se establece la conexion.
+        * Devuelve 0 si todo va bien, -1 en caso de error */
+       if (connect (
+                       Descriptor, 
+                       (struct sockaddr *)&Direccion, 
+                       strlen (Direccion.sun_path) + sizeof (Direccion.sun_family)) == -1)
+       {
+               return -1;
+       }
+
+       return Descriptor;
+}
+
+/*
+* Conecta con un servidor remoto a traves de socket INET
+*/
+int Abre_Conexion_Inet (
+       char *Host_Servidor, 
+       char *Servicio)
+{
+       struct sockaddr_in Direccion;
+       struct servent *Puerto;
+       struct hostent *Host;
+       int Descriptor;
+
+/*
+       Puerto = getservbyname (Servicio, "tcp");
+       Puerto = 15557;
+       if (Puerto == NULL)
+               return -1;
+*/
+
+       Host = gethostbyname (Host_Servidor);
+       if (Host == NULL)
+               return -1;
+
+       Direccion.sin_family = AF_INET;
+       Direccion.sin_addr.s_addr = ((struct in_addr *)(Host->h_addr))->s_addr;
+//     Direccion.sin_port = Puerto->s_port;
+       Direccion.sin_port = 15557;
+       
+       Descriptor = socket (AF_INET, SOCK_STREAM, 0);
+       if (Descriptor == -1)
+               return -1;
+
+       if (connect (
+                       Descriptor, 
+                       (struct sockaddr *)&Direccion, 
+                       sizeof (Direccion)) == -1)
+       {
+               return -1;
+       }
+
+       return Descriptor;
+}
+
+
+/*
+ * Prepara un socket para un cliente UDP.
+ * Asocia un socket a un cliente UDP en un servicio cualquiera elegido por el sistema,
+ * de forma que el cliente tenga un sitio por el que enviar y recibir mensajes.
+ * Devuelve el descriptor del socket que debe usar o -1 si ha habido algún error.
+ */
+int Abre_Conexion_Udp ()
+{
+       struct sockaddr_in Direccion;
+       int Descriptor;
+
+       /* Se abre el socket UDP (DataGRAM) */
+       Descriptor = socket (AF_INET, SOCK_DGRAM, 0);
+       if (Descriptor == -1)
+       {
+               return -1;
+       }
+
+       /* Se rellena la estructura de datos necesaria para hacer el bind() */
+       Direccion.sin_family = AF_INET;            /* Socket inet */
+       Direccion.sin_addr.s_addr = htonl(INADDR_ANY);    /* Cualquier dirección IP */
+       Direccion.sin_port = htons(0);                    /* Dejamos que linux eliga el servicio */
+
+       /* Se hace el bind() */
+       if (bind (
+                       Descriptor, 
+                       (struct sockaddr *)&Direccion, 
+                       sizeof (Direccion)) == -1)
+       {
+               close (Descriptor);
+               return -1;
+       }
+
+       /* Se devuelve el Descriptor */
+       return Descriptor;
+}
diff --git a/net/remotectrl/src/Socket_Cliente.h b/net/remotectrl/src/Socket_Cliente.h
new file mode 100644 (file)
index 0000000..18004aa
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Javier Abellán. 14 Abril 2003
+ *
+ * Funciones para que un cliente pueda abrir sockets con un servidor.
+ */
+#ifndef _SOCKET_CLIENTE_H
+#define _SOCKET_CLIENTE_H
+
+#include <sys/socket.h>
+
+/**
+ * Abre un socket UNIX con un servidor que esté en la misma máquina y que atienda al
+ * servicio de nombre Servicio. 
+ */
+int Abre_Conexion_Unix (char *Servicio);
+
+/**
+ * Abre un socket INET con un servidor que esté corriendo en Host_Servidor y que atienda
+ * al servicio cuyo nombre es Servicio. 
+ * Host_Servidor debe estar dado de alta en /etc/hosts.
+ * Servicio debe estar dado de alta en /etc/services como tcp.
+ */
+int Abre_Conexion_Inet (char *Host_Servidor, char *Servicio);
+
+#endif
diff --git a/net/remotectrl/src/Socket_Servidor.c b/net/remotectrl/src/Socket_Servidor.c
new file mode 100644 (file)
index 0000000..23bf094
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+* Javier Abellan, 20 Jun 2000
+*
+* Funciones para la apertura de un socket servidor y la conexion con sus
+* clientes
+*
+* MODIFICACIONES:
+* 4 Septiembre 2003: Añadida función Abre_Socket_Udp() 
+*/
+
+/* Includes del sistema */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+
+/*
+*      Abre socket servidor UNIX. Se le pasa el servicio que se desea atender. 
+* Deja el socket preparado
+* para aceptar conexiones de clientes.
+* Devuelve el descritor del socket servidor, que se debera pasar
+* a la funcion Acepta_Conexion_Cliente(). Devuelve -1 en caso de error
+*/
+int Abre_Socket_Unix (char *Servicio)
+{
+       struct sockaddr_un Direccion;
+       int Descriptor;
+
+       /*
+       * Se abre el socket
+       */
+       Descriptor = socket (AF_UNIX, SOCK_STREAM, 0);
+       if (Descriptor == -1)
+               return -1;
+
+       /*
+       * Se rellenan en la estructura Direccion los datos necesarios para
+       * poder llamar a la funcion bind()
+       */
+       strcpy (Direccion.sun_path, Servicio);
+       Direccion.sun_family = AF_UNIX;
+
+       if (bind (
+                       Descriptor, 
+                       (struct sockaddr *)&Direccion, 
+                       strlen (Direccion.sun_path) + sizeof (Direccion.sun_family)) == -1)
+       {
+               /*
+               * En caso de error cerramos el socket y devolvemos error
+               */
+               close (Descriptor);
+               return -1;
+       }
+
+       /*
+       * Avisamos al sistema que comience a atender peticiones de clientes.
+       */
+       if (listen (Descriptor, 1) == -1)
+       {
+               close (Descriptor);
+               return -1;
+       }
+
+       /*
+       * Se devuelve el descriptor del socket servidor
+       */
+       return Descriptor;
+}
+
+/*
+* Se le pasa un socket de servidor y acepta en el una conexion de cliente.
+* devuelve el descriptor del socket del cliente o -1 si hay problemas.
+* Esta funcion vale para socket AF_INET o AF_UNIX.
+*/
+int Acepta_Conexion_Cliente (int Descriptor)
+{
+       socklen_t Longitud_Cliente;
+       struct sockaddr Cliente;
+       int Hijo;
+
+       /*
+       * La llamada a la funcion accept requiere que el parametro 
+       * Longitud_Cliente contenga inicialmente el tamano de la
+       * estructura Cliente que se le pase. A la vuelta de la
+       * funcion, esta variable contiene la longitud de la informacion
+       * util devuelta en Cliente
+       */
+       Longitud_Cliente = sizeof (Cliente);
+       Hijo = accept (Descriptor, &Cliente, &Longitud_Cliente);
+       if (Hijo == -1)
+               return -1;
+
+       /*
+       * Se devuelve el descriptor en el que esta "enchufado" el cliente.
+       */
+       return Hijo;
+}
+
+/*
+* Abre un socket servidor de tipo AF_INET. Devuelve el descriptor
+*      del socket o -1 si hay probleamas
+* Se pasa como parametro el nombre del servicio. Debe estar dado
+* de alta en el fichero /etc/services
+*/
+int Abre_Socket_Inet (char *Servicio)
+{
+       struct sockaddr_in Direccion;
+       struct sockaddr Cliente;
+       socklen_t Longitud_Cliente;
+       struct servent *Puerto;
+       int Descriptor;
+
+       /*
+       * se abre el socket
+       */
+       Descriptor = socket (AF_INET, SOCK_STREAM, 0);
+       if (Descriptor == -1)
+               return -1;
+
+       /*
+       * Se obtiene el servicio del fichero /etc/services
+       */
+/*     
+       Puerto = getservbyname (Servicio, "tcp");
+
+       Puerto = 15557;
+
+       if (Puerto == NULL)
+               return -1;
+*/
+       /*
+       * Se rellenan los campos de la estructura Direccion, necesaria
+       * para la llamada a la funcion bind()
+       */
+/*
+       struct hostent *Host;
+       Host = gethostbyname ("192.168.1.1");
+       if (Host == NULL)
+               return -1;
+*/
+
+       Direccion.sin_family = AF_INET;
+//     Direccion.sin_port = Puerto->s_port;
+       Direccion.sin_port = htons(15557);
+       Direccion.sin_addr.s_addr =INADDR_ANY;
+//     Direccion.sin_addr.s_addr = ((struct in_addr *)(Host->h_addr))->s_addr;
+       if (bind (
+                       Descriptor, 
+                       (struct sockaddr *)&Direccion, 
+                       sizeof(struct sockaddr)) == -1)
+       {
+               close (Descriptor);
+               return -1;
+       }
+
+       /*
+       * Se avisa al sistema que comience a atender llamadas de clientes
+       */
+       if (listen (Descriptor, 1) == -1)
+       {
+               close (Descriptor);
+               return -1;
+       }
+
+       /*
+       * Se devuelve el descriptor del socket servidor
+       */
+       return Descriptor;
+}
+
+/**
+ * Abre un socket inet de udp.
+ * Se le pasa el nombre de servicio del socket al que debe atender.
+ * Devuelve el descriptor del socket abierto o -1 si ha habido algún error.
+ */
+int Abre_Socket_Udp (char *Servicio)
+{
+       struct sockaddr_in Direccion;
+       struct servent *Puerto = NULL;
+       int Descriptor;
+
+       /*
+       * se abre el socket
+       */
+       Descriptor = socket (AF_INET, SOCK_DGRAM, 0);
+       if (Descriptor == -1)
+       {
+               return -1;
+       }
+
+       /*
+       * Se obtiene el servicio del fichero /etc/services
+       */
+       Puerto = getservbyname (Servicio, "udp");
+       if (Puerto == NULL)
+       {
+               return -1;
+       }
+
+       /*
+       * Se rellenan los campos de la estructura Direccion, necesaria
+       * para la llamada a la funcion bind() y se llama a esta.
+       */
+       Direccion.sin_family = AF_INET;
+       Direccion.sin_port = Puerto->s_port;
+       Direccion.sin_addr.s_addr = INADDR_ANY; 
+
+       if (bind (
+                       Descriptor, 
+                       (struct sockaddr *)&Direccion, 
+                       sizeof (Direccion)) == -1)
+       {
+               close (Descriptor);
+               return -1;
+       }
+
+       /*
+       * Se devuelve el descriptor del socket servidor
+       */
+       return Descriptor;
+}
diff --git a/net/remotectrl/src/Socket_Servidor.h b/net/remotectrl/src/Socket_Servidor.h
new file mode 100644 (file)
index 0000000..72ac9a0
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Javier Abellán. 14 Abril 2003
+ *
+ * Funciones para que un servidor puede abrir sockets para atender un servicio y aceptar
+ * conexiones de un cliente.
+ */
+#ifndef _SOCKET_SERVIDOR_H
+#define _SOCKET_SERVIDOR_H
+
+/**
+ * Abre un socket INET para atender al servicio cuyo nombre es Servicio.
+ * El Servicio debe estar dado de alta en /etc/services como tcp.
+ * Devuelve el descriptor del socket que atiende a ese servicio o -1 si ha habido error.
+ */
+int Abre_Socket_Inet (char *Servicio);
+
+
+/**
+ * Abre un socket UDP para atender al servicio cuyo nombre es Servicio.
+ * El Servicio debe estar dado de alta en /etc/services como udp.
+ * Devuelve el descriptor del socket que atiende a ese servicio o -1 si ha habido error.
+ */
+int Abre_Socket_Udp (char *Servicio);
+
+
+/**
+ * Abre un socket UNIX para atender al servicio cuyo nombre es Servicio.
+ * Devuelve el descriptor del socket que atiende a ese servicio o -1 si ha habido error.
+ */
+int Abre_Socket_Unix (char *Servicio);
+
+/**
+ * Acepta un cliente para un socket INET.
+ * Devuelve el descriptor de la conexión con el cliente o -1 si ha habido error.
+ */
+int Acepta_Conexion_Cliente (int Descriptor);
+
+#endif
diff --git a/net/remotectrl/src/clientselect.c b/net/remotectrl/src/clientselect.c
new file mode 100644 (file)
index 0000000..b8478e3
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Javier Abellán. 14 de Abril de 2003
+ *
+ * Ejemplo de como un servidor puede manejar varios clientes con select().
+ * Este programa hace de cliente de dicho servidor.
+ */
+#include "Socket.h"
+#include "Socket_Cliente.h"
+
+/* Programa principal. Abre la conexión, recibe su número de cliente y
+ * luego envía dicho número cada segundo */
+main()
+{
+       int sock;               /* descriptor de conexión con el servidor */
+       struct s_msg *buffer;           /* buffer de lectura de datos procedentes del servidor */
+       int error;              /* error de lectura por el socket */
+       buffer = malloc(sizeof(struct s_msg));
+       /* Se abre una conexión con el servidor */
+       sock = Abre_Conexion_Inet ("localhost", "cpp_java");
+
+       /* Se lee el número de cliente, dato que nos da el servidor. Se escribe
+        * dicho número en pantalla.*/
+       error = ReadTcpSocket (sock, &buffer);
+//     struct s_msg Datos;
+//     *Datos = malloc(sizeof struct s_msg);
+//     error = ReadTcpSocket (sock, &Datos);
+//     printf("%d %d %s\n",Datos.type, Datos.command, Datos.data);
+       /* Si ha habido error de lectura lo indicamos y salimos */
+       if (error < 1)
+       {
+               printf ("Me han cerrado la conexión\n");
+               exit(-1);
+       }
+printf("Se leyeron %d bytes\n", error);
+       /* Se escribe el número de cliente que nos ha enviado el servidor */
+       printf ("type=%d\ncommand=%d\nlen=%d\ndata=%s\n", buffer->type, buffer->command, buffer->len, buffer->data);
+       printf ("Soy cliente\n%s\n", buffer);
+
+       /* Bucle infinito. Envia al servidor el número de cliente y espera un
+        * segundo */
+//     while (1)
+//     {
+//             Escribe_Socket (sock, (char *)&buffer, sizeof(int));
+//             sleep (1);
+//     }
+}
+
diff --git a/net/remotectrl/src/remotectrl.c b/net/remotectrl/src/remotectrl.c
new file mode 100644 (file)
index 0000000..73c14be
--- /dev/null
@@ -0,0 +1,251 @@
+#include "remotectrl.h"
+
+int write_msg( struct rmt_socket_t *sckHnd, uint32_t id, uint32_t extra, char *message ){
+       msg_head_t header;
+       int rslt;
+       header.id    = id;
+       header.len   = strlen(message);
+       header.extra = extra;
+  rslt = send(sckHnd->fd,&header,sizeof(struct msg_head_t),0);
+       if (rslt != -1 && header.len > 0) {
+               sckHnd->Tx += rslt;
+               rslt = send(sckHnd->fd, message, header.len, 0);
+               if (rslt > 0)
+               {
+                       sckHnd->Tx += rslt;
+                       rslt += sizeof(struct msg_head_t);
+               }
+       }
+       return rslt;
+}
+
+int read_msg( struct rmt_socket_t *sckHnd, msg_head_t *head, char **message )
+{
+       msg_head_t header;
+       int rslt;
+       char *buffer;
+       int reading = 0;
+       int aux = 0;
+  rslt = recv(sckHnd->fd, head, sizeof(struct msg_head_t), 0);
+//     printf("head->id=%d head->extra=%d head->len=%d\n",head->id,head->extra,head->len);
+       if (rslt == sizeof(struct msg_head_t) ) {
+               sckHnd->Rx += rslt;
+               buffer = malloc(head->len+1);
+               while ( reading < head->len ){
+                       memset(buffer,'\0', head->len+1);
+                       aux = recv(sckHnd->fd, buffer, head->len, 0);
+                       switch ( aux ) {
+                               case -1:
+                                       switch (errno){
+                                               case EINTR:
+                                               case EAGAIN:
+                                                       usleep (100);
+                                                       break;
+                                               default:
+                                                       return -1;
+                                       }
+                               break;
+                               case 0: // mean socket was closed
+                                       sckHnd->Rx += reading;
+                                       return reading;
+                                       break;
+                               break;
+                               default:
+                                       if (reading == 0) 
+                                               *message=malloc(aux+1);
+                                       else
+                                               *message=(char*)realloc(*message,(reading+aux+1)*sizeof(char));
+                                       memcpy(*message+reading, buffer, aux);
+                                       reading += aux; 
+                       }
+               }
+               free(buffer);
+               sckHnd->Rx += reading;
+               reading += rslt;
+               return reading;
+       }
+       return rslt;
+}
+
+void rmtctrl_srv(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients)
+{
+       fd_set fdRead;
+       int maxHnd;
+       int i;
+       struct timeval  nowait; 
+       memset((char *)&nowait,0,sizeof(nowait)); 
+
+       rmtctrl_cleanClients(client, activeClients);
+       FD_ZERO (&fdRead);
+       FD_SET (srv.fd, &fdRead);
+
+       for (i=0; i<*activeClients; i++)
+               FD_SET (client[i].fd, &fdRead);
+
+       maxHnd = rmtctrl_maxValue (client, *activeClients);
+               
+       if (maxHnd < srv.fd)
+               maxHnd = srv.fd;
+
+       select (maxHnd + 1, &fdRead, NULL, NULL,&nowait);
+       for (i=0; i<*activeClients; i++)
+       {
+               if (FD_ISSET (client[i].fd, &fdRead))
+               {
+                               rmtctrl_msg_proccess(&client[i]);
+               }
+       }
+       if (FD_ISSET (srv.fd, &fdRead))
+               rmtctrl_newClient(srv,client, &(*activeClients));
+}
+
+void rmtctrl_msg_proccess(struct rmt_socket_t *client)
+{
+       msg_head_t header;
+       char *msg=NULL;
+       int rslt;
+       rslt = read_msg(client,&header,&msg);
+       if (rslt > 0)
+       {
+               switch (header.id)
+               {
+                       case QRY_STATUS:
+                               rslt = write_msg(client,MSG_END,0, "Bienvenido a mi servidor.\nStatus\n" );
+                       break;
+                       case QRY_CONNECTED_LIST:
+                               rslt = write_msg(client,MSG_START,0, "List of Connected\n" );
+                               rslt = write_msg(client,MSG_PART,0, "Username       IPAddrs         Status\n" );
+                               rslt = write_msg(client,MSG_PART,0, "pepe1          198.164.234.224 Authenticated\n" );
+                               rslt = write_msg(client,MSG_PART,0, "pepe2          198.164.234.220 Authenticated\n" );
+                               rslt = write_msg(client,MSG_PART,0, "pepe3          198.164.234.221 Authenticated\n" );
+                               rslt = write_msg(client,MSG_PART,0, "pepe4          198.164.234.223 Authenticated\n" );
+                               rslt = write_msg(client,MSG_PART,0, "pepe5          198.164.234.227 Authenticated\n" );
+                               rslt = write_msg(client,MSG_END,0, "pepe6          198.164.234.224 Authenticated\n" );
+                       break;
+                       default:
+                               rslt = write_msg(client,MSG_END,9, "Unknow command.\n" );
+               }
+       }
+       else
+       {
+               printf("Desde %s se recibieron %d bytes y se enviaron %d bytes\n",inet_ntoa(client->addr.sin_addr),client->Rx,client->Tx);
+               close(client->fd); /* cierra fd_rmt_client */
+               printf("Client cerro conexión desde %s\n",inet_ntoa(client->addr.sin_addr) ); 
+               client->fd = -1;
+       }
+       if ( msg != NULL) free(msg);
+}
+
+void rmtctrl_newClient(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients)
+{
+       int rslt;
+       int cli = (*activeClients);
+       rmtctrl_accept(srv,&client[cli]);
+       if (client[(*activeClients)].fd != -1)
+       {
+               (*activeClients)++;
+       }
+       if ((*activeClients) >= MAX_CLIENTS)
+       {
+               (*activeClients)--;
+               rslt = write_msg(&client[(*activeClients)],MSG_END,0, "Sorry Server is too Busy\n       Try more late\n" );
+               if (rslt > 0) client[(*activeClients)].Tx += rslt;
+               rmtctrl_close(&client[(*activeClients)]);
+       }
+}
+
+void rmtctrl_close ( struct rmt_socket_t *client )
+{
+       printf("Desde %s se recibieron %d bytes y se enviaron %d bytes\n",inet_ntoa(client->addr.sin_addr),client->Rx,client->Tx);
+       close(client->fd); /* cierra fd_rmt_client */
+       printf("Se cerro conexión desde %s\n",inet_ntoa(client->addr.sin_addr) ); 
+       client->fd = -1;
+}
+
+void rmtctrl_accept (struct rmt_socket_t srv, struct rmt_socket_t *client ) 
+{
+       int sin_size=sizeof(struct sockaddr_in);
+       int int_Send;
+       struct sockaddr_in addr;
+       
+       if ((client->fd = accept(srv.fd,(struct sockaddr *)&client->addr,&sin_size))!=-1) 
+       {
+               client->Rx = 0;
+               client->Tx = 0;
+               unsigned char c = sizeof(uint32_t);
+               int_Send = send(client->fd, &c, 1, 0);
+               if (int_Send > 0) client->Tx += int_Send;
+               printf("Se abrió una conexión desde %s\n", inet_ntoa(client->addr.sin_addr)); 
+       }
+}
+
+struct rmt_socket_t initSrv(){
+       struct rmt_socket_t srv;
+       if ((srv.fd=socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {  
+               printf("error en socket()\n");
+               exit(-1);
+       }
+       srv.addr.sin_family = AF_INET;
+       srv.addr.sin_port = htons(PORT); 
+       srv.addr.sin_addr.s_addr = INADDR_ANY; 
+       bzero(&(srv.addr.sin_zero),8); 
+
+       if(bind(srv.fd,(struct sockaddr*)&srv.addr,sizeof(struct sockaddr))==-1) {
+               printf("error en bind() \n");
+               exit(-1);
+       }     
+
+       if(listen(srv.fd,BACKLOG) == -1) {
+               printf("error en listen()\n");
+               exit(-1);
+       }
+       return srv;
+}
+
+//void cleanClients (int *table, int *n)
+void rmtctrl_cleanClients (struct rmt_socket_t *client, int *n)
+{
+       int i,j;
+
+       if ((client == NULL) || ((*n) == 0))
+               return;
+
+       j=0;
+       for (i=0; i<(*n); i++)
+       {
+               if (client[i].fd != -1)
+               {
+                       client[j].fd = client[i].fd;
+                       client[j].addr = client[i].addr;
+                       client[j].Rx = client[i].Rx;
+                       client[j].Tx = client[i].Tx;
+                       j++;
+               }
+       }
+       
+       *n = j;
+}
+
+int rmtctrl_maxValue (struct rmt_socket_t *client, int n)
+{
+       int i;
+       int max;
+
+       if ((client == NULL) || (n<1))
+               return 0;
+               
+       max = client[0].fd;
+       for (i=0; i<n; i++)
+               if (client[i].fd > max)
+                       max = client[i].fd;
+
+       return max;
+}
+
+
+/*
+void main()
+{
+       rmtctrl_srv();
+}
+*/
diff --git a/net/remotectrl/src/remotectrl.h b/net/remotectrl/src/remotectrl.h
new file mode 100644 (file)
index 0000000..b0b5b03
--- /dev/null
@@ -0,0 +1,49 @@
+/* Estos son los ficheros de cabecera usuales */
+#include <stdio.h>          
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#define PORT 15557 /* El puerto que ser? abierto */
+#define BACKLOG 2 /* El n?mero de conexiones permitidas */
+#define MAX_CLIENTS 10
+
+enum 
+{
+       MSG_OK              = 0,
+       MSG_START           = 1,
+       MSG_PART            = 2,
+       MSG_END             = 3,
+       QRY_STATUS          = 100,
+       QRY_CONNECTED_LIST  = 101,
+       QRY_MACADDR         = 102,
+       QRY_IPADDR          = 103,
+       QRY_USERNAME        = 104,
+};
+
+typedef struct msg_head_t {
+       uint32_t id;
+       uint32_t extra;
+       uint32_t len;
+} msg_head_t;
+
+typedef struct rmt_socket_t {
+       int fd;
+       struct sockaddr_in addr;
+       int Rx;
+       int Tx;
+} rmt_socket_t;
+
+       
+int write_msg( struct rmt_socket_t *sckHnd, uint32_t id, uint32_t extra, char *message );
+int read_msg( struct rmt_socket_t *sckHnd, msg_head_t *head, char **message );
+
+struct rmt_socket_t initSrv();
+void rmtctrl_srv(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients);
+
+void rmtctrl_accept (struct rmt_socket_t srv, struct rmt_socket_t *client );
+void rmtctrl_cleanClients (struct rmt_socket_t *client, int *n);
+void rmtctrl_msg_proccess(struct rmt_socket_t *client);
+void rmtctrl_newClient(struct rmt_socket_t srv, struct rmt_socket_t *client, int *activeClients);
+void rmtctrl_close ( struct rmt_socket_t *client );
diff --git a/net/remotectrl/src/server_socket.c b/net/remotectrl/src/server_socket.c
new file mode 100644 (file)
index 0000000..fcc5a6b
--- /dev/null
@@ -0,0 +1,22 @@
+#include "remotectrl.h"
+
+int main(){
+       time_t tim;
+       struct rmt_socket_t srv;
+       struct rmt_socket_t client[MAX_CLIENTS];
+       int activeClients = 0;                  /* Número clientes conectados */
+       
+       srv = initSrv();
+       
+//     client = initClients();
+       
+
+       while (1){
+               tim=time(NULL);
+               printf("%s", ctime(&tim) );
+               rmtctrl_srv(srv,client,&activeClients);
+               usleep (100);
+       }
+       return 0;
+}
+
diff --git a/net/remotectrl/src/servselect.c b/net/remotectrl/src/servselect.c
new file mode 100644 (file)
index 0000000..c5eace6
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * 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;
+}
+