Buenas chicos,
resulta que he montado el siguiente tinglado:
Aplicación en Bennu (cliente)
Aplicación en PHP (servidor)
1- La idea es que la aplicación cliente envía los datos de usuario y contraseña.
2- La aplicación servidor se encarga de revisar los datos recibidos en una base de datos de MySQL.
3- La aplicación servidor envía "ok" o "nok" como respuesta.
La aplicación cliente envía un "codigo de control" que es un entero, y este es recibido correctamente en el servidor PHP. Hasta aquí todo correcto.
Posteriormente envío una string con el usuario introducido y aquí es donde viene el problema:
Todas las veces que he probado, el resultado ha sido siempre el mismo, si envío una letra solo como nombre de usuario, independientemente de la letra que envío esta se interpreta desde el servidor como una "c". Si envío dos letras, independientemente de cuales sean, en el servidor se muestra "f".
Me da la impresión de que en vez de enviar la "srting" estoy enviando la posición de la memoria. ¿Puede ser esto así?
El código es el siguiente:
NET_LOGIN = 500;
net_codigo = NET_LOGIN;
tcpsock_send(socket,&net_codigo, sizeof(net_codigo));
tcpsock_send(socket,&t_usuario, len(t_usuario));
También he probado lo siguiente con identico resultado:
NET_LOGIN = 500;
net_codigo = NET_LOGIN;
tcpsock_send(socket,&net_codigo, sizeof(net_codigo));
tcpsock_send(socket,&t_usuario, sizeof(t_usuario));
¿¿¿Se os ocurre como puedo enviar datos de una string mediante el socket???
Más pruebas:
NET_LOGIN = 500;
net_codigo = NET_LOGIN;
tcpsock_send(socket,&net_codigo, sizeof(net_codigo));
tcpsock_send(socket,&t_usuario, (len(t_usuario)*8));
NET_LOGIN = 500;
net_codigo = NET_LOGIN;
tcpsock_send(socket,&net_codigo, sizeof(net_codigo));
tcpsock_send(socket,&t_usuario, (len(t_usuario)*32));
NET_LOGIN = 500;
net_codigo = NET_LOGIN;
tcpsock_send(socket,&net_codigo, sizeof(net_codigo));
tcpsock_send(socket,&t_usuario, (len(t_usuario)*256));
Estos tres últimos códigos envían una serie de caracteres extraños al servidor, pero de mi "string" ni rastro...
por último y ya se me acaban las ideas:
NET_LOGIN = 500;
net_codigo = NET_LOGIN;
tcpsock_send(socket,&net_codigo, sizeof(net_codigo));
tcpsock_send(socket,&t_usuario, (len(t_usuario) * sizeof(t_usuario)));
Idem que los tres anteriores...
Muchisimas gracias!
bueno en el bennupack hay un ejemplo de records en linea
ver example_dlls - multiplayer
menos mal que sabes php...
para enviar peticiones al servidor : como usas php puedes adicionar variables.
pagina.php?cadena=micadena;puntaje=230
recuerda que en una peticion no puedes enviar espacios...
cadena=hola mundo
creo que seria
cadena=hola%mundo
y para recolectar datos hay tienes el ejemplo en el bennupack
incluye lo que dije anteriormente..
mejor dicho bájate el ejemplo en dlls del bennupack... y listo...
Gracias l1nk3rn3l por tu respuesta, sin embargo estoy revisando el código del programa web y no lo acabo de entender. El código del ejemplo es el siguiente:
msg=request[2]+" 405 Method Not Allowed";
tcpsock_send(sock,&msg,len(request[2])+23);
Para empezar, no entiendo lo del +23. He visto que son exactamente los cáracteres de "request[2]", pero ¿entonces porqué no usa el len con la cadena msg?
Por otro lado, he simplificado mi código ciñiendome a ese ejemplo y usando fdsock.dll en vez de fsock.dll de la siguiente manera:
t_usuario = "D";
tcpsock_send(socket,&t_usuario, (len(t_usuario))+1);
y en el otro extremo sigo recibiendo el mismo número ASCII tanto si envío una "D" como en el ejemplo anterior o una "a".
He ejecutado el ejemplo, este abre el socket en el puerto 80, pero no puedo conectarme, y en la ventana del programa aparece "client:0"
¿Alguna idea?
Saludos!
Corrijo, ya he visto porqué no "podía conectarme" al servidor web y este funciona correctamente, sin embargo aun no he entendido como envía esos datos... sigo buscando.
Saludos!
¡¡Ya he localizado el problema!!
Para enviar una "string", tiene que ser de tipo "char". Si probais a enviar un "string" envía la dirección de memoria no el contenído de la misma.
Saludos!
;D
global
clients=0;
logfd;
DocumentRoot = "webpages";
AccessLog = "access.log";
begin
full_screen=false;
set_title("Mini WebServer");
fsock_init( 0 ); // Inicializamos la librería fsock
write(0,5,5,0,"Clients: ");
write_var(0,5+text_width(0,"Clients: "),5,0,clients);
server_thread();
end;
function log(string slog)
private
strint str;
begin
logfd = fopen(AccessLog, O_RDWR);
if (!logfd)
logfd = fopen(AccessLog, O_WRITE);
end
fseek(logfd, 0, SEEK_END);
fputs(logfd,ftime("%d/%m/%Y-%H:%M:%S> ",time()) + slog);
fclose(logfd);
end
process server_thread()
private
int socket_listen; // socket_listen para recoger peticiones
int connection=0;
int ipaddr, portaddr;
int i;
int informacion; // enviaremos a los clientes números aleatorios entre 0 y 32768
begin
log("Web Server, Started!");
socket_listen=tcpsock_open(); // nuevo socket
fsock_bind(socket_listen,80); // asociamos socket_listen con el puerto 80
tcpsock_listen(socket_listen,64); // numero de conexiones a escuchar igual a clients
fsock_fdzero(0);
fsock_fdset(0,socket_listen);
while(!key(_ESC))
if (fsock_select(0,-1,-1,0)>0)
say("geca");
connection=tcpsock_accept(socket_listen, &ipaddr, &portaddr);
if(connection>0)
process_client(connection, ipaddr, portaddr);
end
end
fsock_fdset (0, socket_listen); //hay que reincluir tras uso de select
frame;
end;
onexit
fsock_quit(); // Cerramos la librería fsock
end
process process_client(int sock, int ipaddr, int portaddr)
private
char msg[2048];
string hdrFields[128];
string request[3];
rlen, slen, n, pos, d1, d2, cnt;
fp;
string lang;
begin
clients++;
//log("Connect from ip "+((ipaddr)&0ffh)+"."+((ipaddr>> &0ffh)+"."+((ipaddr>>16)&0ffh)+"."+((ipaddr>>24)&0ffh));
log("Connect from ip "+ fsock_get_ipstr(&ipaddr) + ":" + portaddr);
fsock_fdzero(1);
fsock_fdset(1,sock);
while(!key(_esc))
// Esto se podria hacer todo un fdset general, pero como cada frame se ejecuta por separado no hay problemas aca
if (fsock_select(1,-1,-1,0)>0 && fsock_fdisset(1,sock))
// En una aplicacion real, aca se debe poner un loop hasta recibir el paquete completo
rlen=tcpsock_recv(sock,&msg,sizeof(msg));
if(rlen<=0)
break;
end
// Suponemos que aca tenemos el paquete completo
cnt=split("["+chr(13)+chr(10)+"]+", msg, &hdrFields, sizeof(hdrFields));
for(n=1;n<cnt;n++)
if(strcasecmp(substr(hdrFields[n],0,17),"Accept-Language: ")==0)
lang=substr(hdrFields[n],17);
end
end
cnt=split("[ ]+", hdrFields[0], &request, sizeof(request));
log("Request ["+hdrFields[0]+"]");
if(request[0]!="GET")
msg=request[2]+" 405 Method Not Allowed";
tcpsock_send(sock,&msg,len(request[2])+23);
break;
end
/* Expand */
while((pos=find(request[1],"%")) != -1)
d1=asc(ucase(substr(request[1], pos+1, 1)));
d2=asc(ucase(substr(request[1], pos+2, 1)));
if(d1>=asc("A"))
d1-=asc("A")-10;
else
d1-=asc("0");
end
if(d2>=asc("A"))
d2-=asc("A")-10;
else
d2-=asc("0");
end
request[1]=substr(request[1], 0, pos)+chr(d1*16+d2)+substr(request[1], pos+3);
end
/* Comprueba si se quiere acceder a otro directorio anterior al DocumentRoot */
if(find(request[1], "..") != -1)
msg=request[2]+" 403 Forbidden";
tcpsock_send(sock,&msg,len(request[2])+14);
break;
end
// Aca usando los modo de manejo de archivos GZ, podemos dar soporte a archivos paginas gzip
if(substr(request[1],-1,1)=="/")
fp = fopen(DocumentRoot+request[1]+"index.html."+lang, O_READ);
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm."+lang, O_READ);
end
fp = fopen(DocumentRoot+request[1]+"index."+lang+".html", O_READ);
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index."+lang+".htm", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.html.html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm.html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.html.htm", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm.htm", O_READ);
end
else
fp = fopen(DocumentRoot+request[1]+"."+lang, O_READ);
if (!fp)
fp = fopen(DocumentRoot+request[1], O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+".html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+".htm", O_READ);
end
end
if (!fp)
msg=request[2]+" 404 Not Found";
tcpsock_send(sock,&msg,14+len(request[2]));
break;
end
while(!feof(fp))
slen=fread(fp, msg);
tcpsock_send(sock,&msg,slen);
frame;
end
fclose(fp);
break;
end
fsock_fdset(1,sock); //hay que reincluir socket tras select
frame;
end
onexit
fsock_close(sock);// Cierra el socket
clients--;
end
No entiendo el ejemplo de splinter, este se conecta como servidor y crea un cliente, y para crear mas clientes ?
Y para que usa el index.html ?
es un servidor web...
los clientes son las conexiones web... cada vez que vos requeris un objeto a un servidor web, se arma una conexion, esa conexion es 1 cliente.
el index.html es lo que responde el servidor web, cuando uno se conecta y hace un get /
O sea, para crear otro cliente tendria que abrir esa pagina del servidor en el navegador de otra maquina ?
Ya lo he probao, funciona de maravilla, abres la pagina localhost/index.html en el IE y funciona como servidor web...
Por cierto el write_var (clients) no funciona, hay que poner un proceso aparte con frame; loop y write a secas
no te entendi lo del write_var.
que no actualiza el valor, tu ejemplo no hace refresh al write
eso no es posible...
el write_var ese, indica la cantidad de clientes en linea a la vez... por eso es que decis que no actualiza, porque si estas con 1 solo cliente a la vez y si el requerimiento se resuelve rapido, no vas a ver que se mueva mucho... seguramente lo veras todo el tiempo a 0.
muy facil lo tienes, pon un say(client) despues del client++ y ya me darás la razón (y cambialo por un write a secas)...
no tengo el entorno de desarrollo bennugd en mi maquina, aun no tengo el disco rigido final de mi maquina.
por favor, pasame un paquete con tus ejecutables y dll fsock.dll que usas para probar, con el .prg que usaste.
por otro lado, en la funcion process_client en el onexit, comenta o elimina la siguiente linea
clients--;
y decime que pasa.
Es que mi ejemplo ya estaba modificado y por otro lado no lo tengo ya, hice la prueba en el curro ;D
pues vale, no siento, por el momento no podre ayudarte, estoy a 1/2 maquina...
No, si no es a mi que me tienes que ayudar, es sólo un reparo de algun posible bug de Bennu, para mi esta ok ;D
Es tu ejemplo, no me pidas lo que es tuyo
Quote from: FreeYourMind on January 14, 2012, 11:13:23 AM
No, si no es a mi que me tienes que ayudar, es sólo un reparo de algun posible bug de Bennu, para mi esta ok ;D
Es tu ejemplo, no me pidas lo que es tuyo
cuando recupere mi disco y mi backup lo vere... gracias.
no has hecho la prueba que te pedi, cierto?
Que ya no tengo la carpeta de la demo, tendria que montarlo de nuevo con la ultima version.
A ver si luego cuando me ponga con algo lo miro
hombre, simplemente copias el fuente del post que pusiste aca, lo editas, lo compilas y listo... yo no tengo la fsock.dll que estabas usando, si me la pasas lo pruebo...
La tienes tu en tu pagina de descargas del betatester, no se si me explico xD
ls fsock? jojo.. que despistado que estoy... gracias!
lo dicho, write_var funciona perfectamente en el ejemplo... cuando se conecta el cliente el contador sube, cuando se responde el contador se decrementa y el proceso cliente muere...
lo que habias reportado no tiene logica, pero bueno... en fin...
pone una pagina grande, saca el set_fps(0,0), ponele un set_fps(1,0) y vas a ver como vas a ver al contador mantenerse un tiempito.
EDIT: No se porque en wine no me abre la conexion en el port 80, com le estoy pidiendo... en fin... el write_var y la fsock funcionan.
A mi no me funciona.
Yo cada cliente que habro es una pestaña nueva en el navegador, no se como lo haces tu...
puf!!!
hombre, que tengas 800 pestañas del navegador ni significan que tengas 800 clientes conectados... las pestañas del navegador, no significan conexiones permanentes (si bien existen servidores que pueden soportar conexiones persistentes, este no es el caso)... incluso cada pestaña para que vos puedas ver la pagina en tu navegador, se ejecutaron muchas conexionex http... muchos requermientos... por ejemplo, 1 requerimiento trae la pagina html, otro requerimiento, traer 1 imagen que referencia el html (1 requermiento por cada imagen)... luego podes tener 1 requermiento por cada .js o cada .flv o cada .swf o cada .css que aparezca en la pagina, por cada objeto que llame la pagina es 1 requerimiento...
los requerimientos se atienden y cuando obtienen su respuesta, se corta la conexion...
por ende, cuando la pagina esta cargada, ya no existe ningun cliente conectado... por 800, 1000 o 3000 pestañas que tengas abiertas...
acaso pensabas que mientras tenias el browser con la pagina mostrandose estabas conectado al servidor?
bue, espero haber explicado un poco el tema...
hay muchos documentos en internet que describen el protocolo http...
Y porque client es incrementado al abrir una pestana nueva con la pagina ? El say asi lo indica
pero es lo que te estoy diciendo, al conectarse se incrementa y en el onexit se decrementa...
ni te has molestado en ver el codigo, cierto? simplemente como no funcionaba segun tu logica piensa que deberia funcionar, has dicho que no funciona, cierto?
por favor, lee el codigo, y pregunta si no entiendes algo... no tengo problema de explicarlo linea a linea si es necesario, pero intenta entenderlo.
y repito, la cantidad de clientes, no va a asociada a la cantidad de pestañas, sino a la cantidad de pedidos a la vez... cada objeto es 1 pedido, por ejemplo, si tengo un html con 1 grafico... son 2 clientes (que pueden ejecutarse a la vez o no, depende de la rapidez con que se respondan o como el browser los pida), 1 cliente es el html y otro cliente es el grafico... son 2 archivos que se le piden al servidor... el contador de clientes solo esta indicando los clientes que se estan atendiendo (o estan conectados), cuando se les atendio el pedido, se desconectan...
pensa que ningun servidor puede mantener todas las conexiones activas, debe atenderlas lo mas rapido posible y liberar el puerto para otro nuevo cliente... sino ningun servidor web en internet podria subsistir demasiado tiempo... con 65535 pedidos (si nos ponemos optimistas y pensando que son todos los puertos para el, cosa que nunca es cierto) se quedaria sin poder atender a otros.
ademas, es simple, le quitas el clientes--; y veras que el contador incrementa... vamos hombre, al menos molestate en probar lo que te pido... por lo menos asi me haces sentir que no pierdo el tiempo explicando a una planta o una pared...
Si tienes razón, habre metido la pata, pero puse el write en un proceso nuevo despues del client++ (matando el proceso y limpiando el texto antes) y este se incrementaba siempre sin nunca decrementar... Bueno ya miraré porque ocurre esto ultimo. gracias y perdona.
Aqui el código modificado:
global
clients=0;
logfd;
DocumentRoot = "webpages";
AccessLog = "access.log";
begin
full_screen=false;
set_title("Mini WebServer");
fsock_init( 0 ); // Inicializamos la librería fsock
//write(0,5,5,0,"Clients: ");
//write(0,5+text_width(0,"Clients: "),5,0,clients);
write_screen();
server_thread();
end;
process write_screen()
begin
write(0,5,5,0,"Clients: ");
write(0,5+text_width(0,"Clients: "),5,0,clients);
LOOP
frame;
end
end
function log(string slog)
private
strint str;
begin
logfd = fopen(AccessLog, O_RDWR);
if (!logfd)
logfd = fopen(AccessLog, O_WRITE);
end
fseek(logfd, 0, SEEK_END);
fputs(logfd,ftime("%d/%m/%Y-%H:%M:%S> ",time()) + slog);
fclose(logfd);
end
process server_thread()
private
int socket_listen; // socket_listen para recoger peticiones
int connection=0;
int ipaddr, portaddr;
int i;
int informacion; // enviaremos a los clientes números aleatorios entre 0 y 32768
begin
log("Web Server, Started!");
socket_listen=tcpsock_open(); // nuevo socket
fsock_bind(socket_listen,80); // asociamos socket_listen con el puerto 80
tcpsock_listen(socket_listen,64); // numero de conexiones a escuchar igual a clients
fsock_fdzero(0);
fsock_fdset(0,socket_listen);
while(!key(_ESC))
if (fsock_select(0,-1,-1,0)>0)
connection=tcpsock_accept(socket_listen, &ipaddr, &portaddr);
if(connection>0)
process_client(connection, ipaddr, portaddr);
end
end
fsock_fdset (0, socket_listen); //hay que reincluir tras uso de select
frame;
end;
onexit
fsock_quit(); // Cerramos la librería fsock
end
process process_client(int sock, int ipaddr, int portaddr)
private
char msg[2048];
string hdrFields[128];
string request[3];
rlen, slen, n, pos, d1, d2, cnt;
fp;
string lang;
begin
clients++;
delete_text(all_text);
signal(type write_screen, s_kill);
write_screen();
//log("Connect from ip "+((ipaddr)&0ffh)+"."+((ipaddr>> &0ffh)+"."+((ipaddr>>16)&0ffh)+"."+((ipaddr>>24)&0ffh));
log("Connect from ip "+ fsock_get_ipstr(&ipaddr) + ":" + portaddr);
fsock_fdzero(1);
fsock_fdset(1,sock);
while(!key(_esc))
// Esto se podria hacer todo un fdset general, pero como cada frame se ejecuta por separado no hay problemas aca
if (fsock_select(1,-1,-1,0)>0 && fsock_fdisset(1,sock))
// En una aplicacion real, aca se debe poner un loop hasta recibir el paquete completo
rlen=tcpsock_recv(sock,&msg,sizeof(msg));
if(rlen<=0)
break;
end
// Suponemos que aca tenemos el paquete completo
cnt=split("["+chr(13)+chr(10)+"]+", msg, &hdrFields, sizeof(hdrFields));
for(n=1;n<cnt;n++)
if(strcasecmp(substr(hdrFields[n],0,17),"Accept-Language: ")==0)
lang=substr(hdrFields[n],17);
end
end
cnt=split("[ ]+", hdrFields[0], &request, sizeof(request));
log("Request ["+hdrFields[0]+"]");
if(request[0]!="GET")
msg=request[2]+" 405 Method Not Allowed";
tcpsock_send(sock,&msg,len(request[2])+23);
break;
end
/* Expand */
while((pos=find(request[1],"%")) != -1)
d1=asc(ucase(substr(request[1], pos+1, 1)));
d2=asc(ucase(substr(request[1], pos+2, 1)));
if(d1>=asc("A"))
d1-=asc("A")-10;
else
d1-=asc("0");
end
if(d2>=asc("A"))
d2-=asc("A")-10;
else
d2-=asc("0");
end
request[1]=substr(request[1], 0, pos)+chr(d1*16+d2)+substr(request[1], pos+3);
end
/* Comprueba si se quiere acceder a otro directorio anterior al DocumentRoot */
if(find(request[1], "..") != -1)
msg=request[2]+" 403 Forbidden";
tcpsock_send(sock,&msg,len(request[2])+14);
break;
end
// Aca usando los modo de manejo de archivos GZ, podemos dar soporte a archivos paginas gzip
if(substr(request[1],-1,1)=="/")
fp = fopen(DocumentRoot+request[1]+"index.html."+lang, O_READ);
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm."+lang, O_READ);
end
fp = fopen(DocumentRoot+request[1]+"index."+lang+".html", O_READ);
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index."+lang+".htm", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.html.html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm.html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.html.htm", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+"index.htm.htm", O_READ);
end
else
fp = fopen(DocumentRoot+request[1]+"."+lang, O_READ);
if (!fp)
fp = fopen(DocumentRoot+request[1], O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+".html", O_READ);
end
if (!fp)
fp = fopen(DocumentRoot+request[1]+".htm", O_READ);
end
end
if (!fp)
msg=request[2]+" 404 Not Found";
tcpsock_send(sock,&msg,14+len(request[2]));
break;
end
while(!feof(fp))
slen=fread(fp, msg);
tcpsock_send(sock,&msg,slen);
frame;
end
fclose(fp);
break;
end
fsock_fdset(1,sock); //hay que reincluir socket tras select
frame;
end
onexit
fsock_close(sock);// Cierra el socket
clients--;
end
free, write no se actualiza cuando cambia de valor...
en fin...
Tienes razón, me has pillao en esos momentos de retroceso mental xD
en serio, si algo no te ha quedado claro, pregunta... no hay problema... no quiero que me des la razon, porque si.