Foros del Web » Programación para mayores de 30 ;) » C/C++ »

sockets

Estas en el tema de sockets en el foro de C/C++ en Foros del Web. buenos días, este es mi debut en el foro, me especializo en java, pero en este caso mi problema es con C. Les voy a ...
  #1 (permalink)  
Antiguo 23/11/2013, 16:55
 
Fecha de Ingreso: noviembre-2013
Mensajes: 3
Antigüedad: 10 años, 5 meses
Puntos: 0
sockets

buenos días, este es mi debut en el foro, me especializo en java, pero en este caso mi problema es con C. Les voy a pedir ayuda con un codigo de sockets, que lo tengo distribuido en 2 archivos (cliente y servidor). La idea es ejecutar el servidor, luego 4 clientes que se conectan a ese servidor. Lo que pasa es lo siguiente, el servidor una vez conectados los 4 clientes, les envía un mensaje a cada uno, pero hay algún problema con el último cliente, ya que sale el mensaje "connection refused". Les dejo los 2 códigos, el servidor se compila con "cc servidor.c -o servidor.out" y el cliente con "gcc cliente.c -o cliente.out -lm"


Código:
SERVIDOR.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>


#define P_SIZE sizeof(struct pmensaje)

struct pmensaje{
		int mensaje;	//tipo de operacion que debe hacer el cliente
		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
	};



struct pcliente{
	int sd;
	struct sockaddr_in cli;
	socklen_t lon;
};


void impresiones(int opcion){
	switch (opcion){
		case 1:	printf("****************************************************************\n");
				printf("***                 SERVIDOR INICIADO                        ***\n");
				printf("****************************************************************\n");
				break;
		case 2:	printf("****************************************************************\n");
				printf("***                SERVIDOR FINALIZADO                        ***\n");
				printf("****************************************************************\n");
				break;

		default: printf("");
				break;

	}

}



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);
	return 0;
}

int reenviar(int sd, char *param,struct pmensaje *m){
	int ok, d;

	switch (m->cOrigen){
		//capa origen = 1 => enviar a todos los de capa 2
		case 1: enviar(param, m, 4021);
				enviar(param, m, 4022);
				enviar(param, m, 4023);
				break;
		//capa origen = 2 => envio a capa 1 o 3 (mismo cliente)
		case 2: enviar(param, m, 4001);
				break;
		//capa origen = 3 => enviar a todos los de capa 2
		case 3: d = m->nDestino;
//				m->nDestino = 1;
				switch(d){
					case 3: enviar(param, m, 4021);
							break;
					case 4: enviar(param, m, 4022);
							break;
					case 5: enviar(param, m, 4023);
							break;
				}
		default: ok = -1;
				break;
	}
	sleep(1);
	printf("Redireccionando mensaje de capa %i a capa %i de idNeurona %i\n", m->cOrigen,m->cDestino, m->idNeurona);
	return ok;
}

int main(int argc, char *argv[]){

	int i,j;
	int pid;
	int sd;
	int sdcli;
	int clientes[10];
	char buffer[P_SIZE];
	socklen_t lon;
	struct sockaddr_in server;
	struct sockaddr_in cliente;
	struct pmensaje *mensaje;


	system("clear");
	
		argv[1] = "localhost";
	

	impresiones(1);

	server.sin_family = AF_INET;
	server.sin_port = htons(4000);
	server.sin_addr.s_addr = INADDR_ANY;

	sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if ((bind(sd, (struct sockaddr *) &server, sizeof(server)))<0){
		perror("BIND: ");
		exit(-1);
	}

	listen(sd, 100);
	i = 0;
	while (1){
			lon = sizeof(cliente);

				sdcli = accept(sd, (struct sockaddr *) &cliente, &lon);

				pid = fork();
				if (pid == 0){

					close(sd);

					recv(sdcli, buffer, P_SIZE, 0);

					mensaje = (struct pmensaje *) buffer;

					if (i<=3){
						printf("El número de clientes es %i \n*******************************\n",i+1);

					switch (i){
						case 0:	mensaje->capa = 4001;
								break;
						case 1:	mensaje->capa = 4021;
								break;
						case 2:	mensaje->capa = 4022;
								break;
						case 3:	mensaje->capa = 4023;
								break;
					}
					send(sdcli, mensaje, P_SIZE, 0);
					}
					if (i == 3){
						mensaje->mensaje = 100;
						enviar("localhost", mensaje,4001);
						enviar("localhost", mensaje,4021);
						enviar("localhost", mensaje,4022);
						enviar("localhost", mensaje,4023);
					}

					if (i > 3){
						reenviar(sd, "localhost",mensaje);
					}

					close(sdcli);

					exit(0);
				}else{
					i++;

					close(sdcli);
				}
		}


	close(sd);

return 0;
}
  #2 (permalink)  
Antiguo 23/11/2013, 17:01
 
Fecha de Ingreso: noviembre-2013
Mensajes: 3
Antigüedad: 10 años, 5 meses
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;

}



}
  #3 (permalink)  
Antiguo 23/11/2013, 17:04
 
Fecha de Ingreso: noviembre-2013
Mensajes: 3
Antigüedad: 10 años, 5 meses
Puntos: 0
Respuesta: sockets

CLIENTE.C (continuación)

Código:
/**
 * Emula la operatoria de la capa oculta
 */
int operatoriaCapaOculta(struct sockaddr_in local,int sd,  int sdcli, int puerto){
	char buffer[P_SIZE];
	char buffer2[P_SIZE_2];
	int phi = 3;
	int i, lon;
	struct pmensaje *mensaje;
	struct pneurona *n1;
	double umbral = 1;
	double delta;
	double suma;
	int deC1 = 0, deC2 = 0; //variables que indican la cant de paquetes recibidos de c/capa

	mensaje = (struct pmensaje *) buffer;
	n1 = (struct pneurona *) buffer2;
	inicializar(n1, 1, puerto);
	imprimirNeurona(n1,2);
	while(1){


			lon = sizeof(local);
			sdcli = accept(sd, (struct sockaddr *) &local, &lon);
			recv(sdcli, mensaje, P_SIZE, 0);

			imprimirMensaje(mensaje);

			//Si el mensaje es recibido de la capa 1 y esta dirigido a la capa 2, armo y envio el mensaje para la capa 3
			if ((mensaje->cOrigen == 1) && (mensaje->cDestino == 2)){
				n1->valores[mensaje->idNeurona - 1] = mensaje->valor;
				deC1++;

				if(deC1 == 2){
					mensaje->cOrigen = 2;
					mensaje->cDestino = 3;
					mensaje->idNeurona = n1->idNeurona;
					mensaje->nDestino = 1;
					mensaje->valor = fgnet(gnet(n1->pesos, n1->valores, deC1, umbral));
					enviar("localhost", mensaje, 4000);
					deC1 = 0;
					printf("Mensaje enviado a capa 3\n");
				}


			}

			if((mensaje->cOrigen == 3) && (mensaje->cDestino == 2)){
				imprimirNeurona(n1,2);
				printf("Corrigiendo pesos...\n");
				suma = 0;

				for (i=0;i<2;i++){
					suma +=mensaje->valor*n1->pesos[i];
				}

				delta = deltak(gnet(n1->pesos, n1->valores, 2, umbral), suma);

				for (i=0;i<2;i++){
						n1->pesos[0] += delta*phi*fgnet(gnet(n1->pesos, n1->valores, 2, umbral));
				}
				imprimirNeurona(n1,2);

				mensaje->cOrigen = 2;
				mensaje->cDestino = 1;
				mensaje->idNeurona = n1->idNeurona;
				mensaje->valor = delta;

				enviar("localhost", mensaje, 4000);
			}

	}


return 0;

}


int main(int argc, char *argv[]){
	int sd, sdcli,salir, i, j;
	char teclado[255];
	char buffer[P_SIZE];
	char buffer2[P_SIZE_2];
	struct hostent *h;
	struct pmensaje *mensaje;
	struct sockaddr_in remoto, local;
	socklen_t lon;


	system("clear");
	
		argv[1] = "localhost";
	

	mensaje = (struct pmensaje *) buffer;
	mensaje->capa = htons(1);
	mensaje->valor = 0.5;

	saludo(argv[1], mensaje);

	remoto.sin_family = AF_INET;
	remoto.sin_port = htons(mensaje->capa);
	remoto.sin_addr.s_addr = INADDR_ANY;


	sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if ((bind(sd, (struct sockaddr *) &remoto, sizeof(remoto)))<0){
		perror("BIND: ");
		exit(-1);
	}

	listen(sd, 10);
	i = 0;
	salir = 0;
	printf("Estoy escuchando por el puerto %i\n", mensaje->capa);

	while(!salir){
		lon = sizeof(local);
		sdcli = accept(sd, (struct sockaddr *) &local, &lon);
		recv(sdcli, mensaje, P_SIZE, 0);

		if (mensaje->mensaje == 100){
			if (ntohs(remoto.sin_port) == 4001){
				salir = operatoriaCapaMixta(local, sd, sdcli);
			}else{
				operatoriaCapaOculta(local,sd, sdcli, ntohs(remoto.sin_port));
			}
		}
	}
	close(sdcli);
	close(sd);

}

Etiquetas: int, sockets, string, struct
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:33.