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

 

 


Tema destacado: Curso de javascript por TickTack


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ¿Cómo funciona select() en c?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Cómo funciona select() en c?  (Leído 5,159 veces)
mester

Desconectado Desconectado

Mensajes: 219


https://www.youtube.com/watch?v=IlY9C6pzxKc


Ver Perfil WWW
¿Cómo funciona select() en c?
« en: 22 Noviembre 2015, 18:30 pm »

Hola.
Estoy utilizando la función select() para hacer un servidor de chat pero, no sé que problemas tengo jeje. Espero vuestra ayuda.
Ignorad que el código no esté dividido en funciones.
No quiero que me terminéis el programa, solo quiero que me digais, qué problemas tiene. Compilar compila, pero cuando se conectan dos hosts, el segundo no envía mensajes, o cuando se conecta éste, no sucede lo que debe suceder.
Gracias.
Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<sys/types.h>
  5. #include<sys/socket.h>
  6. #include<netinet/in.h>
  7. #include<netdb.h>
  8. #include<fcntl.h>
  9. #include<arpa/inet.h>
  10. #define PUERTO 3317
  11. //PROBLEMA:
  12. //Cuando se va un host deja un espacio libre que hay que rellenar
  13. void usage(char *arg){
  14. printf("%s <puerto>\n",arg);
  15. }
  16. int main(int argc, char **argv){
  17. pid_t id;
  18. fd_set desc;
  19. int c,l,j;
  20. int host=0;
  21. int clilong;
  22. int socket_servidor;
  23. int socket_cliente[25];
  24. char *buffer=calloc(220,sizeof(char));
  25. struct sockaddr_in servidor;
  26. struct sockaddr_in cliente[25];
  27. socket_servidor=socket(AF_INET,SOCK_STREAM,0);
  28. servidor.sin_family = AF_INET;
  29. if(argc>1){
  30. int port=atoi(argv[1]);
  31. servidor.sin_port = htons(port);
  32. }
  33. else
  34. servidor.sin_port = htons(PUERTO);
  35. servidor.sin_addr.s_addr = INADDR_ANY;
  36. if(bind(socket_servidor,(struct sockaddr *)&servidor,sizeof(servidor))<0){
  37. printf("El puerto %d está en uso\n",PUERTO);
  38. usage(argv[0]);
  39. close(socket_servidor);
  40. return 1;
  41. }
  42. listen(socket_servidor,25);
  43. printf("Escuchando por el puerto %d\n",ntohs(servidor.sin_port));
  44. clilong=sizeof(cliente[host]);
  45. socket_cliente[host]=accept(socket_servidor,(struct sockaddr *)&cliente[host],&clilong);
  46. if(socket_cliente[host]<0){
  47. printf("Error aceptando el trafico con el host %s\n",
  48. inet_ntoa(cliente[host].sin_addr));
  49. close(socket_cliente[host]);
  50. close(socket_servidor);
  51. return 1;
  52. }
  53. else
  54. printf("Conectado con el host %s\n",inet_ntoa(cliente[host].sin_addr));
  55. host++;
  56. FD_ZERO(&desc);
  57. FD_SET(socket_servidor,&desc);
  58. for(c=0;c<host;c++)
  59. FD_SET(socket_cliente[c],&desc);
  60. while(1){
  61. if(select(host+4,&desc,NULL,NULL,NULL)<0){
  62. printf("Error\n");
  63. close(socket_cliente[host]);
  64. close(socket_servidor);
  65. return 1;
  66. }
  67. for(c=0;c<host;c++){
  68. printf("C: %d\n",c);
  69. if(FD_ISSET(socket_servidor,&desc)){
  70.                                clilong=sizeof(cliente[host]);
  71.                                socket_cliente[host]=accept(socket_servidor,
  72.                                                        (struct sockaddr *)&cliente[host],&clilong);
  73.                                if(socket_cliente[host]>0){
  74.                                        printf("Se ha conectado el host %s\n",
  75.                                                                inet_ntoa(cliente[host].sin_addr));
  76.                                        host++;
  77.                                        printf("Hosts %d\n",host);
  78.                                }
  79.                                else
  80.                                        printf("Error al conectarse nuevo host\n");
  81. }
  82.                        if(FD_ISSET(socket_cliente[c],&desc)){
  83. printf("Esperando algo\n");
  84. j=recv(socket_cliente[c],buffer,220,0);
  85. if(j>0){
  86. printf("\n%s\n",buffer);
  87. for(l=0;l<=host;l++)
  88. send(l,buffer,220,0);
  89. }
  90. if(j==0){
  91. printf("El host %s se ha desconectado\n",
  92. inet_ntoa(cliente[c].sin_addr));
  93. close(socket_cliente[c]);
  94. host--;
  95. printf("Hosts: %d\n",host);
  96. }
  97. }
  98. }
  99. }
  100. free(buffer);
  101. return 0;
  102. }
  103.  


« Última modificación: 22 Noviembre 2015, 18:32 pm por nonpromisc » En línea

Justicia es dar a cada uno lo que se merece
ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: ¿Cómo funciona select() en c?
« Respuesta #1 en: 22 Noviembre 2015, 18:37 pm »

Si no sabes qué problemas tienes, ¿cómo sabes que tienes problemas?

Di qué error tienes, qué no ocurre correctamente, o qué no sabes implementar.


En línea

mester

Desconectado Desconectado

Mensajes: 219


https://www.youtube.com/watch?v=IlY9C6pzxKc


Ver Perfil WWW
Re: ¿Cómo funciona select() en c?
« Respuesta #2 en: 22 Noviembre 2015, 18:45 pm »

Si no sabes qué problemas tienes, ¿cómo sabes que tienes problemas?

Di qué error tienes, qué no ocurre correctamente, o qué no sabes implementar.
Vale.
Principalmente, cuando ejecuto el programa y conecto un cliente, bien, el cliente envia paquetes y el servidor recibe e imprime. Pero cuando conecto un segundo cliente:
1-No me sale que se haya conectado.
2-No incrementa la variable host
3-No envía nada al servidor. (Enviar envía, pero el servidor no lo imprime)
Y si conecto los dos clientes a la vez despues de haber iniciado el servidor, es decir, conecto uno, sin enviar nada, y luego otro, se queda esperando una segunda conexión, y no recibe ni envía.

Es decir, que es o un if u otro. No quiero usar ni threads ni forks, he probado con sockets no bloqueantes, pero no son la solución.
Gracias
En línea

Justicia es dar a cada uno lo que se merece
kondrag_X1

Desconectado Desconectado

Mensajes: 157


Ver Perfil
Re: ¿Cómo funciona select() en c?
« Respuesta #3 en: 22 Noviembre 2015, 19:59 pm »

Hola,

Te comento un poco a grandes rasgos lo que he visto:

tienes esta parte repetida encima del while y dentro:

Código
  1. socket_cliente[host]=accept(socket_servidor,(struct sockaddr *)&cliente[host],&clilong);
  2. if(socket_cliente[host]<0){
  3. printf("Error aceptando el trafico con el host %s\n",
  4. inet_ntoa(cliente[host].sin_addr));
  5. close(socket_cliente[host]);
  6. close(socket_servidor);
  7. return 1;
  8. }
  9. else
  10. printf("Conectado con el host %s\n",inet_ntoa(cliente[host].sin_addr));
  11. host++;
  12. FD_ZERO(&desc);
  13. FD_SET(socket_servidor,&desc);
  14. for(c=0;c<host;c++)
  15. FD_SET(socket_cliente[c],&desc);
  16.  

lo primero que yo te aconsejaría es que si escribes un if{} el else que también tengo las llaves {} así evitaras confusiones.

la segunda cosa que veo rara es que solo incrementas el número de host cuando aceptas la primera conexión, es decir, dentro del while aceptas pero no incrementas el contador de host o yo no he visto donde esta el host++; como en el fragmento de arriba.

Si yo fuese tu interaria aceptar las conexiones dentro del while te simplificará mucho la tarea.

espero haberte ayudado. :silbar:
En línea

mester

Desconectado Desconectado

Mensajes: 219


https://www.youtube.com/watch?v=IlY9C6pzxKc


Ver Perfil WWW
Re: ¿Cómo funciona select() en c?
« Respuesta #4 en: 22 Noviembre 2015, 22:11 pm »

Hola,

Te comento un poco a grandes rasgos lo que he visto:

tienes esta parte repetida encima del while y dentro:

Código
  1. socket_cliente[host]=accept(socket_servidor,(struct sockaddr *)&cliente[host],&clilong);
  2. if(socket_cliente[host]<0){
  3. printf("Error aceptando el trafico con el host %s\n",
  4. inet_ntoa(cliente[host].sin_addr));
  5. close(socket_cliente[host]);
  6. close(socket_servidor);
  7. return 1;
  8. }
  9. else
  10. printf("Conectado con el host %s\n",inet_ntoa(cliente[host].sin_addr));
  11. host++;
  12. FD_ZERO(&desc);
  13. FD_SET(socket_servidor,&desc);
  14. for(c=0;c<host;c++)
  15. FD_SET(socket_cliente[c],&desc);
  16.  

lo primero que yo te aconsejaría es que si escribes un if{} el else que también tengo las llaves {} así evitaras confusiones.

la segunda cosa que veo rara es que solo incrementas el número de host cuando aceptas la primera conexión, es decir, dentro del while aceptas pero no incrementas el contador de host o yo no he visto donde esta el host++; como en el fragmento de arriba.

Si yo fuese tu interaria aceptar las conexiones dentro del while te simplificará mucho la tarea.

espero haberte ayudado. :silbar:
-Al principio la función la utilizo para que se conecte el primer cliente.
-Sí que incremento hosts:
Código
  1. if(FD_ISSET(socket_servidor,&desc)){
  2.                                clilong=sizeof(cliente[host]);
  3.                                socket_cliente[host]=accept(socket_servidor,
  4.                                                        (struct sockaddr *)&cliente[host],&clilong);
  5.                                if(socket_cliente[host]>0){
  6.                                        printf("Se ha conectado el host %s\n",
  7.                                                                inet_ntoa(cliente[host].sin_addr));
  8.                                        host++;
  9.                                        printf("Hosts %d\n",host);
  10.                                }
  11.                                else
  12.                                        printf("Error al conectarse nuevo host\n");
  13. }
  14.  
Código
  1.                                        host++;
  2.                                        printf("Hosts %d\n",host);
  3.  
Y bueno, sí que podré la funcion de aceptar solo en el while
En línea

Justicia es dar a cada uno lo que se merece
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
vb net SELECT de Acces no funciona
.NET (C#, VB.NET, ASP)
Rudy21 4 4,548 Último mensaje 23 Agosto 2011, 07:17 am
por Rudy21
como crear tabla dinamica con un select dinamico php
PHP
include (); 3 11,847 Último mensaje 21 Septiembre 2012, 03:05 am
por include ();
Como hacer un select de un update? (MSSQL)
Bases de Datos
WHK 7 6,758 Último mensaje 25 Julio 2013, 15:54 pm
por Novlucker
-moz-user-select none no funciona « 1 2 3 »
Desarrollo Web
gAb1 20 8,237 Último mensaje 12 Mayo 2014, 10:54 am
por rubetron
Usar entrada de función como columna en select
Bases de Datos
user-marcos 3 3,291 Último mensaje 29 Junio 2015, 17:15 pm
por WHK
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines