[SOLUCIONADO] Expulsar un cliente de un servidor

Iniciado por Frijolito, Octubre 16, 2018, 12:21:05 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Octubre 16, 2018, 12:21:05 PM Ultima modificación: Octubre 16, 2018, 08:53:38 PM por Gabriela
Hola, hace unos días estaba haciendo un servidor y la cosa es que en la parte donde se tiene que logear para quiero hacer que si alguien escribe mas las pass con el user lo expulse después de una cantidad de intentos pero no se expulsar a un cliente si alguien me podría ayudar todo esta escrito en c con linux, es primera vez que me meto con el temas de sockets por eso la ignorancia , de todas formas gracias de antemano.

Octubre 16, 2018, 12:28:13 PM #1 Ultima modificación: Octubre 16, 2018, 12:36:47 PM por solid water
Puedes reconocer al cliente por un ID que es lo más indicado ya que 2 clientes pueden tener el mismo IP, entonces cuentas sus conexiones fallidas y cierras la conexión del socket con close.

Así puedas identificar el cliente por un ID, sería bueno que tengas en cuenta lo del IP por si más adelante sientes necesidad de bannear ips.

Más adelante en un sistema más avanzado podrías pedir que se te brinde el hwid o algo similar para banear por hardware id.

Saludos,

Octubre 16, 2018, 02:51:14 PM #2 Ultima modificación: Octubre 16, 2018, 02:52:52 PM por Frijolito
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Puedes reconocer al cliente por un ID que es lo más indicado ya que 2 clientes pueden tener el mismo IP, entonces cuentas sus conexiones fallidas y cierras la conexión del socket con close.

Así puedas identificar el cliente por un ID, sería bueno que tengas en cuenta lo del IP por si más adelante sientes necesidad de bannear ips.

Más adelante en un sistema más avanzado podrías pedir que se te brinde el hwid o algo similar para banear por hardware id.

Saludos,

El ID del cliente se encuentra a en estructura sockaddr_in ?  al hacer 3 intentos y que fallen los 3 lo que pasas es que uso el close(socket del cliente) pero en la terminal del servidor me dice "Violación de segmento (`core' generado)"  y se cierra el servidor, para conectarme al servidor uso el comando telnet no se si el problema es usar el telnet o tendría que programar un cliente

Hola mira yo creo que todo esto viene por que intentas crear un sistema anti fuerza bruta.

La idea sería que cuando un usuario hace un log-in fallido guardes en una base de datos (mysql va bien con ubuntu) el ip la fecha y hora.
Luego cada vez que quiere conectarse haces un select a ese ip para contar todos los intentos fallidos en un intervalo de tiempo, es decir si por ejemplo hizo 10 en una hora no lo dejas conectarse por 12 horas.

El problema que tiene esto es que si se conectan desde la misma red por ejemplo wifi o un cibercafe todos tienen la misma ip pública por lo que confundes 2 usuarios con 1 solo, pero no está del todo mal para comenzar.

Con que los reconozcas por ID quiero hacer énfasis a que por ejemplo en el server cuando llegan o salen mensajes tengas una lista de clientes   list[i_ClientID]->Enviar_Datos(); entonces tu los reconoces por el ID y no caes en la trampa de reconocerlos por ip ya que puede haber 2 clientes con el mismo ip y le mandas mensajes al cliente equivocado.
Supongo que de algún modo ya estas reconociéndolos.

Con respecto al error que te tira, no estoy demasiado ducho en el tema, pero si compartes el código es posible que alguien pueda ayudarte.

Saludos,

Octubre 16, 2018, 05:25:43 PM #4 Ultima modificación: Octubre 16, 2018, 05:27:57 PM por Frijolito
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hola mira yo creo que todo esto viene por que intentas crear un sistema anti fuerza bruta.

La idea sería que cuando un usuario hace un log-in fallido guardes en una base de datos (mysql va bien con ubuntu) el ip la fecha y hora.
Luego cada vez que quiere conectarse haces un select a ese ip para contar todos los intentos fallidos en un intervalo de tiempo, es decir si por ejemplo hizo 10 en una hora no lo dejas conectarse por 12 horas.

El problema que tiene esto es que si se conectan desde la misma red por ejemplo wifi o un cibercafe todos tienen la misma ip pública por lo que confundes 2 usuarios con 1 solo, pero no está del todo mal para comenzar.

Con que los reconozcas por ID quiero hacer énfasis a que por ejemplo en el server cuando llegan o salen mensajes tengas una lista de clientes   list[i_ClientID]->Enviar_Datos(); entonces tu los reconoces por el ID y no caes en la trampa de reconocerlos por ip ya que puede haber 2 clientes con el mismo ip y le mandas mensajes al cliente equivocado.
Supongo que de algún modo ya estas reconociéndolos.

Con respecto al error que te tira, no estoy demasiado ducho en el tema, pero si compartes el código es posible que alguien pueda ayudarte.

Saludos,
ese es el codigo si me puedes ayudar con el problema, gracias de antemano <3
Código: c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/sendfile.h> //Sirve para poder enviar archivos
#include <sys/types.h> //Sirve para poder recivir archivos
#include <linux/if_packet.h>
#include <sys/ioctl.h> // Estas 2 librerias son para poder saber algunos datos sobre el
#include <net/if.h> // Cliente en cuention

#define BUFFSIZE 1
#define ERROR -1

// Funciones //

void login(int socket_cliente, char user[9], char pass[8]);
void direccip(int socket_cliente, struct sockaddr_in addr);
void salir(int socket_servidor, int socket_cliente);
void enviar(int socket_cliente, FILE* archivo);

int main(){

int socket_servidor; //Socket del servidor para escuchar mensajes
int socket_cliente; //Socket del cliente para enviar mesajes
int puerto = 15560; //Numero de puerto en /etc/service
char indicered[100]; //Inidece de red
char texto[50]; //Mensaje para usar los comandos
char pass[8]; //Contrasena
char user[9]; //Usuario
FILE * archivo; //Archivo sin formato

socket_servidor = socket(AF_INET, SOCK_STREAM, 0);
socklen_t longc;

// Declaracion de las escructuras;
struct sockaddr_in servidor, cliente; //Creamos las estructuras del cliente y servidor al mismo tiempo
bzero((char *)&servidor, sizeof(servidor)); //Primero llenamos de 0's la struct
servidor.sin_family = AF_INET; //Asiganamos la estructura
servidor.sin_port = htons(puerto); //Indicamos el puerto
servidor.sin_addr.s_addr = INADDR_ANY; //Esta macro especifica nuestra direccion

if(bind(socket_servidor, (struct sockaddr *)&servidor, sizeof(servidor)) < 0){ //asignamos un puerto al socket
    printf("Error al asociar el puerto a la conexion\n");
    return 1;
}
listen(socket_servidor,3); //Escuchamos por este puero maximo 2 clientes distintos
printf("Escuchando en el puerto %d\n", ntohs(servidor.sin_port));
longc = sizeof(cliente); //Asignamos el tamano de la estructura a esta variable
socket_cliente = accept(socket_servidor, (struct sockaddr *)&cliente, &longc); // Esperamos una conexion
if(socket_cliente == -1){
printf("Error en al conexion\n");
return 1;
}
printf("Conectando con %s:%d\n",inet_ntoa(cliente.sin_addr),htons(cliente.sin_port));

//Login con el servidor

login(socket_cliente, user, pass);

//Hablar con el servidor

while(free){
bzero(texto, sizeof(texto));
recv(socket_cliente,texto,50,0);
if(strncmp(texto,"IP",2) == 0){
direccip(socket_cliente, cliente);
}
if(strncmp(texto,"EXIT", 4) == 0){
salir(socket_servidor, socket_cliente);
}
if(strncmp(texto,"DESCARGAR", 9) == 0){
enviar(socket_cliente, archivo);
}
}
}
void login(int socket_cliente, char user[9], char pass[8]){
        int intentos = 0;
bzero(user, 9);
bzero(pass, 8);

if(intentos == 3){
close(socket_cliente);
}

send(socket_cliente,"Usuario: ",10,0);
read(socket_cliente,user,9);
send(socket_cliente, "Contrasena: ", 12, 0);
read(socket_cliente, pass, 8);

if(strncmp(user, "frijolito",9) == 0 && strncmp(pass, "abc12345",8) == 0){
}
else{
send(socket_cliente,"Error\n", 7,0);
intentos = intentos + 1;
login(socket_cliente, user, pass);
}
}

void direccip(int socket_cliente, struct sockaddr_in addr){
    write(socket_cliente, "Tu eres: ",9);
    write(socket_cliente, inet_ntoa(addr.sin_addr), 16);
    write(socket_cliente,"\n",2);
}
void salir(int socket_servidor, int socket_cliente){
write(socket_cliente, "ADIOS ;)\n", 10);
close(socket_servidor);
close(socket_servidor);
exit(1);
}
void enviar(int socket_cliente, FILE * archivo){
char buffer[BUFFSIZE];
char mensaje[80];
archivo = fopen("lena.png", "rb");
if(!archivo){
printf("Error al abrir el archivo\n");
send(socket_cliente,"error al abrir el archivo",26,0);
}
while(!feof(archivo)){
fread(buffer,sizeof(char),BUFFSIZE, archivo);
if(send(socket_cliente,buffer,BUFFSIZE,0) == ERROR){
perror("Error al enviar el arvhivo:");
}
}
}

Octubre 16, 2018, 05:47:30 PM #5 Ultima modificación: Octubre 17, 2018, 08:56:03 AM por solid water
Hola no estoy seguro que sea esto pero podrías probar.
Cuando le haces un close socket cliente, luego sigues enviandole cosas, deberìas poner un return si fallo 3 veces:

Código: c++

void login(int socket_cliente, char user[9], char pass[8]){
        int intentos = 0;
        bzero(user, 9);
        bzero(pass, 8);

         if(intentos == 3){
                close(socket_cliente);
                return;
        }

        send(socket_cliente,"Usuario: ",10,0);
        read(socket_cliente,user,9);
        send(socket_cliente, "Contrasena: ", 12, 0);
        read(socket_cliente, pass, 8);


Y lo mismo luego, al salir de la función aunque el login haya fallado sigues usando socket_cliente, deberías hacer que en lugar de retornar void, login retorne un int o un bool, que si se conecta bien devuelva 1 y si no 0, entonces si devuelve 0 no utilizas más socket_cliente ya que lo cerraste, si no te sale ahora en un rato vengo y te ayudo a modificarlo.

Saludos,

Octubre 16, 2018, 06:47:49 PM #6 Ultima modificación: Octubre 16, 2018, 07:00:15 PM por solid water
Así funciona bien el login fallido y no tira error.
Lo que si fíjate cuando haces log-in bien, a mi es como que no se me limpia el buffer de entrada y me inserta un salto por lo que no me deja ingresar bien la contraseña nunca, pero si a vos te funcionaba bien esa parte la dejé igual que siempre.

Código: c++

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/sendfile.h>               //Sirve para poder enviar archivos
#include <sys/types.h>                  //Sirve para poder recivir archivos
#include <linux/if_packet.h>
#include <sys/ioctl.h>                  // Estas 2 librerias son para poder saber algunos datos sobre el
#include <net/if.h>                             // Cliente en cuention

#define BUFFSIZE 1
#define ERROR -1

// Funciones //

int login(int socket_cliente, char user[9], char pass[8]);
void direccip(int socket_cliente, struct sockaddr_in addr);
void salir(int socket_servidor, int socket_cliente);
void enviar(int socket_cliente, FILE* archivo);
int intentos = 0;

int main(){

        int socket_servidor;            //Socket del servidor para escuchar mensajes
        int socket_cliente;                     //Socket del cliente para enviar mesajes
        int puerto = 15560;                     //Numero de puerto en /etc/service
        char indicered[100];            //Inidece de red
        char texto[50];                         //Mensaje para usar los comandos
        char pass[8];                           //Contrasena
        char user[9];                           //Usuario
        FILE * archivo;                         //Archivo sin formato

        socket_servidor = socket(AF_INET, SOCK_STREAM, 0);
        socklen_t longc;

        // Declaracion de las escructuras;
        struct sockaddr_in servidor, cliente;           //Creamos las estructuras del cliente y servidor al mismo tiempo
        bzero((char *)&servidor, sizeof(servidor)); //Primero llenamos de 0's la struct
        servidor.sin_family = AF_INET;                          //Asiganamos la estructura
        servidor.sin_port = htons(puerto);                      //Indicamos el puerto
        servidor.sin_addr.s_addr = INADDR_ANY;          //Esta macro especifica nuestra direccion

        if(bind(socket_servidor, (struct sockaddr *)&servidor, sizeof(servidor)) < 0){ //asignamos un puerto al socket
                printf("Error al asociar el puerto a la conexion\n");
        return 1;
        }
        listen(socket_servidor,3);                              //Escuchamos por este puero maximo 2 clientes distintos
        printf("Escuchando en el puerto %d\n", ntohs(servidor.sin_port));
        longc = sizeof(cliente);                                //Asignamos el tamano de la estructura a esta variable
        socket_cliente = accept(socket_servidor, (struct sockaddr *)&cliente, &longc); // Esperamos una conexion
        if(socket_cliente == -1){
                printf("Error en al conexion\n");
                return 1;
        }
        printf("Conectando con %s:%d\n",inet_ntoa(cliente.sin_addr),htons(cliente.sin_port));

        //Login con el servidor

        int conexion = login(socket_cliente, user, pass);

        //Hablar con el servidor
       if(conexion == 1){
        while(free){
                bzero(texto, sizeof(texto));
                recv(socket_cliente,texto,50,0);
                if(strncmp(texto,"IP",2) == 0){
                        direccip(socket_cliente, cliente);
                }
                if(strncmp(texto,"EXIT", 4) == 0){
                        salir(socket_servidor, socket_cliente);
                }
                if(strncmp(texto,"DESCARGAR", 9) == 0){
                        enviar(socket_cliente, archivo);
                }
        }
        }else{
                printf("Ingreso 3 veces mal usuario");
                system("pause");
                close(socket_servidor);
        }
}
int login(int socket_cliente, char user[9], char pass[8]){

        bzero(user, 9);
        bzero(pass, 8);

         if(intentos == 3){
                close(socket_cliente);
                return 0;
         }

        send(socket_cliente,"Usuario: ",10,0);
        read(socket_cliente,user,9);
        send(socket_cliente, "Contrasena: ", 12, 0);
        read(socket_cliente, pass, 8);

        if(strncmp(user, "frijolito",9) == 0 && strncmp(pass, "abc12345",8) == 0){
             return 1;
        }
        else{
                send(socket_cliente,"Error\n", 7,0);
                intentos = intentos + 1;
                login(socket_cliente, user, pass);

        }
}

void direccip(int socket_cliente, struct sockaddr_in addr){
    write(socket_cliente, "Tu eres: ",9);
    write(socket_cliente, inet_ntoa(addr.sin_addr), 16);
    write(socket_cliente,"\n",2);
}
void salir(int socket_servidor, int socket_cliente){
        write(socket_cliente, "ADIOS ;)\n", 10);
        close(socket_servidor);
        close(socket_servidor);
        exit(1);
}
void enviar(int socket_cliente, FILE * archivo){
        char buffer[BUFFSIZE];
        char mensaje[80];
        archivo = fopen("lena.png", "rb");
        if(!archivo){
                printf("Error al abrir el archivo\n");
                send(socket_cliente,"error al abrir el archivo",26,0);
        }
        while(!feof(archivo)){
                fread(buffer,sizeof(char),BUFFSIZE, archivo);
                if(send(socket_cliente,buffer,BUFFSIZE,0) == ERROR){
                        perror("Error al enviar el arvhivo:");
                }
        }
}


probalo, vas a ver que no crashea y cierra la conexion tras 3 ingresos fallidos.

Saludos,

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hola no estoy seguro que sea esto pero podrías probar.
Cuando le haces un close socket cliente, luego sigues enviandole cosas, deberìas poner un return si fallo 3 veces:

Código: c++

void login(int socket_cliente, char user[9], char pass[8]){
        int intentos = 0;
        bzero(user, 9);
        bzero(pass, 8);

         if(intentos == 3){
                close(socket_cliente);
                return;
        }

        send(socket_cliente,"Usuario: ",10,0);
        read(socket_cliente,user,9);
        send(socket_cliente, "Contrasena: ", 12, 0);
        read(socket_cliente, pass, 8);


Y lo mismo luego, al salir de la funciòn aunque el login haya fallado sigues usando socket_cliente, deberías hacer que en lugar de retornar void, login retorne un int o un bool, que si se conecta bien devuelva 1 y si no 0, entonces si devuelve 0 no utilizas màs socket_cliente ya que lo cerraste, si no te sale ahora en un rato vengo y te ayudo a modificarlo.

Saludos,

gracias me a ayudado mucho y solo era un pequeno error gracias <3

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Así funciona bien el login fallido y no tira error.
Lo que si fíjate cuando haces log-in bien, a mi es como que no se me limpia el buffer de entrada y me inserta un salto por lo que no me deja ingresar bien la contraseña nunca, pero si a vos te funcionaba bien esa parte la dejé igual que siempre.

Código: c++

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/sendfile.h>               //Sirve para poder enviar archivos
#include <sys/types.h>                  //Sirve para poder recivir archivos
#include <linux/if_packet.h>
#include <sys/ioctl.h>                  // Estas 2 librerias son para poder saber algunos datos sobre el
#include <net/if.h>                             // Cliente en cuention

#define BUFFSIZE 1
#define ERROR -1

// Funciones //

int login(int socket_cliente, char user[9], char pass[8]);
void direccip(int socket_cliente, struct sockaddr_in addr);
void salir(int socket_servidor, int socket_cliente);
void enviar(int socket_cliente, FILE* archivo);
int intentos = 0;

int main(){

        int socket_servidor;            //Socket del servidor para escuchar mensajes
        int socket_cliente;                     //Socket del cliente para enviar mesajes
        int puerto = 15560;                     //Numero de puerto en /etc/service
        char indicered[100];            //Inidece de red
        char texto[50];                         //Mensaje para usar los comandos
        char pass[8];                           //Contrasena
        char user[9];                           //Usuario
        FILE * archivo;                         //Archivo sin formato

        socket_servidor = socket(AF_INET, SOCK_STREAM, 0);
        socklen_t longc;

        // Declaracion de las escructuras;
        struct sockaddr_in servidor, cliente;           //Creamos las estructuras del cliente y servidor al mismo tiempo
        bzero((char *)&servidor, sizeof(servidor)); //Primero llenamos de 0's la struct
        servidor.sin_family = AF_INET;                          //Asiganamos la estructura
        servidor.sin_port = htons(puerto);                      //Indicamos el puerto
        servidor.sin_addr.s_addr = INADDR_ANY;          //Esta macro especifica nuestra direccion

        if(bind(socket_servidor, (struct sockaddr *)&servidor, sizeof(servidor)) < 0){ //asignamos un puerto al socket
                printf("Error al asociar el puerto a la conexion\n");
        return 1;
        }
        listen(socket_servidor,3);                              //Escuchamos por este puero maximo 2 clientes distintos
        printf("Escuchando en el puerto %d\n", ntohs(servidor.sin_port));
        longc = sizeof(cliente);                                //Asignamos el tamano de la estructura a esta variable
        socket_cliente = accept(socket_servidor, (struct sockaddr *)&cliente, &longc); // Esperamos una conexion
        if(socket_cliente == -1){
                printf("Error en al conexion\n");
                return 1;
        }
        printf("Conectando con %s:%d\n",inet_ntoa(cliente.sin_addr),htons(cliente.sin_port));

        //Login con el servidor

        int conexion = login(socket_cliente, user, pass);

        //Hablar con el servidor
       if(conexion == 1){
        while(free){
                bzero(texto, sizeof(texto));
                recv(socket_cliente,texto,50,0);
                if(strncmp(texto,"IP",2) == 0){
                        direccip(socket_cliente, cliente);
                }
                if(strncmp(texto,"EXIT", 4) == 0){
                        salir(socket_servidor, socket_cliente);
                }
                if(strncmp(texto,"DESCARGAR", 9) == 0){
                        enviar(socket_cliente, archivo);
                }
        }
        }else{
                printf("Ingreso 3 veces mal usuario");
                system("pause");
                close(socket_servidor);
        }
}
int login(int socket_cliente, char user[9], char pass[8]){

        bzero(user, 9);
        bzero(pass, 8);

         if(intentos == 3){
                close(socket_cliente);
                return 0;
         }

        send(socket_cliente,"Usuario: ",10,0);
        read(socket_cliente,user,9);
        send(socket_cliente, "Contrasena: ", 12, 0);
        read(socket_cliente, pass, 8);

        if(strncmp(user, "frijolito",9) == 0 && strncmp(pass, "abc12345",8) == 0){
             return 1;
        }
        else{
                send(socket_cliente,"Error\n", 7,0);
                intentos = intentos + 1;
                login(socket_cliente, user, pass);

        }
}

void direccip(int socket_cliente, struct sockaddr_in addr){
    write(socket_cliente, "Tu eres: ",9);
    write(socket_cliente, inet_ntoa(addr.sin_addr), 16);
    write(socket_cliente,"\n",2);
}
void salir(int socket_servidor, int socket_cliente){
        write(socket_cliente, "ADIOS ;)\n", 10);
        close(socket_servidor);
        close(socket_servidor);
        exit(1);
}
void enviar(int socket_cliente, FILE * archivo){
        char buffer[BUFFSIZE];
        char mensaje[80];
        archivo = fopen("lena.png", "rb");
        if(!archivo){
                printf("Error al abrir el archivo\n");
                send(socket_cliente,"error al abrir el archivo",26,0);
        }
        while(!feof(archivo)){
                fread(buffer,sizeof(char),BUFFSIZE, archivo);
                if(send(socket_cliente,buffer,BUFFSIZE,0) == ERROR){
                        perror("Error al enviar el arvhivo:");
                }
        }
}


probalo, vas a ver que no crashea y cierra la conexion tras 3 ingresos fallidos.

Saludos,

El código funciona y gracias por eso, pero el problema es que el servidor tambien se cierra al poner 3 veces mal las credenciales la idea es que solo se saque al cliente no al server

Octubre 17, 2018, 07:35:11 PM #9 Ultima modificación: Octubre 18, 2018, 08:56:18 AM por solid water
Eso es por que vos no tenes un bucle en un proceso padre que espere clientes, vos esperas uno solo y seguís el flujo de tu programa hacia el final.
En internet tenés ejemplos de como aceptar múltiples clientes y usar fork.

Por ejemplo mira este: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta


Mira si lo pones así logras que el server no se cierre y vuelva a aceptar clientes: (Pero seguis aceptando solo 1 cliente por vez no podes aceptar muchos simultaneos si no implementas lo que te dije antes):

Código: c++
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/sendfile.h>               //Sirve para poder enviar archivos
#include <sys/types.h>                  //Sirve para poder recivir archivos
#include <linux/if_packet.h>
#include <sys/ioctl.h>                  // Estas 2 librerias son para poder saber algunos datos sobre el
#include <net/if.h>                             // Cliente en cuention

#define BUFFSIZE 1
#define ERROR -1

// Funciones //

int login(int socket_cliente, char user[9], char pass[8]);
void direccip(int socket_cliente, struct sockaddr_in addr);
void salir(int socket_servidor, int socket_cliente);
void enviar(int socket_cliente, FILE* archivo);
int intentos = 0;

int main(){

        int socket_servidor;            //Socket del servidor para escuchar mensajes
        int socket_cliente;                     //Socket del cliente para enviar mesajes
        int puerto = 15560;                     //Numero de puerto en /etc/service
        char indicered[100];            //Inidece de red
        char texto[50];                         //Mensaje para usar los comandos
        char pass[8];                           //Contrasena
        char user[9];                           //Usuario
        FILE * archivo;                         //Archivo sin formato

        socket_servidor = socket(AF_INET, SOCK_STREAM, 0);
        socklen_t longc;

        // Declaracion de las escructuras;
        struct sockaddr_in servidor, cliente;           //Creamos las estructuras del cliente y servidor al mismo tiempo
        bzero((char *)&servidor, sizeof(servidor)); //Primero llenamos de 0's la struct
        servidor.sin_family = AF_INET;                          //Asiganamos la estructura
        servidor.sin_port = htons(puerto);                      //Indicamos el puerto
        servidor.sin_addr.s_addr = INADDR_ANY;          //Esta macro especifica nuestra direccion

        if(bind(socket_servidor, (struct sockaddr *)&servidor, sizeof(servidor)) < 0){ //asignamos un puerto al socket
                printf("Error al asociar el puerto a la conexion\n");
        return 1;
        }


        listen(socket_servidor,3);                              //Escuchamos por este puero maximo 2 clientes distintos
while(true){
        intentos = 0;
        printf("Escuchando en el puerto %d\n", ntohs(servidor.sin_port));
        longc = sizeof(cliente);                                //Asignamos el tamano de la estructura a esta variable
        socket_cliente = accept(socket_servidor, (struct sockaddr *)&cliente, &longc); // Esperamos una conexion
        if(socket_cliente == -1){
                printf("Error en al conexion\n");
                return 1;
        }
        printf("Conectando con %s:%d\n",inet_ntoa(cliente.sin_addr),htons(cliente.sin_port));

        //Login con el servidor

        int conexion = login(socket_cliente, user, pass);

        //Hablar con el servidor
       if(conexion == 1){
        while(free){
                bzero(texto, sizeof(texto));
                recv(socket_cliente,texto,50,0);
                if(strncmp(texto,"IP",2) == 0){
                        direccip(socket_cliente, cliente);
                }
                if(strncmp(texto,"EXIT", 4) == 0){
                        salir(socket_servidor, socket_cliente);
                }
                if(strncmp(texto,"DESCARGAR", 9) == 0){
                        enviar(socket_cliente, archivo);
                }
        }
}else{
printf("Ingreso 3 veces mal usuario \n\n");
                System("pause");



}
   }
}
int login(int socket_cliente, char user[9], char pass[8]){
       
        bzero(user, 9);
        bzero(pass, 8);

         if(intentos == 3){
                close(socket_cliente);
        return 0;
}

        send(socket_cliente,"Usuario: ",10,0);
        read(socket_cliente,user,9);
        send(socket_cliente, "Contrasena: ", 12, 0);
        read(socket_cliente, pass, 8);

        if(strncmp(user, "frijolito",9) == 0 && strncmp(pass, "abc12345",8) == 0){
             return 1;
}
        else{
                send(socket_cliente,"Error\n", 7,0);
                intentos = intentos + 1;
                login(socket_cliente, user, pass);
       
        }
}

void direccip(int socket_cliente, struct sockaddr_in addr){
    write(socket_cliente, "Tu eres: ",9);
    write(socket_cliente, inet_ntoa(addr.sin_addr), 16);
    write(socket_cliente,"\n",2);
}
void salir(int socket_servidor, int socket_cliente){
        write(socket_cliente, "ADIOS ;)\n", 10);
        close(socket_servidor);
        close(socket_servidor);
        exit(1);
}
void enviar(int socket_cliente, FILE * archivo){
        char buffer[BUFFSIZE];
        char mensaje[80];
        archivo = fopen("lena.png", "rb");
        if(!archivo){
                printf("Error al abrir el archivo\n");
                send(socket_cliente,"error al abrir el archivo",26,0);
        }
        while(!feof(archivo)){
                fread(buffer,sizeof(char),BUFFSIZE, archivo);
                if(send(socket_cliente,buffer,BUFFSIZE,0) == ERROR){
                        perror("Error al enviar el arvhivo:");
                }
        }
}




Saludos,