Código fuente del Servidor:
/************************************************************************* * * Servidor del juego Ahorcado en TCP. * Asignatura: Redes II. * Autores: * Gabriel Cebrián Márquez. * EstefanÃa Coronado Calero. * Iván Durango Blanco. * ************************************************************************/ #include#include #include #include #include #include #include #include #include #include #include #include #include /*extern int errno;*/ #include "error.h" #include "socket_utils.h" #define _USE_BSD #define QLEN 32 /* Longitud máxima de la cola de conexiones */ #define BUFSIZE 4096 #define MAXDICT 32 /* Máximo tamaño de la palabra del ahorcado */ #define MAXLINEA MAXDICT + 10 #define NUM_PALABRAS 15 void reaper(int); int escogeAleatorio(); int ahorcadoSrv(int desc); /************************************************************************* * * main - Servidor concurrente para el servicio del ahorcado remoto. * *************************************************************************/ int main(int argc, char *argv[]) { char *service = "8041"; /* Nombre del servicio o número de puerto */ struct sockaddr_in fsin; /* Dirección del cliente */ unsigned int alen; /* Tamaño de la dirección del cliente */ int msock; /* Socket del servidor maestro */ int ssock; /* Socket del servidor esclavo */ switch (argc) { case 1: break; default: errexit("Uso del programa: Ahorcado_servidor\n"); } /* Se crea un socket pasivo */ msock = passiveTCP(service, QLEN); (void) signal(SIGCHLD, reaper); while (1) { alen = sizeof(fsin); /* Cambiamos el identificador del socket */ ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) { if (errno == EINTR) continue; errexit("Error ACCEPT: %s\n", strerror(errno)); } switch (fork()) { case 0: /* Hijo */ (void) close(msock); exit(ahorcadoSrv(ssock)); default: /* Padre */ (void) close(ssock); break; case -1: errexit("Error FORK: %s\n", strerror(errno)); } } } /************************************************************************* * * ahorcadoSrv - Función que gestiona el juego en el servidor. * *************************************************************************/ int ahorcadoSrv(int desc) { /* Diccionario de palabras para el juego */ char diccionario[NUM_PALABRAS][MAXDICT] = { "CARACOL", "MOTOCICLETA", "HORMIGA", "GUACAMAYO", "HECHICERO", "JUGUETE", "LICENCIA", "INSECTICIDA", "JINETE", "LADRILLO", "LEVADIZO", "JEROGLIFICO", "LEVITACION", "IMPACIENCIA", "IMPERMEABILIDAD"}; char auxiliar[MAXLINEA]; char solucion[MAXLINEA] = "Correcta: "; /* Array auxiliar para mostrar la palabra correcta al final. */ char ahorcado[] = "AHORCADO"; /* Array auxiliar para mostrar ahorcado*/ char buffer[BUFSIZ]; char solucionSrv[MAXDICT + 26] = "La palabra a adivinar es: "; /* Solución que se mostrará en el servidor. */ int cc; int aleatorio = escogeAleatorio(); /* Indice aleatorio del array*/ int i; int encontrados; int NumCaracteresAEncontrar = 0; int errores = 0; /* Mostramos la palabra que se debe adivinar en la terminal del servidor. */ printf("%s\n", strcat(solucionSrv, diccionario[aleatorio])); /* Inicializamos el vector auxiliar a espacios vacÃos. */ for (i = 0; i < MAXLINEA; i++) auxiliar[i] = ' '; /* Colocamos los asteriscos de la palabra elegida. */ for (i = 10; diccionario[aleatorio][i-10] != '\0'; i++) auxiliar[i] = '*'; auxiliar[i] = '\0'; /* Pongo el limite de caracteres que deben ser encontrados. */ NumCaracteresAEncontrar = i - 10; /* Enviamos la primera pista al cliente, todavÃa sin haber realizado ningún intento. */ if (write(desc, auxiliar, MAXLINEA) < 0) errexit("Error WRITE (primera pista): %s\n", strerror(errno)); /* Mientras no superemos el número de errores, no hayamos ganado y leamos algo del cliente */ while ((NumCaracteresAEncontrar > 0) && (errores < 8) && (cc = read(desc, buffer, sizeof(buffer))) ) { if (cc < 0) errexit("No se ha leÃdo la letra correctamente: %s\n", strerror(errno)); /* Inicializamos encontrados, que servirá para ver si se encuentra la letra recibida todavÃa sin descubrir. */ encontrados = 0; /* Recorremos todas las letras de la palabra del diccionario */ for (i = 10; diccionario[aleatorio][i-10] != '\0'; i++) { /* Miramos que no la hayamos introducido anteriormente. */ if ((toupper(buffer[0]) == diccionario[aleatorio][i-10]) && (toupper(buffer[0]) != auxiliar[i])) { auxiliar[i] = toupper(buffer[0]); encontrados++; NumCaracteresAEncontrar--; } } if (encontrados == 0) errores++; /* Ponemos la palabra AHORCADO según el número de errores. */ for (i = 0; i < errores; i++) auxiliar[i] = ahorcado[i]; if ( NumCaracteresAEncontrar != 0 && errores < 8) { if (write(desc, auxiliar, MAXLINEA) < 0) errexit("Error WRITE (envÃo pista): %s\n", strerror(errno)); } } if (errores >= 8) { if (write(desc, "FIN DE LA PARTIDA. ¡Has sido ahorcado!", MAXLINEA) < 0) errexit("Error WRITE (envÃo final de partida): %s\n", strerror(errno)); } else { if (write(desc, "FIN DE LA PARTIDA. ¡Has ganado!", MAXLINEA) < 0) errexit("Error WRITE (envÃo final de partida): %s\n", strerror(errno)); } /* Enviamos la palabra correcta */ if (write(desc, strcat(solucion, diccionario[aleatorio]), MAXLINEA) < 0) errexit("Error WRITE (envÃo solución): %s\n", strerror(errno)); /* Cerramos socket */ close(desc); return 0; } /************************************************************************* * * escogeAleatorio - Función que gestiona el juego en el servidor. * *************************************************************************/ int escogeAleatorio() { int i, n, aleatorio, P, U; /* Indices, entre 0 y NUM_PALABRAS-1. Son NUM_PALABRAS palabras*/ P = 0; U = NUM_PALABRAS-1; srand(time(NULL)); aleatorio = P+(int)(((U-P+1.0)*rand())/(RAND_MAX+1.0)); return aleatorio; } /************************************************************************* * * reaper - Limpia los hijos en estado zombie. * *************************************************************************/ void reaper(int sig) { int status; while (wait3(&status, WNOHANG, (struct rusage *)0) >= 0) /* empty */; }
Código fuente del Cliente:
/************************************************************************* * * Cliente del juego Ahorcado en TCP. * Asignatura: Redes II. * Autores: * Gabriel Cebrián Márquez. * EstefanÃa Coronado Calero. * Iván Durango Blanco. * ************************************************************************/ #include#include #include #include #include #include /*extern int errno;*/ #include "error.h" #include "socket_utils.h" /* LibrerÃas incluÃdas */ #include "miconio.h" int ahorcadoCli(const char *host, const char *service); int comparacion(char *c1); void leerDeServidor(char *buf, int socket); #define MAXLINEA 42 /* Máximo tamaño de la lÃnea que recibiremos. */ /************************************************************************* * * Main - Cliente ahorcado TCP. * ************************************************************************/ int main(int argc, char *argv[]) { char *host = "localhost"; /* Host que se usa si no se indica ninguno */ char *service = "8041"; /* Nombre del servicio por defecto */ char nombreServidor[256]; /* Almacenará el nombre del servidor, si fuera necesario. */ switch (argc) { case 1: printf("Indica el nombre del host o IP al que conectar: "); scanf("%s", nombreServidor); fflush(stdin); host = nombreServidor; break; case 2: host = argv[1]; break; default: fprintf(stderr, "Uso del programa: Ahorcado_cliente [host]\n"); exit(1); } ahorcadoCli(host, service); exit(0); } /************************************************************************* * * ahorcadoCli - Función que gestiona el juego para el cliente. * ************************************************************************/ int ahorcadoCli(const char *host, const char *service) { char buf[MAXLINEA+1]; /* Buffer para intercambio de información */ int socket; /* Descripción del socket */ int outchars; /* Número de caracteres enviados */ socket = connectTCP(host, service); printf("\n======================================="); printf("\n AHORCADO REMOTO"); printf("\n======================================="); printf(""); printf("\nInstrucciones: El servidor elegirá aleatoriamente una palabra que usted tendrá"); printf("\n que adivinar."); printf("\nDispone de 8 intentos para acertarla. En cada intento podrá elegir una letra."); printf("\nSi la palabra a adivinar la contiene, esta aparecerá en su lugar."); printf("\nSi usted repite una letra se le añadirá un fallo a su lista. El juego finalizará"); printf("\n si usted adivina la palabra o por el contrario se muestra la palabra AHORCADO."); printf("\n\n\nErrores: Palabra a adivinar:"); printf("\n\n"); /* Leemos la cadena del servidor donde se nos ofrece la primera pista. */ leerDeServidor(buf, socket); printf("%s\n",buf); while (buf[0] = getch()) { if (((buf[0] >= 'A') && (buf[0] <= 'Z')) || ((buf[0] >= 'a') && (buf[0] <= 'z'))) { buf[MAXLINEA] = '\0'; /* Fin de linea */ outchars = strlen(buf); if (send(socket, buf, outchars) < 0) errexit("Error SEND: %s\n", strerror(errno));; /* Se lee del servidor */ leerDeServidor(buf, socket); if(comparacion(buf) == 1) { printf("%s\n",buf); /* Hemos llegado al final, ganando o perdiendo, imprimimos dos lÃneas. */ leerDeServidor(buf, socket); printf("%s\n",buf); close(socket); exit(0); } printf("%s\n",buf); } } } /************************************************************************* * * comparacion - Función que determina cuando finaliza el cliente, acabará * cuando el servidor responde FIN. * Si hemos llegado al final retorna 1. De lo contrario retorna 0. * ************************************************************************/ int comparacion(char *c1) { char palabra[] = "FIN"; int i; for (i = 0; i<3; i++) { if (c1[i]!=palabra[i]) return 0; } return 1; } /************************************************************************* * * leerDeServidor - Función que recoje lo que el servidor envÃa. * **************************************************************************/ void leerDeServidor(char *buf, int socket) { int inchars; int n; for (inchars = 0; inchars < MAXLINEA; inchars += n) { n = read(socket, &buf[inchars], MAXLINEA - inchars); if (n < 0) errexit("Error READ: %s\n", strerror(errno)); } }
Link para descargar el código fuente:
Codigo_fuente_ahorcado
Para más información sobre como ejecutar, como a sido diseñado, etc visitar:
http://aprendiendo2veces.blogspot.com/2011/04/aplicacion-cliente-servidor-ahorcado.html
2 comentarios:
Hola q tal, q bibliotecas tengo q enlazar a la hora de compilar, es decir como lo compilo
Hola, para compilar se puede utilizar el compilador GCC de Linux introduciendo los
siguientes comandos según queramos para el cliente o el servidor:
Para el cliente:
gcc Ahorcado_cliente.c socket_utils.c error.c miconio.c -o Ahorcado_cliente
Para el servidor:
gcc Ahorcado_servidor.c socket_utils.c error.c -o Ahorcado_servidor
Las bibliotecas:
socket_utils.c error.c miconio.c
Las subo para que las puedas descargar. Además te añado tambien el makefile, con el que puedes compilar ejecutando desde Linux:
$ make all
Saludos!!
Publicar un comentario