by Jorge Jaurena » Tue Dec 20, 2011 12:21 pm
Este es un caso muy particular ya que el primer byte de la respuesta siempre es nul, esto hace que el evento de lectura asuma que ahi termina la transmision y no recibe mas, por lo tanto nunca recibia nada.
Esto lleva a tener que pasar los byte recibidos a hexa o a decimal, la funcion que probe es la siguiente:
// Esto lo compile y funciono bien asumiendo una cadena de byte de 8 bits separados por un espacio, lo que no significa que siempre venga
// asi, eso depende de lo que tu servidor envie, esa informacion deberia dartela quien desarrollo el server.
// Todo lo paso directo a caracter que en definitiva era lo que necesitaba.
#include "FiveWin.ch"
Function Main()
Local Var
Var:="00100110 00100000 00101110 00101111"
MsgInfo(BinToChr(Var),"Resultado")
Return nil
Function BinToChr(cBin)
Local n,q,nResult,Retorno,NumBin
Retorno:=""
NumBin :=""
For q=1 To Len(cBin)
IF SUBSTR(cBin,q,1)==" "
NumBin:=""
ELSE
NumBin:=NumBin+SUBSTR(cBin,q,1)
ENDIF
IF LEN(NumBin)=8
nResult:=0
For n=8 to 1 Step -1
IF SubStr(NumBin,n,1)=="1"
nResult += 2 ^ ( 8-n )
endif
Next
Retorno:=Retorno+CHR(INT(nResult))
ENDIF
Next
Return Retorno
//
En mi problema en particular esto no funciono, a pesar de que el modelo de arriba funciona perfecto.
Aclaro que los proveedores del hard no son los autores del protocolo de comunicacion, entonces tampoco podian informarme bien, asi que tenia que arreglarmelas un poco solo.
Entre tantas pruebas, por casualidad el exe produce un error y graba el ya conocido error.log, cuando lo abro a ver que habia hecho mal me encuentro con la grata sorpresa que en el primer argumento (la variable que supuestamente contenia la lectura recibida y yo no podia ver) estaba la cadena de caracteres tal cual como yo queria obtenerla.
Por lo tanto deje de probar otras cosas y mire como hace FWH para generar el error.log e hice exactamente lo mismo y obtuve un archivo plano con una linea que contenia lo que queria obtener.
Aqui muestro la solucion.
// Esto es para establecer la comunicacion, enviar el comando y recibir la respuesta, en este caso en particular el server se cierra solo
// despues de enviar la respuesta.
Function EnvioComando()
Local oSocket
oSocket:= TSocket():New( 997 ) && Aca creo el socket, el puerto (997) deberia decirtelo el que desarrollo el server.
oSocket:bRead:= { | oSocket | VerResSer(oSocket:GetData()) } && Este es el evento de lectura, aca recibe la respuesta
oSocket:Connect( "192.168.0.150" ) && Esta es la ip donde esta el server.
oSocket:SendData("q") && Aca envio un comando, los comandos deberian ser indicados por quien desarrollo el server.
// oSocket:End() && Solo si el server no se cierra solo y quiero cerrar el puerto. En mi caso esto no va.
Return nil
// En la siguiente funcion entra la respuesta como parametro y simplemente se graba en el archivo de texto, de ahi en mas uno hace lo que
// quiere, pero ya esta en formato legible. Yo lo paso a una dbf porque me sirve para lo que quiero hacer pero podes leerlo directo del txt.
Function VerResSer(Dato)
MemoWrit( "Resp.txt", cValToChar(Dato) ) && Asi graba el error.log
USE BASE NEW
APPEND FROM Resp.txt SDF
CLOSE
Return nil
Aclaro que todo esto comenzo probando con los ejemplos de la clase TSocket que trae FWH, pueden encontrar un ejemplo de server y otro de cliente, es muy facil de usar, el problema surge cuando tenes que interactuar con un server que no conoces y no tenes mucha ayuda como me paso a mi, por eso tuve que hacer lo del archivo de texto, no es muy elegante pero anda.
Esta es la solucion que yo encontre para mi caso particular, no significa que sea universal, disculpen que me extendi pero trate de ser lo mas claro posible. Espero sirva
Saludos.
Jorge G. Jaurena