Página 1 de 1

Comunicacion en JSON a traves de Socket

Publicado: Vie May 09, 2025 1:38 am
por michaelp
Saludos , necesito comunicacion en JSON a traves de Socket, Tanto en C como en JAVA las realizo sin problemas , pero no quiero tener muchos ejecutables , He descargado hbsocket.c y hbsocket.h y edite un Makefile pero no tiene TSocket que es lo que necesito alguna idea para poder conseguirla o reemplazar? Agradeceria esa ayuda esto con XAILER ENTERPRISE 9.2 Gracias de antemano

Re: Comunicacion en JSON a traves de Socket

Publicado: Vie May 09, 2025 8:21 am
por Jose Lopez
Hola.
Te paso esta rutina que usé hace algún tiempo.

METHOD ButtonRecibirDatosClick( oSender ) CLASS TFormMenu
Local cPath := AppData:cPathDatos+"\"
LOCAL pSocket, cBuffer, nBytes, cRequest, cResponse, cFileIpServer, cPathDatos, cIpServer

cPathDatos := cPath // hb_DirBase() + "Datos\"

cFileIpServer := cPathDatos+"IpServer.ini"
cIpServer := FileStr(cFileIpServer)

::oMemo1:Clear()

// initializar sockets
hb_INetInit()
pSocket := hb_INetConnect( cIpServer, 22221 )
IF hb_INetErrorCode( pSocket ) <> 0
::oMemo1:Append("Socket error: "+ToString(hb_INetErrorDesc( pSocket ) ) + CRLF )
hb_INetCleanUp()
RETURN Nil
ENDIF
If ToString( oSender:Cargo) == "CARGOS"
Text into cRequest
<?xml version="1.0" encoding="UTF-8" ?>
<SXML>
<solicitud id="0" baseDatos="HotelSql" claveAcceso="">
<tipoOperacion>CONSULTA_TIPOS_CARGO</tipoOperacion>
</solicitud>
</SXML>
EndText
ElseIf ToString( oSender:Cargo) == "COBROS"
Text into cRequest
<?xml version="1.0" encoding="UTF-8" ?>
<SXML>
<solicitud id="0" baseDatos="HotelSQL" claveAcceso="">
<tipoOperacion>CONSULTA_TIPOS_COBRO</tipoOperacion>
</solicitud>
</SXML>
EndText
Else
RETURN Nil
EndIf

nBytes := hb_INetSend( pSocket, cRequest )
cResponse:= ""
// get HTTP response from server
DO WHILE nBytes > 0
cBuffer := Space( 4096 )
nBytes := hb_INetRecv( pSocket, @cBuffer )
cResponse += Left( cBuffer, nBytes )
ENDDO

// disconnect and cleanup memory
hb_INetClose( pSocket )
hb_INetCleanUp()

// save response
StrFile( cResponse,"Receive.xml" )
::oMemo1:Append( cResponse )


RETURN Nil

Re: Comunicacion en JSON a traves de Socket

Publicado: Vie May 09, 2025 3:05 pm
por ignacio
Gracias por la contribución.

Saludos

Re: Comunicacion en JSON a traves de Socket

Publicado: Vie May 09, 2025 7:06 pm
por michaelp
Gracias me funciono perfecto lo convertí a una Clase clasica de Xailer

CLASS TInetClient
DATA cHost
DATA nPort
DATA pSocket
DATA cResponse

METHOD New( cHost, nPort )
METHOD Connect()
METHOD SendRequest( cRequest )
METHOD Close()

ENDCLASS

//---------------------------------------------------------------------------------

METHOD New( cHost, nPort ) CLASS TInetClient

::cHost := cHost
::nPort := nPort
::pSocket := NIL
::cResponse := ""

RETURN Self

//---------------------------------------------------------------------------------

METHOD Connect() CLASS TInetClient

hb_inetInit()
::pSocket := hb_inetConnect( ::cHost, ::nPort )

IF hb_inetErrorCode( ::pSocket ) <> 0
::cResponse := "[ERROR] Conexión fallida: " + hb_inetErrorDesc( ::pSocket )
RETURN .F.
ENDIF

RETURN .T.

//---------------------------------------------------------------------------------

STATIC FUNCTION IntToLE( n )
RETURN Chr( hb_bitAnd(n, 0xFF) ) + ;
Chr( hb_bitAnd(hb_bitShift(n, -8), 0xFF) ) + ;
Chr( hb_bitAnd(hb_bitShift(n, -16), 0xFF) ) + ;
Chr( hb_bitAnd(hb_bitShift(n, -24), 0xFF) )

//---------------------------------------------------------------------------------

METHOD SendRequest( cRequest ) CLASS TInetClient

LOCAL cBuffer, nBytes, cHeader, nLen, nTotal
::cResponse := ""

IF Empty( ::pSocket )
::cResponse := "[ERROR] Socket no conectado"
RETURN NIL
ENDIF

// Construir cabecera de 32 bytes con protocolo del marcador
nLen = Len( cRequest )
cHeader := IntToLE( nLen ) + ;
IntToLE( 0x18181818 ) + ;
IntToLE( 0 ) + ;
Replicate( Chr(0), 20 )

hb_inetSend( ::pSocket, cHeader + cRequest )

// Leer cabecera de respuesta (32 bytes)
cBuffer := Space( 32 )
nBytes := hb_inetRecv( ::pSocket, @cBuffer )
IF nBytes < 32
::cResponse := "[ERROR] Cabecera incompleta"
RETURN ::cResponse
ENDIF

// Leer longitud de datos desde cabecera (manual unpack LE)
// Leer longitud de datos desde cabecera (manual unpack LE)
nTotal := hb_bitOr( Asc( SubStr( cBuffer, 1, 1 ) ), ;
hb_bitOr( hb_bitShift( Asc( SubStr( cBuffer, 2, 1 ) ), 8 ), ;
hb_bitOr( hb_bitShift( Asc( SubStr( cBuffer, 3, 1 ) ), 16 ), ;
hb_bitShift( Asc( SubStr( cBuffer, 4, 1 ) ), 24 ) ) ) )

::cResponse := ""

DO WHILE Len( ::cResponse ) < nTotal
cBuffer := Space( 4096 )
nBytes := hb_inetRecv( ::pSocket, @cBuffer )
IF nBytes <= 0
EXIT
ENDIF
::cResponse += Left( cBuffer, nBytes )
ENDDO

RETURN ::cResponse

//---------------------------------------------------------------------------------

METHOD Close() CLASS TInetClient

IF !Empty( ::pSocket )
hb_inetClose( ::pSocket )
::pSocket := NIL
ENDIF

hb_inetCleanUp()

RETURN NIL y lo llamo asi desde mi formulario


oClient := TInetClient():New( "175.120.2.226", 5005 )

IF oClient:Connect()
oClient:SendRequest('{"comand":"GetInfo"}' )
::oMemo1:Value := oClient:cResponse
oClient:Close()
ELSE
MsgInfo( oClient:cResponse )
ENDIF

Re: Comunicacion en JSON a traves de Socket

Publicado: Vie May 09, 2025 9:05 pm
por Jose Lopez
Muchas gracias a ti por compartir la adaptación a una Clase.