Sala de chat en C para 100 usuarios

Creando el cliente

06 de Diciembre de 2019

Dificultad
Conocimiento de C 75%
baner-chat-100

Descargar el proyecto completo

El cliente es quien se conectará al servidor, quien enviará mensajes y recibirá mensajes de otros clientes. En principio como debe ser una sala de chat. 
Librerías:
Algunas de las librerías que estaremos utilizando seran estas: 
#include  -  Contiene las definiciones de las macros, las constantes, las declaraciones de funciones de la biblioteca estándar del lenguaje de programación C para hacer operaciones, estándar, de entrada y salida.
#include  -  Biblioteca estándar de propósito general del lenguaje de programación C. Contiene los prototipos de funciones de C para gestión de memoria dinámica, control de procesos y otras.
#include  - Contiene algunas funciones y tipos y algunas operaciones de manipulación de memoria.
#include  - Define constantes y tipos simbólicos misceláneos, y declara funciones misceláneas. 
#include <sys/types.h>  - Define algunos tipos adicionales.
#include <sys/socket.h> -  Define alguno tipos y macros para establecer una conexión con otro ordenador que nos permitirá intercambiar datos.
#include <netinet/in.h>
#include <arpa/inet.h>
#include  - Define algunas funciones y tipos para manejar procesos hijos o hilos dentro de nuestros programas.

#include "commons.h" - define algunas funciones comunes que utilizaremos en el proyecto.
 

Funciones:

void emisor(); //maneja los mensajes de entrada 
void receptor(); //maneja los mensajes de entrada 
int main(int argc, char **argv);
Las funciones del codigo del cliente se explican por sí solas, tendremos un proceso central en el main que será el encargado de configurar y establecer inicialmente una conexión con el servidor, mientras que las otras funciones son hilos apartes encargados de manejar los mensajes entrantes y salientes.

Función main

La primera parte, la definición misma de la función y tal vez muchos iniciados en el lenguaje nunca la hayan visto, son esos dos argumentos de la función.

 

int main(int argc, char **argv)

Y es de saber que la función recibe dos parámetros, un número y un array de punteros a caracteres. Estos argumentos vienen desde cuando se ejecuta el programa desde una consola y se le pasan lo que llamamos argumentos del sistema.

arg-system

De esta manera al ejecutar la linea “./client 8000” le estariamos mandando los siguientes datos a la función main. 

argc argv
2 [“./client”,”8000”]

Una vez aclaramos esto, utilizamos esta función, para pasarle directamente el puerto de la máquina al que queremos que se conecte.

if (argc != 2)
    {
        printf("Uso: %s \n", argv[0]);
        return EXIT_FAILURE;
    }
 
    char *ip = "127.0.0.1";
    int port = atoi(argv[1]); //Convierte string a int

Se define la ip del servidor, que como estamos en la misma máquina, es la ip local y procedemos a configurar la conexión del socket.

struct sockaddr_in server_addr;
 
// Configuracion del Socket 
sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ip);
server_addr.sin_port = htons(port);
Todas estas son configuraciones necesarias a la hora de conectarnos a la red ya sea local, entre varias máquinas o a la internet. 

Entonces estaría listo para conectarse: 
int err = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (err == -1)
{
   printf("ERROR: conectando\n");
   return EXIT_FAILURE;
}

Connect es una librería de socket que intenta establecer una coneccion a la dirección ip y el puerto que se le designaron, si la coneccion es fallida, devuelve un -1. Una vez exitosa la coneccion se lleva a cabo el primer mensaje al servidor, que es el nombre de usuario que se pidió anteriormente. Se crean 2 hilos para manejar tanto las comunicaciones entrantes y salientes.

send(sockfd, name, 32, 0);
 
printf("=== Bienvenido a la sala de chat ===\n");
pthread_t hilo_emisor; //Creacion del hilo emisor
 
if (pthread_create(&hilo_emisor, NULL, (void *)emisor, NULL) != 0)
{
    printf("ERROR: pthread  - Hilo del emisor\n");
    return EXIT_FAILURE;
}
 
pthread_t hilo_receptor; //Creacion del hilo receptor
if (pthread_create(&hilo_receptor, NULL, (void *)receptor, NULL) != 0)
{
    printf("ERROR: pthread - Hilo del receptor\n");
    return EXIT_FAILURE;
}
Ya al final este proceso quedará en un bucle infinito y para desconectarse del chat será con Ctrl+C.

Función Emisor

Una vez establecida la conexión con el servidor el hilo emisor llama a la función emisor y esperará hasta que el usuario realice una entrada en el teclado.
void emisor()
{
    char message[LENGTH] = {};
    char buffer[LENGTH + 32] = {};
 
 
    while (1)
    {
        memset(message, 0, LENGTH); //resetea el buffer de mensajes
        memset(buffer, 0, LENGTH+32); //resetea el buffer de mensajes
        reset_stdout();  // Vacía el búfer de salida.
 
        fgets(message, LENGTH, stdin); //captura el mensaje del usuario
        
        message[strcspn(message, "\n")] = '\0'; //elimina los saltos de linea
        
        sprintf(buffer, "%s-> %s\n", name, message);
        
        send(sockfd, buffer, strlen(buffer), 0); //envia el mensaje all servidor
    }
}

Función Receptor

Este hilo constantemente está comprobando los mensajes recibidos por el socket desde el servidor y se encarga de imprimirlos en pantalla.
void receptor()
{
    char message[LENGTH] = {};
    while (1)
    {
        int receive = recv(sockfd, message, LENGTH, 0); //recibe los mensajes del servidor
        if (receive > 0)
        {
            printf("%s", message); //Imprime los mensajes del servidor
            reset_stdout();  // Vacía el búfer de salida.
        }
        else if (receive == 0)
        {
            break;
        }
        else
        {
            // -1
        }
        memset(message, 0, sizeof(message)); //resetea el buffer de mensajes
    }
}
Y así cada vez que realice una nueva entrada, esté while infinito, enviará los mensajes, ya formateados con el nombre del emisor al servidor.
A continuacion en la siguiente parte del tutorial, empezaremos con el codigo del servidor. 

Descargar el proyecto completo

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Otros Posts: