//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//ENTRADA-SALIDA
//*****************entrada_salida.h*************************
//++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++--LENGUAJE C --TRABAJO CON SOCKETS-- ++++++++
//****Programado por HILARIO IGLESIAS MARTÍNEZ****
//Laminador jubilado deL Tren de Alambrón de
//Arcelor Mittal en Gijón -ASTURIAS-
// https://es.wikipedia.org/wiki/Tren_de_alambron
//*******************************************
//Cuestiones o dudas a: idusdruida51@gmail.com
//Realizado en plataforma LINUX Ubuntu 20.04.4 LTS.
//Bajo el standard ANSI C.-C-11
//Usado el IDE Sublime Text.
//****************************************************
//Includes necesarios para el funcionamiento del Servidor.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netdb.h>
//Declaración de la estructura sockaddr contenidas en #include<netinet/in.h>
struct sockaddr;
// Declaramos una función destinada para el chat cliente servidor.
void lafunc(int chatServClient)
{
char buferIntercambio[90]; //Reserva de buffer para el intercambio de 90bytes write y read
int h;
// Este es un bucle repetitivo read >-> write para el chat interactivo
for (;;) {
bzero(buferIntercambio, 90);//borra los datos en los n bytes de la memoria
//comenzando en la ubicación señalada , escribiendo ceros (bytes que contiene '\0') en esa área.
// Leemos el mensaje del cliente y lo copiamos en buferIntermedio.
read(chatServClient, buferIntercambio, sizeof(buferIntercambio));
// Imprimimos el contenido del buffer del cliente.
printf("Mensaje del cliente: %s\t : ", buferIntercambio);
bzero( buferIntercambio,90);//volvemos a borrar datos
h = 0;
// Copiamos el mensaje del Servidor en el buffer.
while ((buferIntercambio[h++] = getchar()) != '\n');
//repetir bucle mientras no sea igual.
//chatServClient es el nuevo descriptor de socket creado por aceppt.
//Para cada cliente aceptado se crear'un nuevo Descriptor Socket
// Mandamos el contenido del bufer al client utilizando la función write().
write(chatServClient, buferIntercambio, sizeof(buferIntercambio));
// Si el mensaje contiene "Exit" entonces el seridor sale y el chat termina.
if (strncmp("hasta luego lucas", buferIntercambio, 16) == 0)
// la llamada strncmp compara caracteres,
//en este caso le decimos que compare 16.
// si el servidor manda el mensaje "hasta luego lucas" 16 bytes --16) == 0)
//el servidor saldrá de la conexión
{
printf("Salida del Servidor\n");
break;
}
}
}
---------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------
//*****************SERVIDOR*************************
//++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++--LENGUAJE C --TRABAJO CON SOCKETS-- ++++++++
//****Programado por HILARIO IGLESIAS MARTÍNEZ****
//Laminador jubilado deL Tren de Alambrón de
//Arcelor Mittal en Gijón -ASTURIAS-
// https://es.wikipedia.org/wiki/Tren_de_alambron
//*******************************************
//Cuestiones o dudas a: idusdruida51@gmail.com
//Realizado en plataforma LINUX Ubuntu 20.04.4 LTS.
//Bajo el standard ANSI C.-C-11
//Usado el IDE Sublime Text.
//Compilación: gcc archivo.c -o archivo
//Para prueba en el propio equipo se utiliza host 127.0.0.1
//Se puede hacer prueba en la consola de LINUX
//En una consola se abre el Servidor, en otra se abre el Cliente.
//Puedes probar este Servidor con el CLIENTE adjunto.
//También puedes probarlo con la utilidad TELNET
//abriendos dos consolas Linux.
//entrada_salida.h debe estar en el mismo directorio a la hora de
//compilar con gcc.
//***************************************************
#include<stdio.h>
#include "entrada_salida.h" //Debemos incluir nuestra entrada_salida.h entre ""
int main()
{
//declaracion de variables.
int sockDescriptor, chatServClient, Larg,lon_MiServ;
struct sockaddr_in strucServidor, struCliente;
// Creación del Socket y comprobación de su ejecución, si devuelve -1 el descriptor habrá error
sockDescriptor = socket(AF_INET, SOCK_STREAM, 0);
if (sockDescriptor == -1) {
printf("La creación del socket no ha tenido exito\n");
exit(0);
}
else
printf("Socket creado con éxito\n");
bzero(&strucServidor, sizeof(strucServidor));
//En vez de pasar el puerto por argumento de main, lo hacemos por medio de la entrada standard scanf.
printf("***************************************************************************************\n" );
printf("---PARA EVITAR CONFLICTOS CON PUERTOS EN USO, INTRODUCE UN PUERTO POR ENCIMA DE 1000---\n");
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
char puerto [20];
scanf("%s",puerto);
int valor =atoi(puerto); //Esta función convierte el argumento de una cadena en un número entero (tipo int).
printf("Valor covertido por atoi() %i\n",valor );
//*****************************
// assign IP, PORT
strucServidor.sin_family = AF_INET;
strucServidor.sin_addr.s_addr = htonl(INADDR_ANY); // (Adaptacion Little Endian o Big Endian) para red
strucServidor.sin_port = htons(valor); //La función htons convierte un u_short de host
// a orden de bytes de red TCP/IP ( big-endian).
// Binding newly created socket to given IP and verification
if ((bind(sockDescriptor, (struct sockaddr *)&strucServidor, sizeof(strucServidor))) != 0) {
printf("socket bind ha fallado...\n");
exit(0);
}
else
printf("Socket enlazado con éxito.\n");
printf("Tamaño de la strucServidor = %li\n", sizeof(strucServidor));
//******************************************************
//Ver el número de puerto. Ejemplo de utilización de getsockname.
lon_MiServ=sizeof(strucServidor);
getsockname (sockDescriptor,(struct sockaddr *)&strucServidor,&lon_MiServ);//hacemos un cast a (struct sockaddr *)
printf("Cualquier dirección IP: %d , PUERTO:, %d\n",htonl(INADDR_ANY),ntohs(strucServidor.sin_port));
printf("La IP local es: %s\n", inet_ntoa(strucServidor.sin_addr));
printf("El Puerto local de conexión es: %d\n", (int) ntohs(strucServidor.sin_port));
//*******************************************************************
// Ahora el Servidor está preparado para escuchar
if ((listen(sockDescriptor, 5)) != 0) { //Ponemos el socket a escuchar, y una cola máxima de 5 clientes.
printf("La escucha de Clientes ha fallado...\n");
exit(0);
}
else
printf("El Servidor está preparado\n");
Larg = sizeof(struCliente);
// Aceptamos datos del cliente.
chatServClient = accept(sockDescriptor, (struct sockaddr *)&struCliente, &Larg);//Nuevo socket abierto por aceppt()
if (chatServClient < 0) {
printf("El servidor no ha aceptado\n");
exit(0);
}
else
printf("El servidor acepta CLIENTE con nuevo SOCKET-Descriptor %d: \n",chatServClient);
// Llamada a la función lafunc que trabajará con los buffer
lafunc(chatServClient);
// El socket descriptor es cerrado
close(sockDescriptor);
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//*****************CLIENTE*************************
//++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++--LENGUAJE C --TRABAJO CON SOCKETS-- ++++++++
//****Programado por HILARIO IGLESIAS MARTÍNEZ****
//Laminador jubilado deL Tren de Alambrón de
//Arcelor Mittal en Gijón -ASTURIAS-
// https://es.wikipedia.org/wiki/Tren_de_alambron
//*******************************************
//Cuestiones o dudas a: idusdruida51@gmail.com
//Realizado en plataforma LINUX Ubuntu 20.04.4 LTS.
//Bajo el standard ANSI C.-C-11
//Usado el IDE Sublime Text.
//Compilación: gcc archivo.c -o archivo
//Para prueba en el propio equipo se utiliza host 127.0.0.1
//Se puede hacer prueba en la consola de LINUX
//En una consola se abre el Servidor, en otra se abre el Cliente.
//Si no se quiere utilizar este cliente,
// se puede utilizar la utilidad telnet como cliente
//*************************************************************
//Declaración de librerias.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netdb.h>
void funcion_CHAT(int socket_Descriptor) //declaración de la función de llamada
{
char IntercambioBueffer[90]; //dimensionamos con 90 bytes el buffer de intercambio
int InterBufer;
for (;;) { //Bucle repetitivo lectura escritura
bzero(IntercambioBueffer, sizeof(IntercambioBueffer));//borramos el buffer
printf("Introduce EL MENSAJE: ");
InterBufer = 0;
while ((IntercambioBueffer[InterBufer++] = getchar()) != '\n');
write(socket_Descriptor, IntercambioBueffer, sizeof(IntercambioBueffer));
bzero(IntercambioBueffer, sizeof(IntercambioBueffer));
read(socket_Descriptor, IntercambioBueffer, sizeof(IntercambioBueffer));
printf("Envio del SERVIDOR: %s", IntercambioBueffer);
if ((strncmp(IntercambioBueffer, "hasta luego lucas", 16)) == 0) {
printf("El Cliente ha salido\n");
break;
}
}
}
int main(int argc, char const **argv)
{
// Pasamos el puerto por argumento de main.
if(argc<2)
{
printf("<Debes introducir host 127.0.0.1> <Y el puerto que has seleccionado en el Servidor>\n");
return 1;
}
int socket_Descriptor,puerto;
struct sockaddr_in servidorChat, clienteChat;
struct hostent *servidor;
servidor = gethostbyname(argv[1]); //Asignacion
// Testeo del host
if(servidor == NULL)
{ //Comprobación
printf("El Host no existe\n");
return 1;
}
// Creación del descriptor Socket, y verificación.
socket_Descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (socket_Descriptor == -1) {
printf("La creación del socket ha fallado\n");
exit(0);
}
else
printf("El socket Descriptor se ha creado con éxito\n");
bzero(&servidorChat, sizeof(servidorChat));
puerto=(atoi(argv[2]));
// Asignación de la IP, y el PUERTO correspondiente
servidorChat.sin_family = AF_INET;
servidorChat.sin_addr.s_addr = inet_addr("127.0.0.1"); //La IP, por defecto para probar el chat, con
//Telnet o el Cliente
servidorChat.sin_port = htons(puerto); //conversión de valores
// conexión del Cliente con el Servidor
if (connect(socket_Descriptor, (struct sockaddr*)&servidorChat, sizeof(servidorChat)) != 0) {
printf("La conexión con el servidor ha fallado\n");
exit(0);
}
else
printf("Se ha conectado con el Servidor\n");
// Llamada a la función declarada
funcion_CHAT(socket_Descriptor);
// Cierra el socket_Descriptor
close(socket_Descriptor);
}