Tema: sockets
Ver Mensaje Individual
  #2 (permalink)  
Antiguo 23/11/2013, 17:01
marcelofb
 
Fecha de Ingreso: noviembre-2013
Mensajes: 3
Antigüedad: 11 años, 1 mes
Puntos: 0
Respuesta: sockets

Código:
CLIENTE.C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <math.h>

#define P_SIZE sizeof(struct pmensaje)
#define P_SIZE_2 sizeof(struct pneurona)

struct pneurona{
	int idNeurona;
	double valores[3];
	double pesos[3];
};




struct pmensaje{
		int mensaje;	//tipo de operacion
		int idNeurona;	//identificacion del cliente
		int cOrigen;	//capa de origen del mensaje
		int cDestino;	//capa de destino del mensaje
		int nDestino;	//neurona destino
		int capa;		//nro de capa en la que estoy
		float valor;	//valor
	};




/**
 * envia datos por el puerto especificado
 */
int enviar(char *param, struct pmensaje *m, int puerto){
	int sd;
	socklen_t lon;
	struct sockaddr_in server;
	struct hostent *h;

	server.sin_family = AF_INET;
	server.sin_port = htons(puerto);

	if (h = gethostbyname("localhost")){
		memcpy(&server.sin_addr, h->h_addr, h->h_length);
	}else{
		printf("No se encontró %s\n", param);
	}

	sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	lon = sizeof(server);


	if(connect(sd, (struct sockaddr *)&server, lon)<0){
		perror("Connect");
		exit(-1);
	}

	send(sd, m, P_SIZE, 0);
	close(sd);
	return 0;
}

/**
 * solicita datos por teclado
 */
int pedido_de_datos(int i){
	char teclado[P_SIZE];

	if (i<3){
		printf("Ingrese valor %i: ", i);
	}else{
		printf("Ingrese valor esperado: ", i);

	}

	fgets(teclado,sizeof(teclado),stdin);
	teclado[strlen(teclado)-1] = '\0';

	return atoi(teclado);

}

/**
 * primera comunicacion con el servidor
 */
int saludo(char *param, struct pmensaje *m){
	int sd, leidos, n;
	socklen_t lon;
	struct sockaddr_in server;
	struct hostent *h;

	server.sin_family = AF_INET;
	server.sin_port = htons(4000);
	if (h = gethostbyname(param)){
		memcpy(&server.sin_addr, h->h_addr, h->h_length);
	}else{
		printf("No se encontró %s\n", param);
	}
	sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	lon = sizeof(server);


	if(connect(sd, (struct sockaddr *)&server, lon)<0){
		perror("Connect");
		exit(-1);
	}

	send(sd, m, P_SIZE, 0);

	leidos = 0;
	while (leidos < P_SIZE){
		if ((n = recv(sd, m + leidos, P_SIZE - leidos, 0)) <= 0){
			close(sd);
			break;
		}
		leidos += n;
	}



	close(sd);

	return m->capa;
}


int imprimirMensaje(struct pmensaje *m){
		printf("------------------------------------------------------------------\n");
		printf("idNeurona: %i\n", m->idNeurona);
		printf("Capa Origen: %i\n", m->cOrigen);
		printf("Capa Destino: %i\n", m->cDestino);
		printf("Neurona Destino: %i\n", m->nDestino);
		printf("Capa: %i\n", m->capa);
		printf("Mensaje: %i\n", m->mensaje);
		printf("Valor: %5.2f\n", m->valor);
		printf("------------------------------------------------------------------\n");
		return 0;
}

int imprimirNeurona(struct pneurona *n, int max){
	int i;
	printf("------------------------------------------------------------------\n");
	printf("idNeurona: %i\n", n->idNeurona);
	printf("\tPesos\tValores\n");

	for (i=0;i<max;i++){
		printf("%i)\t%5.2f\t %5.2f\n", i,n->pesos[i], n->valores[i]);
	}
	printf("------------------------------------------------------------------\n");

}


/**
 * calcula la g(net)
 */
double gnet(double pesos[], double valores[], int max, double phi){
	double suma;
	int i;
	suma = 0;

	for (i=0;i<max;i++){
		suma += (pesos[i]*valores[i])-phi;
	}
	return suma;
}

/**
 * calcula la f(gnet)
 */
double fgnet(double gnet){
	double exponencial;
	double valor;

	exponencial = exp(gnet);
	valor = (1/(1+exponencial));

	return valor;
}



/**
 * Calcula el valor de salida de la neurona (activacion)
 */
int y(double fgnet){

	if (fgnet > 0.5){
		return 1;
	}else{
		return 0;
	}
}

/**
 * Inicualiza las neuronas
 */
int inicializar(struct pneurona *n, int id, int puerto){
	int i;
	double peso;

	peso = 0.33;
	n->idNeurona = id;

	if (puerto == 4001)
		if (id == 6){
			peso = 1;
		}else{
			peso = 0.5;
		}
	else{
		switch(puerto){
			case 4021: n->idNeurona = 3;
						break;
			case 4022: n->idNeurona = 4;
						break;
			case 4023: n->idNeurona = 5;
						break;
		}
	}

	for (i=0; i<3; i++){
		n->pesos[i] = peso;
		n->valores[i] = 0;
	}


printf("id: %i\n", n->idNeurona);
	return 0;
}

/**
 * Calcula el delta para la neurona 6
 */
double delta6(double gnet, double ydeseado){
	return fgnet(gnet)*(1- fgnet(gnet))*(ydeseado-fgnet(gnet));

}


/**
 * Calcula el delta para la neurona
 */
double deltak(double gnet, double suma){
	return fgnet(gnet)*(1-fgnet(gnet))*suma;
}


/**
 * emula la operatoria de la capa de entrada (C1) y la capa de salida (C3)
 */
int operatoriaCapaMixta(struct sockaddr_in local,int sd, int sdcli){
	char buffer[P_SIZE];

	char buffer2[P_SIZE_2];
	char buffer3[P_SIZE_2];
	char buffer4[P_SIZE_2];

	int phi = 3;
	char teclado[P_SIZE];
	int i,j=0, deseado,lon, pid;
	int salir;
	struct pmensaje *mensaje;
	struct pneurona *n1;
	struct pneurona *n2;
	struct pneurona *n3;
	int asignado[3];
	int deC1 = 0, deC2 = 0, deC3 = 0;
	double umbral = 0.5;
	double suma1, suma2;

	mensaje = (struct pmensaje *) buffer;

	n1 = (struct pneurona *) buffer2;
	n2 = (struct pneurona *) buffer3;
	n3 = (struct pneurona *) buffer4;

	inicializar(n1, 1, 4001);
	inicializar(n2, 2, 4001);
	inicializar(n3, 6, 4001);

	printf("*********************************************************\n");
	printf("***          Ya puede comenzar la operatoria          ***\n");
	printf("*********************************************************\n");

	salir = 0;
	imprimirNeurona(n1,1);
	imprimirNeurona(n2,1);
	imprimirNeurona(n3,3);
	while(!salir){

		deseado = pedido_de_datos(3);
		for (i=1;i<=2;i++){
			mensaje->cOrigen = 1;
			mensaje->cDestino = 2;
			mensaje->nDestino = 1;
			mensaje->idNeurona = i;
			mensaje->capa = 4001;
			if (i == 1){
				n1->pesos[0] = pedido_de_datos(1);
				mensaje->valor = fgnet(gnet(n1->pesos,n1->valores,1,umbral));
			}else{
				n2->pesos[0] = pedido_de_datos(2);
				mensaje->valor = fgnet(gnet(n2->pesos, n2->valores, 1,umbral));
			}
			enviar("localhost", mensaje, 4000);
			printf("Mensaje de capa 1 enviado a capa 2\n");
		}

		//Espera recibir los 3 mensajes de c/u de las neuronas de capa 2
		i = 0;
		while (i < 3){
			lon = sizeof(local);
			sdcli = accept(sd, (struct sockaddr *) &local, &lon);
			recv(sdcli, mensaje, P_SIZE, 0);

			printf("Recibido mensaje de la neurona %i\n", mensaje->idNeurona);
			if ((mensaje->cOrigen == 2) && (mensaje->cDestino == 3)){
				n3->valores[mensaje->idNeurona-3] = mensaje->valor;
			}
			i++;
		}

/******************************* carteles correspondientes a C3 *********************************************/

		i = y(fgnet(gnet(n3->pesos, n3->valores, 3, umbral)));
		if (i != deseado){
			printf("El valor recibido es distinto del valor deseado (%i != %i)\n", i, deseado);
			imprimirNeurona(n3,3);


			printf("Corrigiendo pesos con delta = %7.5f...\n", delta6(gnet(n3->pesos, n3->valores, 3, umbral), deseado));


			//Retropropago el valor de delta
			mensaje->cOrigen = 3;
			mensaje->cDestino = 2;
			mensaje->idNeurona = 6;
			for (i=0; i<3;i++){
				mensaje->nDestino = i+3;
				mensaje->valor = n3->pesos[i]*delta6(gnet(n3->pesos, n3->valores, 3, umbral), deseado);
				enviar("localhost", mensaje, 4000);
			}

			//Corrijo los pesos de la neurona 3
			for (i=0;i<3;i++){
				n3->pesos[i] += umbral*delta6(gnet(n3->pesos, n3->valores, 3, umbral), deseado)*fgnet(gnet(n3->pesos, n3->valores, 3, umbral));
			}
			imprimirNeurona(n3,3);

			//Recibe los delta de la capa 2 para la capa 1
			i = 0;
			suma1 = 0;
			suma2 = 0;
			printf("Valores originales de los pesos de las neuronas 1 y 2...\n");
			imprimirNeurona(n1,1);
			imprimirNeurona(n2,1);
			while (i < 3){
				lon = sizeof(local);
				sdcli = accept(sd, (struct sockaddr *) &local, &lon);
				recv(sdcli, mensaje, P_SIZE, 0);
				printf("Recibido mensaje de la neurona %i\n", mensaje->idNeurona);

				if ((mensaje->cOrigen == 2) && (mensaje->cDestino == 1)){
					if (mensaje->nDestino == 1){
						suma1 += mensaje->valor*n1->pesos[0];
					}else{
						suma2 += mensaje->valor*n2->pesos[0];
					}

				}
				i++;
			}

			n1->pesos[0] +=phi*deltak(gnet(n1->pesos, n1->valores, 1, umbral), suma1)*fgnet(gnet(n1->pesos, n1->valores, 1, umbral));
			n2->pesos[0] +=phi*deltak(gnet(n2->pesos, n2->valores, 1, umbral), suma2)*fgnet(gnet(n2->pesos, n2->valores, 1, umbral));
			printf("Valores resultantes de la correccion de los pesos de las neuronas 1 y 2...\n");
			imprimirNeurona(n1,1);
			imprimirNeurona(n2,1);
		}else{
			printf("El valor recibido es igual al deseado %i = %i\n", i, deseado);

		}
/**********************************************************************************************************/


		printf("Desea salir de la aplicacion? S/N \n");
		fgets(teclado,sizeof(teclado),stdin);
		teclado[strlen(teclado)-1] = '\0';

		salir = strcmp(teclado, "N");

	}

	printf("*********************************************************\n");
	printf("***             Finalizada la operatoria              ***\n");
	printf("*********************************************************\n");

return salir;

}



}