Para continuar con esta sección recomiendo antes seguir la primera parte: Sockets en C (Parte I) – Linux
Esta sección la quiero dedicar para subir dos ejemplos de un chat interactivo utilizando sockets de flujo entre un servidor y un cliente.
Ejemplo1:
Servidor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | // Ficheros de cabecera #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> //Funcion principal int main( int argc, char **argv) { //Definir variables,estructuras struct sockaddr_in server; struct sockaddr_in client; int fd,fd2,longitud_cliente,numbytes,puerto; char buf[1024]; //Para recibir mensaje char enviar2[1024]; //Para enviar mensaje char enviar[1024]; //Para enviar mensaje system ( "clear" ); printf ( "La direccion del servidor es 127.0.0.1\n\n" ); printf ( "Por favor introduzca el puerto de escucha: \n\n" ); scanf ( "%d" ,&puerto); server.sin_family= AF_INET; server.sin_port = htons(puerto); server.sin_addr.s_addr = INADDR_ANY; bzero(&(server.sin_zero),8); //Definicion de socket if (( fd=socket(AF_INET,SOCK_STREAM,0) )<0){ perror ( "Error de apertura de socket" ); exit (-1); } //Avisar al sistema que se creo un socket if (bind(fd,( struct sockaddr*)&server, sizeof ( struct sockaddr))==-1) { printf ( "error en bind() \n" ); exit (-1); } //Establecer el socket en modo escucha if (listen(fd,5) == -1) { printf ( "error en listen()\n" ); exit (-1); } printf ( "SERVIDOR EN ESPERA...\n" ); longitud_cliente= sizeof ( struct sockaddr_in); if ((fd2 = accept(fd,( struct sockaddr *)&client,&longitud_cliente))==-1) { printf ( "error en accept()\n" ); exit (-1); } printf ( "------SESION INICIADA------\n" ); printf ( "CLIENTE CONECTADO\n" ); strcpy (enviar, "SERVIDOR CONECTADO..." ); send(fd2, enviar, 1024,0); //Ciclo para enviar y recibir mensajes while (1){ //El servidor espera el primer mensaje recv(fd2,buf,1024,0); if ( strcmp (&buf, "salir" )==0){ break ; } printf ( "Cliente: %s\n" ,buf); //El cliente recibe el mensaje del servidor printf ( "Escribir mensaje: " ); scanf ( "%*c%[^\n]" ,enviar2); send(fd2,enviar2,1024,0); if ( strcmp (enviar2, "salir" )==0){ break ; } } close(fd2); close(fd); return 0; } |
Cliente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | // Ficheros de cabecera #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> int main( int argc, char *argv[]) { //Definir variables,estructuras struct sockaddr_in server; char ip[16]; int fd, numbytes,puerto; char buf[1024]; char enviar[1024]; system ( "clear" ); printf ( "ingrese la ip del servidor\n" ); scanf ( "%s" ,ip); printf ( "ingrese el puerto de conexion\n" ); scanf ( "%d" ,&puerto); //Socket if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){ printf ( "socket() error\n" ); exit (-1); } //Datos del servidor server.sin_family = AF_INET; server.sin_port = htons(puerto); server.sin_addr.s_addr=inet_addr(ip); bzero(&(server.sin_zero),8); //Conectarse al servidor if (connect(fd, ( struct sockaddr *)&server, sizeof ( struct sockaddr))==-1){ printf ( "connect() error\n" ); exit (-1); } //Recibir mensaje de bienvenida if ((numbytes=recv(fd,buf,1024,0)) == -1){ printf ( "Error en recv() \n" ); exit (-1); } printf ( "%s\n" ,buf); //Ciclo para enviar y recibir mensajes while (1){ //El servidor espera el primer mensaje printf ( "Escribir mensaje: " ); scanf ( "%*c%[^\n]" ,enviar); send(fd,enviar,1024,0); if ( strcmp (enviar, "salir" )==0){ break ; } //El cliente recibe el mensaje del servidor recv(fd,buf,1024,0); if ( strcmp (buf, "salir" )==0){ break ; } printf ( "Servidor: %s\n" ,buf); } close(fd); } |
Ejemplo2:
Servidor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> main(){ int server_sockfd, client_sockfd; // descriptores de sockets int server_len, client_len; //tamaños de las estructuras struct sockaddr_in server_address; //declaracion de estructuras struct sockaddr_in client_address; char c[1024]; //cadena del cliente char ch[1024]; //cadena del servidor int inicio = 0; //determina el inicio de sesion char cs[1024]; //cadena del servidor int bufs; //almacenamiento del tamanio cadena server int ciclo = 1; //variable para ciclo de lectura escritura int puerto; //variable para el puerto system ( "clear" ); printf ( "La direccion del servidor es 127.0.0.1\n\n" ); printf ( "Por favor introduzca el puerto de escucha: \n\n" ); scanf ( "%d" ,&puerto); server_sockfd = socket(AF_INET, SOCK_STREAM, 0); // se llena la estructura para el servidor con los datos necesarios server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr( "127.0.0.1" ); server_address.sin_port = puerto; server_len = sizeof (server_address); //avisamos al sistema operativo la creacion del socket bind(server_sockfd, ( struct sockaddr *)&server_address, server_len); //decimos al server que quede escuchando listen(server_sockfd,5); printf ( "SERVIDOR EN ESPERA...\n" ); while (ciclo){ //acepta la conexion con el cliente actual client_sockfd = accept(server_sockfd, ( struct sockaddr *)&client_address, &client_len); if (inicio ==0){ printf ( "------SESION INICIADA------\n" ); printf ( "CLIENTE CONECTADO\n" ); strcpy (ch, "SERVIDOR CONECTADO..." ); send(client_sockfd, ch, 1024,0); inicio = 1; } recv(client_sockfd, cs, 1024,0); printf ( "El cliente dijo: %s\n" ,cs); printf ( "ingrese una cadena: \n" ); scanf ( "%*c%[^\n]" ,c); send(client_sockfd, c, 1024,0); close(client_sockfd); } close(server_sockfd); } |
Cliente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> main(){ int sockfd; int len; struct sockaddr_in address; int result; char ch[1024]; char c[1024]; int buf; int inicio = 0; char cs[1024]; int bufs; int ciclo =1; char ipserver[10]; int puerto; system ( "clear" ); printf ( "ingrese la ip del servidor\n" ); scanf ( "%s" ,ipserver); printf ( "ingrese el puerto de conexion\n" ); scanf ( "%d" ,&puerto); while (ciclo){ sockfd = socket(AF_INET, SOCK_STREAM,0); //llenado de la estructura de datos address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr(ipserver); address.sin_port = puerto; len = sizeof (address); //conectar con el server result = connect(sockfd, ( struct sockaddr *)&address, len); if (result ==-1){ perror ( "ERROR EN LA CONEXION\n" ); close(sockfd); } //validar el inicio de sesion if (inicio==0){ printf ( "--------------- SESION INICIADA --------------\n" ); recv(sockfd, ch, 1024,0); printf ( "%s\n" ,ch); inicio = 1; } printf ( "ingrese una cadena para enviar al server: " ); scanf ( "%*c%[^\n]" ,c); send(sockfd,c, 1024,0); recv(sockfd, ch, 1024,0); printf ( "El servidor dijo: %s\n" ,ch); } close(sockfd); } |