elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  duda socket
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: duda socket  (Leído 2,096 veces)
Maik33

Desconectado Desconectado

Mensajes: 128


Ver Perfil
duda socket
« en: 15 Enero 2012, 16:23 pm »

Hola, tengo una duda de como hacer un "mini chat" en C para linux.

Se manejar los sockets, como hacer para que cliente y servidor se manden mensajes entre ellos.
Pero, lo que yo quiero hacer es que en el servidor se conecten varios clientes, y que los clientes se manden mensajes entre ellos.

Para hacer esto se puede hacer que los clientes se conecten al mismo puerto?
Cada vez que se conecte un cliente habría que hacer un proceso/hilo para atenderle?
Gracias.


En línea

Maik33

Desconectado Desconectado

Mensajes: 128


Ver Perfil
Re: duda socket
« Respuesta #1 en: 16 Enero 2012, 12:51 pm »

Hola, siento auto-responderme, pero ya he conseguido hacer un servidor que acepte n clientes. Os dejo el codigo:
Codigo del servidor:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <sys/wait.h>
  9. #include <arpa/inet.h>
  10. #define MYPORT 3490    /*Numero de puerto donde se conectaran los clientes*/
  11. #define BACKLOG 10     /* Tamaño de la cola de conexiones recibidas */
  12. #define MAX 150
  13.  
  14. main(){
  15.  int sockfd;                 /* El servidor escuchara por sockfd */
  16.  int newfd;                    /*  las transferencias de datos se realizar mediante newfd */
  17.  struct sockaddr_in my_addr;                       /* contendra la direccion IP y el numero de puerto local */
  18.  struct sockaddr_in their_addr;                     /* Contendra la direccion IP y numero de puerto del cliente */
  19.  int sin_size;                                                         /* Contendra el tamanio de la escructura sockaddr_in */
  20.  char texto[MAX];
  21.  int nbytes;
  22.  
  23.  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) /*Crea un socket y verifica si hubo algun error*/
  24.  {
  25.    perror("socket");
  26.    exit(1);
  27.  }
  28.  /* Asignamos valores a la estructura my_addr para luego poder llamar a la funcion bind() */
  29.  my_addr.sin_family = AF_INET; /*no debe convertirse a  network byte order, es solo utilizado por el kernel*/
  30.  my_addr.sin_port = htons(MYPORT); /*debe convertirse a network byte order porque es enviado por la red*/
  31.  my_addr.sin_addr.s_addr = INADDR_ANY;    /* automaticamente usa la IP local */
  32.  bzero(&(my_addr.sin_zero), 8);        /* rellena con ceros el resto de la estructura */
  33.  /* Le asignamos un nombre al socket */
  34.  if ( bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1){
  35.    perror("bind");
  36.    exit(1);
  37.  }
  38.  /* Habilitamos el socket para recibir conexiones, con una cola de 5 conexiones en espera como maximo */
  39.  if (listen(sockfd, BACKLOG) == -1){
  40.    perror("listen");
  41.    exit(1);
  42.  }
  43.  
  44.  while(1)                          /* loop que llama a accept() */
  45.  {
  46.    sin_size = sizeof(struct sockaddr_in);
  47.    /*Se espera por conexiones ,*/
  48.    if ((newfd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1){
  49.      perror("accept");
  50.      continue;                /* Si se produce un error se finaliza el programa */
  51.    }
  52.    printf("server:  conexion desde:  %s\n", inet_ntoa(their_addr.sin_addr));
  53.    /* Llamamos a fork() para crear un proceso hijo que atendera a la conexion recien establecida
  54.     El proceso hijo sera igual que el padre, hereda los descriptores de sockets, lo unico que los diferencia
  55.     es el valor devuelto por fork(), al padre le devuelve el PID del hijo , y al hijo le devuelve un
  56.     valor cero .  Por eso, para saber si estamos en el proceso padre o hijo, comparamos el valor
  57.     devuelto por fork().  Si fork devuelve cero, entonces estamos en el proceso hijo.  Ver la pagina
  58.     del manual de fork. */
  59.     if (!fork()){
  60.       /* Aca comienza el proceso hijo, enviamos los datos mediante newfd */
  61.       if(send(newfd,"Bienvenido al servidor\n",23,0)==-1)
  62. perror("send");
  63.       if((nbytes=recv(newfd,texto,MAX,0))==-1){
  64. perror("recv");
  65. exit(-1);
  66.       }
  67.       texto[nbytes]='\0';
  68.       while(strcmp(texto,"salir\0")!=0){
  69. printf("%s:%s\n",inet_ntoa(their_addr.sin_addr),texto);
  70. if((nbytes=recv(newfd,texto,MAX,0))==-1){
  71.   perror("recv");
  72.   exit(-1);
  73. }
  74. texto[nbytes]='\0';
  75.       }
  76.       close(newfd);
  77.       printf("Desconexion\n");
  78.       exit(0);
  79.     }
  80.    /* El proceso padre no necesita este descriptor, solo lo utiliza el proceso hijo, en la proxima llamada a
  81.     accept(), retornara con un nuevo descriptor de socket */
  82.    close(newfd);
  83.    /* Se suspende la ejecucion del proceso padre hasta que finalice el proceso hijo */
  84.    while(waitpid(-1,NULL,WNOHANG) > 0);
  85.    /* Una vez finalizado el proceso hijo, se vuelve a llamar a accept() */
  86.  }
  87. }

Codigo cliente(s):
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <netdb.h>
  6. #include <sys/types.h>
  7. #include <netinet/in.h>
  8. #include <sys/socket.h>
  9. #define PORT 3490                            /* El puerto donde se conectara */
  10. #define MAXDATASIZE 150     /* maxima cant. De bytes que se pueden recibir en una llamada a recv */
  11.  
  12. int main(int argc, char *argv[]){
  13.  int sockfd, numbytes;                /* Contendra el numero de bytes recibidos despues de llamar a recv() */
  14.  char buf[MAXDATASIZE];            /* Buffer donde se reciben los datos */
  15.  struct hostent *he;                               /* Se utiliza para convertir el nombre del host a su direccion IP */
  16.  struct sockaddr_in their_addr;         /* direccion del server donde se conectara */
  17.  /* Tratamiento de la linea de comandos. */
  18.  if (argc != 2){
  19.    fprintf(stderr,"usage: client hostname\n");
  20.    exit(1);
  21.  }
  22.  /* Convertimos el nombre del host a su direccion IP */
  23.  if ((he=gethostbyname(argv[1])) == NULL){
  24.    error("gethostbyname");
  25.    exit(1);
  26.  }
  27.  /* Creamos el socket */
  28.  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
  29.    perror("socket");
  30.    exit(1);
  31.  }
  32.  /* Establecemos their_addr con la direccion del server */
  33.  their_addr.sin_family = AF_INET;
  34.  their_addr.sin_port = htons(PORT);
  35.  their_addr.sin_addr = *((struct in_addr *)he->h_addr);
  36.  bzero(&(their_addr.sin_zero), 8);
  37.  /* Intentamos conectarnos con el servidor */
  38.  if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1){
  39.    perror("connect");
  40.    exit(1);
  41.  }
  42.  /* Recibimos los datos del servidor */
  43.  if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1){
  44.    perror("recv");
  45.    exit(1);
  46.  }
  47.  /* Visualizamos lo recibido */
  48.  buf[numbytes] = '\0';
  49.  printf("Recivido: %s\n",buf);
  50.  /* Devolvemos recursos al sistema */
  51.  do{
  52.    printf("> ");
  53.    scanf("%[^\n]",buf);
  54.    getchar();
  55.    if(send(sockfd,buf,strlen(buf),0)==-1){
  56.      printf("Error\n");
  57.      perror("send");
  58.    }
  59.  }while(strcmp(buf,"salir\0")!=0);
  60.  close(sockfd);
  61.  return 0;
  62. }

De momento lo unico que hacen los clientes mandar mensajes al servidor y el servidor imprime en pantalla en mensaje de cada uno. Ahora mi duda es la siguiente:
cuando llegue un nuevo mensaje al servidor este mande ese mensaje a todos los conectados al servidor. Como puedo saber quienes estan conectados al servidor?
Gracias


En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda socket c++
Programación C/C++
isma3l 0 1,565 Último mensaje 29 Abril 2012, 02:04 am
por isma3l
Duda al obtener datos por socket en adaptador RS-232/RJ-45
.NET (C#, VB.NET, ASP)
gualcot 0 1,414 Último mensaje 13 Agosto 2012, 19:12 pm
por gualcot
[Duda] Cifrar Socket
Análisis y Diseño de Malware
xv0 9 5,024 Último mensaje 8 Diciembre 2012, 09:08 am
por xv0
[Duda] ¿Inyectar información en un socket ya abierto?
.NET (C#, VB.NET, ASP)
Shout 4 2,278 Último mensaje 9 Julio 2013, 19:44 pm
por Shout
Duda conceptual acerca de los Socket's
Java
Xedrox 3 1,419 Último mensaje 23 Junio 2014, 19:01 pm
por engel lex
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines