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
This commit is contained in:
thepeople 2010-02-12 00:36:12 +00:00
parent c2aab8c511
commit 7dfd14a763
14 changed files with 1579 additions and 0 deletions

48
net/remotectrl/Makefile Normal file
View File

@ -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))

View File

@ -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)

View File

@ -0,0 +1,17 @@
prefix=/usr
DESTDIR=
COPTS=-O2
WOPTS=-pedantic -Werror -Wall
FPIC=-fPIC
CFLAGS=$(COPTS) $(WOPTS) -std=gnu99
AR=ar
CC=gcc
RANLIB=ranlib
INSTALL=install
MKDIR=mkdir
LINK=$(CC)
SHLIB_EXT=so
SHLIB_FLAGS=-shared -Wl,-soname,$(SHLIB_FILE)

417
net/remotectrl/src/Socket.c Normal file
View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
// }
}

View File

@ -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();
}
*/

View File

@ -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 );

View File

@ -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;
}

View File

@ -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;
}