Problema con aplicacion Cliente-Servidor

Started by Phoenix, January 18, 2010, 06:52:18 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Phoenix

Buenas!

Estoy probando la biblioteca fsock para la realizacion de una autenticacion de los clientes dentro de la base de datos de un servidor.

El codigo que tengo es el siguiente:

[code language="bennu"]

Servidor

 Main Process...

 fsock_init(64); //Iniciamos fsock
 socket_listen=tcpsock_open();
 fsock_bind(socket_listen,1322);
 tcpsock_listen(socket_listen,60);

 fsock_fdzero(0); //Socketset 0 para la conexion al servidor
 fsock_fdset(0,socket_listen);

 //Esperamos conexiones
 Repeat
   if (fsock_select(0,-1,-1,0)>0) //Si hay actividad en el socketset
      say("conexion recibida");
      sock_cliente=tcpsock_accept(socket_listen,&ipaddr,&portaddr);
      if((sock_cliente!=-1)) //Si recibimos una conexion de entrada de usuario
          //Ejecuto el proceso que respondera a este cliente
            n_conectados++;
            Client_Login(sock_cliente,n_conectados);
       end
    end
    fsock_fdset (0, socket_listen); //hay que reincluir tras uso de select
    frame;
 until(key(_esc));

 Process Login(sock_cliente,Mysocketset)
       
       tcpsock_recv(sock_cliente,&Nombre,sizeof(Nombre));

       //... Compruebo que el nombre esta en la base de datos y le contesto
       Login_ok=Login_BuscaBD(Nombre);

   //... Mando respuesta de si el login es correcto.. es decir si el nombre esta en la BD
   tcpsock_send(sock_cliente,&Login_ok,sizeof(Login_ok));

   if(login_ok==1) //Correcto

     //... Este proceso esperara a otras peticiones de este cliente
          fsock_socketset_free(Mysocketset);
          fsock_socketset_add(Mysocketset,sock_cliente );

          loop
           if((fsock_select(Mysocketset,-1,-1,0)>0) && fsock_fdisset(Mysocketset,sock_cliente))
                tcpsock_recv(sock_cliente,&accion,sizeof(accion));
                if(accion==1)
                  say("Hola usuario!! Elegiste la opcion 1");
                  accion=0;
                end
                if(accion==2) // desconexion
                   say("Jugador desconectado");
                   accion=0;
                   break;
                end
             fsock_fdset(Mysocketset,sock_cliente);
           end
           frame;
          end
        end
    if(login_ok==2) //Incorrecto
              //Cierro conexion con el usuario
        end
 end

[/code]

[code language="bennu"]

Cliente

  Main Process

  fsock_socketset_free(0);
  fsock_socketset_add(0,socket_conex);

  if((tcpsock_connect(socket_conex,"xxx.xxx.xxx.xxx",1322))==0) //xxx... Ip Servidor xD
       //Mando nombre
       tcpsock_send(socket_conex,&Nombre,sizeof(Nombre));
       //Espero confirmacion de que mi login fue correcto
   tcpsock_recv(sock_cliente,&login_ok,sizeof(login_ok));
   if(login_ok==1)
          say("Identificacion correcta");
          Repeat
              if(key(_enter))
                 say("Mandando saludo");
             accion=1;
                 tcpsock_send(socket_conex,&accion,sizeof(accion));
          end
          until(key(_esc))
          //Cerrar conexion
       end
   if(Login_ok==2)
      say("error conexion, login failed");
   end
   end

[/code]

Despues de esto... xD, el server me responde correctamente dependiendo de si el nombre esta dentro de una base de datos que contiene el servidor... El problema viene.. en que... la parte de codigo del proceso "Login" del servidor, que espera a que un usuario ya conectado le mande nuevas peticiones, no parece responderlas con lo que tanto server como cliente se quedan bloqueados. Alguien sabe si estoy haciendo mal la espera de peticiones de los clientes logeados en el servidor? o como habria que hacerlo?

Muchas gracias.

Windgate

Ojo con los FRAME, ten en cuenta que si un bucle no hace FRAME bloquea, también ten en cuenta que el FPS puede variar del cliente al servidor y no es bueno asumir que por cada iteración del cliente el servidor hace otra... Tuve varios problemas así con la network de Sandman y por ahora he paralizado mi "investigación", te sigo el corriente a ver si consigues algo más palpable que lo que yo conseguí...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Phoenix

El servidor se comporta perfectamente al aceptar nuevas conexiones y
en cada una de ellas realiza la comprobacion de si ese nombre de
usuario pertenece a la base de datos.

Pff no se tio, el unico gran problema esta en poder responder a un cliente
ya logueado. estoy 100% seguro que el problema viene a que no estoy
usando bien lo de los socketsets y que ademas no uso las funciones correctamente
para saber cuando se hace una accion desde el cliente.

[code language="bennu"]
if((fsock_select(Mysocketset,-1,-1,0)>0) && fsock_fdisset(Mysocketset,sock_cliente))[/code]

A esta parte me refiero xD, mañana lo mirare haber si saco algo con la mente
algo mas freskita.

Windgate

Yo usé la otra librería que es de más alto nivel, tendría que mirar lo que hacían esas funciones de la fsock porque las probé hace muchísimo y ni me acuerdo ya, por ahora no puedo decirte mucho... Sólo que el tema de conexiones de red es una cuenta pendiente para muchos de nosotros y haría falta algún ejemplo/plantilla. Por ahí circulaba uno de chat (Para mi librería) y me sirvió de algo, pero no tenía nada que ver con lo que yo prentedía, que era un juego, y ahí me encontré glitches y problemas para que server y cliente vayan al mismo fps y/o al menos puedan bloquearse hasta recibir respuesta :P

Mañana ambos más frescos seguimos con el asunto, ok!
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

yo estoy seguro que hay ejemplos funcionales en el foro
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Phoenix

Bueno posteo el codigo completo de la aplicacion... he logrado que si solo conecto un cliente, podemos comunicarnos con el servidor una vez conectados a el, incluso si el cliente se desconecta manda un mensaje de desconexion para que el server cierre ese proceso con el cliente. Ahora... todo va mal cuando conecto 2 clientes al servidor y mando un mensaje de saludo al server con cualquiera de los 2 clientes... se queda bloqueado tanto cliente como servidor. Sigo pensando lo mismo de los socketsets.

En el codigo empleo una variable "ok" para sincronizar el servidor con el cliente, cuando se vayan a mandar datos de uno a otro. El cliente al conectarse manda un array de chars(Nombre de usuario) y el server le respondera consultando en la BD si fue correcto.

Por otra parte no encontre ningun ejemplo que funcione con el fsock y ademas emplee sockets/TCP para las conexiones.

Uso Bennu 0.93, que es la unica que encontre en la que funcionaran los modulos sqlite3 y fsock a la vez xD, que lo incluyo en el rar para no tener que buscarlo.

Enlace:

http://www.mediafire.com/?eyiywyncdei


Windgate

Descargando.

Sí que hay ejemplos por ahí, pero yo buscaba algo muy sencillo, como por ejemplo el típico pong con los 2 palitos y la bolita para hacer un juego para 2 jugadores, algo con el mínimo número de líneas y comentado, ya sé que es mucho pedir :D Para la librería de Sandman estaba el chat, pero me pareció demasiado complicado y alejado de lo que buscaba, así que tiré directamente de la documentación, que también tiene algún breve ejemplo de uso y me sirvió para empezar.

Yo comencé con un juego sencillito, pero aparecieron algunos glitches con la librería de Sandman y paralicé el proyecto, algún día que lo desempolve y lo deje un poco estable lo subo como recurso, conseguí 2 jugadores en PCs diferentes moviéndose en pantalla sin problemas, pero con el tercer cliente y siguientes comenzaron los problemas de glitches, bloqueos, paquetes perdidos... Quizás un mal protocolo, quizás un mal programador... También detectamos algún pequeño bug en la librería y aunque se arregló alguna cosa también quedaron ideas pendientes de incluir.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Drumpi

Una preguntita ¿la espera de respuesta es una función bloqueante? es decir, ¿se queda ahi hasta que obtiene algún tipo de respuesta?
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Phoenix

Quote from: Drumpi on January 19, 2010, 02:20:08 PM
Una preguntita ¿la espera de respuesta es una función bloqueante? es decir, ¿se queda ahi hasta que obtiene algún tipo de respuesta?

Yo lo tengo configurado como bloqueante, pero puedes definir el socket como no bloqueante si es necesario.

[code language="bennu"]int fsock_setblock(int socket, int nobloqueante);
Ej.- fsock_setblock(socket_listen,1);[/code]


l1nk3rn3l

en el bennupack hay un monton de ejemplos para red
ve al paquete de DLLs..

;D

Windgate

k++ l1nk, tengo por ahí los paquetes de ejemplos pero francamente nunca he husmeado a fondo el de dlls fíjate tú...

Por cierto, te lo he dicho decenas de veces, ¿Por qué no metiste la dll de Bennu3D en el Bennupack 1.8?, lo he instalado en decenas de lugares y siempre tengo que meterlo a mano :( tenlo en cuenta para la 1.9 xfa xfa xfa xD

Bien, y sobre los sockets, si manejas todos los clientes en local... No me queda muy claro si serán capaces o no de diferenciar a quién de los clientes va dirigido cada paquete del server... No soy ningún experto en sockets que conste :P
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Phoenix

Quote from: l1nk3rn3l on January 19, 2010, 09:12:59 PM
en el bennupack hay un monton de ejemplos para red
ve al paquete de DLLs..

;D

Ok gracias! ahora le echare un vistazo.

Estoy probando usando conexiones udp, parace que la cosa es algo mas estable, al menos, eso me parece por ahora xD.

@Windgate, luego probare a ejecutar 2 clientes en maquinas con distinta ip y ver que pasa.

SplinterGU

junto con la ultima version compile la fsock... esta en el directorio contrib... el binario facilmente identificable...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Phoenix

Quote from: SplinterGU on January 20, 2010, 04:32:47 PM
junto con la ultima version compile la fsock... esta en el directorio contrib... el binario facilmente identificable...

Mola, muchas gracias!

Ahora mismo cambie a usar la libnetwork.dll de Sandman, de momento.. funciona perfecto.. atiende la conexion de nuevos clientes y ademas contesta las distintas acciones de los clientes ya conectados. Luego seguire, a ver si todo va tan bien como hasta ahora xD.


Windgate

¿Todo bien con la librería de Sandman? Interesante, quizás vaya siendo hora de desenterrar mi proyecto y enseñaros los problemas que tenía, como os digo al final me quedé sin saber si el error se debía al protocolo que estaba usando... Por supuesto eran muy pocas líneas de código, soy un trolazo y siempre intento tener procesos/funciones que caben en pantalla :P
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es