HBSOCKET FUCIONAN BIEN LOS THREADS ?

HBSOCKET FUCIONAN BIEN LOS THREADS ?

Postby rterraz » Wed Jul 02, 2014 1:14 pm

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
User avatar
rterraz
 
Posts: 182
Joined: Wed Nov 08, 2006 11:44 pm
Location: Argentina

Re: HBSOCKET FUCIONAN BIEN LOS THREADS ?

Postby Adolfo » Mon Jul 07, 2014 8:08 pm

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
;-) Ji,ji,ji... buena la cosa... "all you need is code"

http://www.xdata.cl - Desarrollo Inteligente
----------
Asus TUF F15, 32GB Ram, 1 TB NVME M.2, 1 TB SSD, GTX 1650
User avatar
Adolfo
 
Posts: 846
Joined: Tue Oct 11, 2005 11:57 am
Location: Chile

Re: HBSOCKET FUCIONAN BIEN LOS THREADS ?

Postby pablovidal » Mon Jul 07, 2014 9:23 pm

Esto es un ejemplo..
Code: Select all  Expand view

#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
------------------------------------------------------
*/
User avatar
pablovidal
 
Posts: 401
Joined: Thu Oct 06, 2005 10:15 pm
Location: Republica Dominicana

Re: HBSOCKET FUCIONAN BIEN LOS THREADS ?

Postby rterraz » Mon Jul 14, 2014 3:38 pm

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

Code: Select all  Expand view

#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
User avatar
rterraz
 
Posts: 182
Joined: Wed Nov 08, 2006 11:44 pm
Location: Argentina


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 28 guests