Autor
|
Tema: ¿Cómo funciona select() en c? (Leído 5,159 veces)
|
mester
Desconectado
Mensajes: 219
https://www.youtube.com/watch?v=IlY9C6pzxKc
|
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. #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> #include<fcntl.h> #include<arpa/inet.h> #define PUERTO 3317 //PROBLEMA: //Cuando se va un host deja un espacio libre que hay que rellenar void usage(char *arg){ } int main(int argc, char **argv){ pid_t id; fd_set desc; int c,l,j; int host=0; int clilong; int socket_servidor; int socket_cliente[25]; char *buffer =calloc(220,sizeof(char)); struct sockaddr_in servidor; struct sockaddr_in cliente[25]; socket_servidor=socket(AF_INET,SOCK_STREAM,0); servidor.sin_family = AF_INET; if(argc>1){ servidor.sin_port = htons(port); } else servidor.sin_port = htons(PUERTO); servidor.sin_addr.s_addr = INADDR_ANY; if(bind(socket_servidor,(struct sockaddr *)&servidor,sizeof(servidor))<0){ printf("El puerto %d está en uso\n",PUERTO ); usage(argv[0]); close(socket_servidor); return 1; } listen(socket_servidor,25); printf("Escuchando por el puerto %d\n",ntohs (servidor. sin_port)); clilong=sizeof(cliente[host]); socket_cliente[host]=accept(socket_servidor,(struct sockaddr *)&cliente[host],&clilong); if(socket_cliente[host]<0){ printf("Error aceptando el trafico con el host %s\n", inet_ntoa(cliente[host].sin_addr)); close(socket_cliente[host]); close(socket_servidor); return 1; } else printf("Conectado con el host %s\n",inet_ntoa (cliente [host ]. sin_addr)); host++; FD_ZERO(&desc); FD_SET(socket_servidor,&desc); for(c=0;c<host;c++) FD_SET(socket_cliente[c],&desc); while(1){ if(select(host+4,&desc,NULL,NULL,NULL)<0){ close(socket_cliente[host]); close(socket_servidor); return 1; } for(c=0;c<host;c++){ if(FD_ISSET(socket_servidor,&desc)){ clilong=sizeof(cliente[host]); socket_cliente[host]=accept(socket_servidor, (struct sockaddr *)&cliente[host],&clilong); if(socket_cliente[host]>0){ printf("Se ha conectado el host %s\n", inet_ntoa(cliente[host].sin_addr)); host++; } else printf("Error al conectarse nuevo host\n"); } if(FD_ISSET(socket_cliente[c],&desc)){ j=recv(socket_cliente[c],buffer,220,0); if(j>0){ for(l=0;l<=host;l++) send(l,buffer,220,0); } if(j==0){ printf("El host %s se ha desconectado\n", inet_ntoa(cliente[c].sin_addr)); close(socket_cliente[c]); host--; } } } } return 0; }
|
|
« Ú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
Mensajes: 3.412
ASMático
|
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
Mensajes: 219
https://www.youtube.com/watch?v=IlY9C6pzxKc
|
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
Mensajes: 157
|
Hola, Te comento un poco a grandes rasgos lo que he visto: tienes esta parte repetida encima del while y dentro: socket_cliente[host]=accept(socket_servidor,(struct sockaddr *)&cliente[host],&clilong); if(socket_cliente[host]<0){ printf("Error aceptando el trafico con el host %s\n", inet_ntoa(cliente[host].sin_addr)); close(socket_cliente[host]); close(socket_servidor); return 1; } else printf("Conectado con el host %s\n",inet_ntoa (cliente [host ]. sin_addr)); host++; FD_ZERO(&desc); FD_SET(socket_servidor,&desc); for(c=0;c<host;c++) FD_SET(socket_cliente[c],&desc);
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.
|
|
|
En línea
|
|
|
|
mester
Desconectado
Mensajes: 219
https://www.youtube.com/watch?v=IlY9C6pzxKc
|
Hola, Te comento un poco a grandes rasgos lo que he visto: tienes esta parte repetida encima del while y dentro: socket_cliente[host]=accept(socket_servidor,(struct sockaddr *)&cliente[host],&clilong); if(socket_cliente[host]<0){ printf("Error aceptando el trafico con el host %s\n", inet_ntoa(cliente[host].sin_addr)); close(socket_cliente[host]); close(socket_servidor); return 1; } else printf("Conectado con el host %s\n",inet_ntoa (cliente [host ]. sin_addr)); host++; FD_ZERO(&desc); FD_SET(socket_servidor,&desc); for(c=0;c<host;c++) FD_SET(socket_cliente[c],&desc);
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. -Al principio la función la utilizo para que se conecte el primer cliente. -Sí que incremento hosts: if(FD_ISSET(socket_servidor,&desc)){ clilong=sizeof(cliente[host]); socket_cliente[host]=accept(socket_servidor, (struct sockaddr *)&cliente[host],&clilong); if(socket_cliente[host]>0){ printf("Se ha conectado el host %s\n", inet_ntoa(cliente[host].sin_addr)); host++; } else printf("Error al conectarse nuevo host\n"); }
host++;
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
|
|
|
|
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
|
23 Agosto 2011, 07:17 am
por Rudy21
|
|
|
como crear tabla dinamica con un select dinamico php
PHP
|
include ();
|
3
|
11,847
|
21 Septiembre 2012, 03:05 am
por include ();
|
|
|
Como hacer un select de un update? (MSSQL)
Bases de Datos
|
WHK
|
7
|
6,758
|
25 Julio 2013, 15:54 pm
por Novlucker
|
|
|
-moz-user-select none no funciona
« 1 2 3 »
Desarrollo Web
|
gAb1
|
20
|
8,237
|
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
|
29 Junio 2015, 17:15 pm
por WHK
|
|