Hola amigos
Estoy haciendo una aplicacion con FWH en la cual necesito implementar consultas a una DBF de un Servidor, en principio pense hacerlo via FTP pero estudiando los Socket creo que esa seria la mejor opcion.
Las consultas pueden ser muchas y puede ocurrir que varias se hagan en forma simultanea, probe usando los ejemplos de FWH pero tengo que hacer las mismas de a una y eso me origina muchos retrasos y bloqueos del servidor por lo que empece a estudiar la clase HBSOCKET de Daniel Garcia Gil que parece funcionar bien con las funciones de Harbour pero no llego a comprender bien como funciona el Multihilo, como controlarlos y como optimizar las funciones para evitar errorres en el Servidor.
Busque ejemplos, pero todos los que encontre me resultaron incompletos y muy basicos, he intentado comunicarme con Daniel via email a ver si el me puede aportar algun ejemplo mas completo de su uso pero aun no he tenido respuesta.
Agradeceria mucho si alguien me puede ilustrar con algun ejemplo de como usarla para lograr lo que necesito.
En resumen, consultas simultaneas de clientes que envian una cadena con datos al Servidor Socket que debe ser procesada por el mismo, que consulta a una o varias DBF y luego genera una respuesta que debe ser enviada al cliente que hizo la consulta.
No he encontrado documentacion que explicite el uso de las funciones incluidas en Harbour.
Como soy neofito en el uso de los sockets les estaria muy agradecido si pudieran orientarme en el tema
HBSOCKET FUCIONAN BIEN LOS THREADS ?
Re: HBSOCKET FUCIONAN BIEN LOS THREADS ?
No reinventes la rueda.
Trata de probar LETODB y NETIO que te permiten acceder a las dbf de las siguiente forma
use //190.151.50.90/datos/clientes.dbf
Trata de probar LETODB y NETIO que te permiten acceder a las dbf de las siguiente forma
use //190.151.50.90/datos/clientes.dbf
Ji,ji,ji... buena la cosa... "all you need is code"
http://www.xdata.cl - Desarrollo Inteligente
----------
Lenovo Legion Y520, 16GB Ram, 1 TB NVME M.2, 1 TB SSD, GTX 1050
http://www.xdata.cl - Desarrollo Inteligente
----------
Lenovo Legion Y520, 16GB Ram, 1 TB NVME M.2, 1 TB SSD, GTX 1050
- pablovidal
- Posts: 398
- Joined: Thu Oct 06, 2005 10:15 pm
- Location: Republica Dominicana
- Contact:
Re: HBSOCKET FUCIONAN BIEN LOS THREADS ?
Esto es un ejemplo..
Code: Select all
#include "inkey.ch"
#include "setcurs.ch"
#include "hbsocket.ch"
#include "hbclass.ch"
#include "std.ch"
#define CRLF chr(13)+chr(10)
Function Main()
Local nLinea := 1
SetMode( 40, 150 )
SET COLOR TO "W+/B"
CLS
While lastkey() != 27
nLinea := 1
clear
hb_ThreadStart( @MainSocket(), nLinea, "ClientName", "HostName" , nPuerto ) ; Inkey(0.01) ; nLinea++
hb_ThreadStart( @MainSocket(), nLinea, "ClientName", "HostName" , nPuerto ) ; Inkey(0.01) ; nLinea++
hb_ThreadStart( @MainSocket(), nLinea, "ClientName", "HostName" , nPuerto ) ; Inkey(0.01) ; nLinea++
Inkey(59)
Enddo
Return Nil
Function MainSocket( nLinea, cBanca, cHostName, nPort )
Local oSocket
Local cInfo := ""
Local nMill := hb_MilliSeconds()
@ nLinea, 01 Say cBanca + " : " + StrZero( nPort, 4 ) + " || "
Hb_InetInit()
oSocket := Hb_InetConnect( cHostName, nPort )
hb_InetTimeout( oSocket, 30 )
Hb_InetSend( oSocket, "#VER~" + CRLF )
If ReadLine( oSocket, @cInfo )
@ nLinea, 28 Say StrZero( hb_MilliSeconds() - nMill, 5 ) + " | " + cInfo
End
Hb_InetClose( oSocket )
Hb_InetCleanup()
Return( cInfo )
Static Function ReadLine( Socket, cInfo )
Local lRet := .t.
Local nBytes
do while .t.
if Hb_InetDataReady( Socket, 512 ) > 0
BEGIN SEQUENCE
cInfo := Hb_InetRecvLine( Socket, @nBytes )
RECOVER
lRet := .f.
END
exit
endif
enddo
Return lRet
Saludos,
Pablo Alberto Vidal
/*
------------------------------------------------------
Harbour 3.2.0, Fivewin 17.02, BCC7
------------------------------------------------------
*/
Pablo Alberto Vidal
/*
------------------------------------------------------
Harbour 3.2.0, Fivewin 17.02, BCC7
------------------------------------------------------
*/
Re: HBSOCKET FUCIONAN BIEN LOS THREADS ?
Gracias por sus respuestas...ya entendi como usar el Multithread, solo me faltaria saber como generar la consulta y enviar la respuesta al cliente usando HB_SOCKETSEND()
Estoy usando este codigo en el Socket Server
La funcion Process me devuelve siempre el largo de la cadena que envio desde el acliente...
En lugar de ello necesito hacer una consulta a una DBF y luego enviar mi respuesta al Cliente
Espero que puedan ayudarme porque no logro entender como hacerlo
Estoy usando este codigo en el Socket Server
Code: Select all
#include 'fivewin.ch'
#include "hbsocket.ch"
#define ADDRESS "0.0.0.0"
#define PORT 8000
#define EOT ( Chr( 4 ) )
#define LISTEN_TIMEOUT 3000 // 3s
#define RECV_TIMEOUT 10000 // 10s
STATIC oWnd,oBar,hListen,hSocket
*REQUEST HB_MT
//..............
Function main()
DEFINE WINDOW oWnd TITLE 'Server Socket'
DEFINE BUTTONBAR oBar OF oWnd _3D 2007
DEFINE BUTTON FILE '.\connect.bmp' OF oBar ACTION Server() TOOLTIP "Listen"
DEFINE BUTTON FILE '.\door.bmp' OF oBar ACTION oWnd:end()
* DEFINE BUTTON OF oBar ACTION oClient:SendData( "Hello from server!" ) TOOLTIP "Talk to client"
ACTIVATE WINDOW oWnd
RETU .T.
//....................
Function Server()
if !hb_mtvm()
? "soporte multithread es requerido..."+CRLF+;
"Compile: Buildh Ipserver /mt"
return .T.
else
? 'Mutithread activo'
endif
? "create listening socket..."
if empty( hListen := hb_socketOpen() )
? "socket create error " + hb_ntos( hb_socketGetError() )
endif
if !hb_socketBind( hListen, { HB_SOCKET_AF_INET, ADDRESS, PORT } )
? "bind error " + hb_ntos( hb_socketGetError() )
endif
if !hb_socketListen( hListen )
? "listen error " + hb_ntos( hb_socketGetError() )
else
? 'A la escucha...'
endif
oWnd:SetText('Socket a la escucha...')
do while .t.
if empty( hSocket := hb_socketAccept( hListen, , LISTEN_TIMEOUT ) )
if hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT
* ? "loop..."
else
? "accept error " + hb_ntos( hb_socketGetError() )
endif
else
* ? "accept socket request"
hb_threadDetach( hb_threadStart( @process(), hSocket ) )
endif
if getkeystate(VK_ESC)
? 'Socket detenido...'
exit
endif
enddo
oWnd:SetText('Escucha Detenida...') // ? "close listening socket..."
hb_socketShutdown( hListen )
hb_socketClose( hListen )
return NIL
//..........................
Function process( hSocket )
local cRequest
local nLen
local cBuf
do while .t.
cRequest := ""
nLen := 1
do while at( EOT, cRequest ) == 0 .and. nLen > 0
cBuf := space( 4096 )
if ( nLen := hb_socketRecv( hSocket, @cBuf, , , RECV_TIMEOUT ) ) > 0
cRequest += left( cBuf, nLen )
else
if nLen == -1 .AND. hb_socketGetError() == HB_SOCKET_ERR_TIMEOUT
nLen := 0
endif
endif
enddo
if nLen == -1
? "hb_socketRecv error " + hb_ntos( hb_socketGetError() )
elseif nLen == 0
? "connection closed"
exit
else
* if "exit" $ cRequest
if EOT $ cResquest
? "exit"
exit
endif
endif
enddo
? "close socket..."
hb_socketShutdown( hSocket )
hb_socketClose( hSocket )
return NIL
La funcion Process me devuelve siempre el largo de la cadena que envio desde el acliente...
En lugar de ello necesito hacer una consulta a una DBF y luego enviar mi respuesta al Cliente
Espero que puedan ayudarme porque no logro entender como hacerlo