La magia de los Sockets
- Busmatic_wpb
- Posts: 162
- Joined: Wed Feb 22, 2017 2:19 am
La magia de los Sockets
Estimados Listeros.
Gracias a mi amigo Venesolano Sr. Albeiro Valencia que me ha ayudado a desarrollar un aplicacion de coneccion por la clase sockets, al final trabajo de maravillas , le hemos metido mano a la clase se han hecho grandes cosas. Hemos logrado comunicarnos los equipos (coches) que tengo en carretera a un server estacionario en un 100% sin errores y comandos to envio de informarcion de los clientes al server grabando en tablas Mysql con Dolphin y trabaja de muy bien .
Tambien hemos logrado enviar comandos de Servidor a cliente y viceverza y la verdad he quedado atonito ver el poder rapidez con que esta cosa trabaja la clase.
Ya montamos un arreglo de clientes que nos ayuda a mandar mensajes o peticiociones de informacion a uno a todos clientes..
Hemos logrado enviar strings de mas de 100 caracteres y ni cuenta se da el programa TAkilla- cliente que esta montado en un table windows 10 con fivewin que se comporta al 100% , utilzamos un timer para cada minuto madar el string al servidor, les comento esto porque he visto mucho comentarios acerca de esta calse
y queria compartir mis impresiones.
Vean ustedes que bonito
Ejemplo sockets
Albeiro Valencia
albeiroval@gmail.com
_ Chacon.
http://www.busmaticcr.com
Ejemplo sockets
Ahore miren la informacion descargada por CLiente..
Gracias a mi amigo Venesolano Sr. Albeiro Valencia que me ha ayudado a desarrollar un aplicacion de coneccion por la clase sockets, al final trabajo de maravillas , le hemos metido mano a la clase se han hecho grandes cosas. Hemos logrado comunicarnos los equipos (coches) que tengo en carretera a un server estacionario en un 100% sin errores y comandos to envio de informarcion de los clientes al server grabando en tablas Mysql con Dolphin y trabaja de muy bien .
Tambien hemos logrado enviar comandos de Servidor a cliente y viceverza y la verdad he quedado atonito ver el poder rapidez con que esta cosa trabaja la clase.
Ya montamos un arreglo de clientes que nos ayuda a mandar mensajes o peticiociones de informacion a uno a todos clientes..
Hemos logrado enviar strings de mas de 100 caracteres y ni cuenta se da el programa TAkilla- cliente que esta montado en un table windows 10 con fivewin que se comporta al 100% , utilzamos un timer para cada minuto madar el string al servidor, les comento esto porque he visto mucho comentarios acerca de esta calse
y queria compartir mis impresiones.
Vean ustedes que bonito
Ejemplo sockets
Albeiro Valencia
albeiroval@gmail.com
_ Chacon.
http://www.busmaticcr.com
Ejemplo sockets
Ahore miren la informacion descargada por CLiente..
Last edited by Busmatic_wpb on Wed May 16, 2018 3:52 am, edited 3 times in total.
Regards.
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
- albeiroval
- Posts: 323
- Joined: Tue Oct 16, 2007 5:51 pm
- Location: Barquisimeto - Venezuela
Re: La magia de los Sockets
_,
Muchas gracias por tus palabras, para mi es un placer haber podido colaborar con este proyecto.
Muchas gracias por tus palabras, para mi es un placer haber podido colaborar con este proyecto.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: La magia de los Sockets
Estimados _ y Albeiro,
¿ Podríais publicar un ejemplo de cómo lo habéis hecho para ayudar a otros usuarios ?
Muchas gracias
¿ Podríais publicar un ejemplo de cómo lo habéis hecho para ayudar a otros usuarios ?
Muchas gracias
- jose_murugosa
- Posts: 943
- Joined: Mon Feb 06, 2006 4:28 pm
- Location: Uruguay
- Contact:
Re: La magia de los Sockets
Fascinante, lo que relatas lo es realmente, de verdad sería buenísimo que compartieras un ejemplo sobre como usas sockets con nosotros.
Saludos/Regards,
José Murugosa
FWH + Harbour + Bcc7. Una seda!
José Murugosa
FWH + Harbour + Bcc7. Una seda!
- Busmatic_wpb
- Posts: 162
- Joined: Wed Feb 22, 2017 2:19 am
Re: La magia de los Sockets
Saludes,
Con mucho gusto haremos una copia del desarrollo, del servidor de sockets y Cliente el compañero Albeiro, el hizo cambios sustanciales y mejoras para ajustarla a mis necesitades y ponerla andar. Les comento que esta rutina trabaja exelente libre de errores fue modificada de la rutina original de FW / Autor : Antonio Linares .
y prontamente se publicara al Server/Cliente con _ hechos y ajustes.
_ Chacon
http://www.SITU.com
Con mucho gusto haremos una copia del desarrollo, del servidor de sockets y Cliente el compañero Albeiro, el hizo cambios sustanciales y mejoras para ajustarla a mis necesitades y ponerla andar. Les comento que esta rutina trabaja exelente libre de errores fue modificada de la rutina original de FW / Autor : Antonio Linares .
y prontamente se publicara al Server/Cliente con _ hechos y ajustes.
_ Chacon
http://www.SITU.com
Last edited by Busmatic_wpb on Mon May 21, 2018 5:53 am, edited 5 times in total.
Regards.
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
Re: La magia de los Sockets
Gracias por el aporte a la comunidad.
Dios te bendiga.
Dios te bendiga.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: La magia de los Sockets
Estimado Albeiro,
Revisando el código de _, parece que el servidor es un trabajo derivativo del ejemplo sockserv.prg de FWH
¿ Podrías publicar _ y mejoras realizadas ?
gracias
Revisando el código de _, parece que el servidor es un trabajo derivativo del ejemplo sockserv.prg de FWH
¿ Podrías publicar _ y mejoras realizadas ?
gracias
- Busmatic_wpb
- Posts: 162
- Joined: Wed Feb 22, 2017 2:19 am
Re: La magia de los Sockets
Estimado Linares.
Con mucho gusto publicaremos socket server /cliente y sus modificaciones protamente apenas terminemos de hacer los ultimos ajustes segun me comunico el Sr. Valencia
_ Chacon.
Con mucho gusto publicaremos socket server /cliente y sus modificaciones protamente apenas terminemos de hacer los ultimos ajustes segun me comunico el Sr. Valencia
_ Chacon.
Last edited by Busmatic_wpb on Mon May 21, 2018 5:49 am, edited 1 time in total.
Regards.
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
- albeiroval
- Posts: 323
- Joined: Tue Oct 16, 2007 5:51 pm
- Location: Barquisimeto - Venezuela
Re: La magia de los Sockets
Estimado Antonio,
A continuacion agrego el codigo servidor y cliente para manejo de sockets que usa _ Chacon en su aplicacion de control
sistematizado de monitoreo de coches en tiempo real, el cual es una maravilla.
Codigo Server :
Codigo Cliente :
Tome como referencia los ejemplos de sockserv.prg y sockcli.prg de FWH.
A continuacion agrego el codigo servidor y cliente para manejo de sockets que usa _ Chacon en su aplicacion de control
sistematizado de monitoreo de coches en tiempo real, el cual es una maravilla.
Codigo Server :
Code: Select all
#include "FiveWin.ch"
#include "FileI.ch"
#include "TSocket.ch"
#include "C:\dolphin\include\tdolphin.ch"
#define ST_COMMAND 1
#define ST_SENDFILE 2
#define FILE_BLOCK 8000
//-------------------------------------------//
static h
static oSocket
static oClient
//-------------------------------------------//
Function Main2()
Local oBar
Local aConexion := { { 0, "S/N", "FECHA", "HORA" } }
h := Hash()
h["cFileTxt"] := "monitor_avl.txt"
h["lListen" ] := .F.
h["cTable" ] := "monitoravl"
h["aClient" ] := {}
SET DELETED ON
SET CASESENSITIVE ON
SET PADRIGHT ON
SET LOGICALVALUE ON
h["oSrv"] := TSituMySQL():New( "localhost", "root", "pampa36", "situ" )
if h["oSrv"]:lConnect
ValidaTabla( h["cTable"] )
endif
if !File( h["cFileTxt"] )
h["hFile"] := FCreate( h["cFileTxt"], FC_NORMAL )
endif
h["hFile"] := FOpen( h["cFileTxt"], FO_READWRITE + FO_SHARED )
DEFINE WINDOW h["oWnd"] TITLE "Servidor : "
@200,600 BTNBMP oBtn1 OF h["oWnd"] ;
SIZE 500,300 PIXEL ;
RESOURCE "#8002" ;
TOP NOBORDER
oBtn1:lTransparent = .t.
oBtn1:cToolTip = { "Busmatic de CR" + CRLF + "Ing: _ Chacon","Todos los derechos reservados "+str(year(date())), 1, CLR_BLACK, 14089979 }
oBtn1:SetColor( 0, )
DEFINE BUTTONBAR oBar OF h["oWnd"] 2015 SIZE 70, 70
DEFINE BUTTON OF oBar;
CENTER;
PROMPT "Conectar" ;
ACTION if(!h["lListen"], Server(), MsgStop("Server ya esta Activo") );
FILE "BMP\conecta.png";
TOOLTIP "Conectar"
DEFINE BUTTON OF oBar;
CENTER;
PROMPT "Send Data";
ACTION EnvioCom( );
FILE "BMP\todos.png";
TOOLTIP "Actulizar tarifas";
GROUP
DEFINE BUTTON OF oBar;
CENTER;
PROMPT "Send MSG";
ACTION EnvioMensa();
FILE "BMP\todosuser .png";
TOOLTIP "Enviar mensajes a todos ";
GROUP
DEFINE BUTTON OF oBar;
CENTER;
PROMPT "Desconecta";
ACTION ( OnClose( oSocket ), h["oWnd"]:End() );
TOOLTIP "Exit";
FILE "BMP\STOP.png";
GROUP
@ 6, 6 XBROWSE h["oBrw"] OF h["oWnd"];
DATASOURCE aConexion;
COLUMNS 1,2,3,4;
HEADERS "Id", "Placa", "Fecha", "Hora";
FOOTERS;
SIZE 360, 600
h["oBrw"]:nMarqueeStyle := MARQSTYLE_HIGHLROW
h["oBrw"]:nHeaderLines := 1
h["oBrw"]:lColDividerComplete := .T.
h["oBrw"]:cToolTip := 'Desglose de movimimientos'
h["oBrw"]:nColDividerStyle := 1
h["oBrw"]:lHScroll := .T.
h["oBrw"]:lfastedit := .f.
h["oBrw"]:lAllowRowSizing := .T.
h["oBrw"]:nHeaderLines := 1
h["oBrw"]:nFooterLines := 0
h["oBrw"]:nDataLines := 3
h["oBrw"]:lFooter := .f.
h["oBrw"]:nRowHeight :=30
h["oBrw"]:lFastEdit := .F.
h["oBrw"]:SetBackGround( "BMP\fondo2.png", BCK_FILL )
h["oBrw"]:lKinetic := .T.
h["oBrw"]:lContrastClr := .T. //para que no cambie color de texto automaticamente segun intensidad del fondo
h["oBrw"]:lColChangeNotify := .t. // bChange evalua cambio de columna y permite tomar una accion
h["oBrw"]:lCanPaste := .t. //copiar/pegar datos entre columnas
WITH OBJECT h["oBrw"]
:SetGroupHeader( ' ID ' + CRLF + 'Asigdos', 1,1 )
:SetGroupHeader( 'COCHES ' + CRLF + 'CONECTADOS',2,4)
END
WITH OBJECT h["oBrw"]
h["oBrw"]:aCols[ 1 ]:cHeader = "CONECTA"
h["oBrw"]:aCols[ 1 ]:nWidth = 60
h["oBrw"]:aCols[ 1 ]:nHeadStrAlign := AL_CENTER
h["oBrw"]:aCols[ 1 ]:nDataStrAlign := AL_CENTER
END
WITH OBJECT h["oBrw"]
h["oBrw"]:aCols[ 2 ]:cHeader = "Coche"
h["oBrw"]:aCols[ 2 ]:nWidth = 100
h["oBrw"]:aCols[ 2 ]:nHeadStrAlign := AL_CENTER
h["oBrw"]:aCols[ 2 ]:nDataStrAlign := AL_CENTER
END
WITH OBJECT h["oBrw"]
h["oBrw"]:aCols[ 3 ]:cHeader = "Fecha"
h["oBrw"]:aCols[ 3 ]:nWidth = 75
h["oBrw"]:aCols[ 3 ]:nHeadStrAlign := AL_CENTER
h["oBrw"]:aCols[ 3 ]:nDataStrAlign := AL_CENTER
END
WITH OBJECT h["oBrw"]
h["oBrw"]:aCols[ 4 ]:cHeader = "Hora"
h["oBrw"]:aCols[ 4 ]:nWidth = 100
h["oBrw"]:aCols[ 4 ]:nHeadStrAlign := AL_CENTER
h["oBrw"]:aCols[ 4 ]:nDataStrAlign := AL_CENTER
END
h["oBrw"]:CreateFromCode()
ACTIVATE WINDOW h["oWnd"] ;
MAXIMIZED;
ON INIT Server()
FClose( h["hFile"] )
h["oSrv"]:Close()
Return Nil
//-------------------------------------------//
static Function Server()
if oSocket != NIL
oSocket:End()
endif
oSocket = TSocket():New( TSOCK_SRV, 5000, "soc2serv.ini" )
oSocket:bAccept = ;
<| oSocket |
oClient := TSocket():Accept( oSocket:nSocket )
AAdd( h["aClient"], oClient:nSocket )
oClient:Cargo := ST_COMMAND
oClient:bRead := { | oSocket | OnRead( oSocket ) }
oClient:bClose := { | oSocket | OnClose( oSocket ) }
oClient:SendData( "ok" )
Return Nil
>
oSocket:Listen()
h["oWnd"]:SetText( "Servidor : (" + oSocket:cIPAddr + ")" )
h["lListen"] := .T.
Return Nil
//-------------------------------------------//
static Function OnRead( oSocket )
Local aSockServ
Local cToken
Local aFirstName
Local aSecondName
Local aAliasName
Local cName
Local cSSNome
Local cMsg
Local cData := oSocket:GetData()
do case
case oSocket:Cargo == ST_COMMAND
cToken = StrToken( cData, 1 )
do case
case cToken == "SEND-BRW"
cMsg := SubStr( cData, 10 )
UpdateBrowse( cMsg )
case cToken == "SENDCMD"
if "QUIT" $ SubStr( cData, 8 )
LogFile( "socket_server.txt", "Close Server !!!" )
MsgWait( "Close Server !!!" )
h["oWnd"]:End()
endif
case cToken == "MSG"
cMsg := SubStr( cData, 5 )
AddLineMonitor( cData )
// MsgRun( cMsg )
endcase
case oSocket:Cargo == ST_SENDFILE
fwrite( oSocket:h["hFile"], cData, Len( cData ) )
LogFile( "socket_server.txt", { "writting..." } )
if Len( cData ) < FILE_BLOCK
// fclose( oSocket:h["hFile"] )
// MsgInfo( Len( cData ) )
// oSocket:Cargo = ST_COMMAND
endif
endcase
Return Nil
//-------------------------------------------//
static Function OnClose( oSocket )
// MsgRun( "Client has closed!" )
// ? oSocket:nSocket
if oSocket != Nil
DeleteItem( oSocket:nSocket )
do case
case oSocket:Cargo == ST_SENDFILE
fclose( oSocket:h["hFile"] )
endcase
oSocket:End()
endif
Return Nil
//-------------------------------------------//
static Function AddLineMonitor( cTexto )
Local o := TFBuffer():new( h["hFile"] )
o:addString( cTexto )
o:free()
Desglose( cTexto)
Return Nil
//-------------------------------------------//
Function Desglose(cTexto)
Local dOpusuario := substr(cTexto,5,4)
Local dFecha := substr(cTexto,9,10)
Local dHora := substr(cTexto,19,8)
Local dPlacas := substr(cTexto,27,13)
Local dchoferNom := substr(cTexto,40,13)
Local dultParada := substr(cTexto,53,25)
Local dlati := substr(cTexto,78,14)
Local dlong := substr(cTexto,92,14)
Local dSpeed := VAL(substr(cTexto,106,6))
Local dSindescar := VAL(substr(cTexto,112,5))
Local INI001 := AT("£",cTexto)
Local INI002 := AT("Ø",cTexto)-1
Local INI003 := AT("ƒ",cTexto)
Local INI004 := AT("á",cTexto)-1
Local dInter := substr(cTexto,INI001+1,abs(INI001-INI002))
Local dExter := substr(cTexto,INI003+1,abs(INI003-INI004))
Local Data13 := ""
Local INI005:=AT("¦",cTexto)-1
Local dvsw :=substr(cTexto,INI005+2,9)
Local INI006 := AT("¢",cTexto)-1
Local dtarver:= substr(cTexto,INI006+2,19)
Local INI0016:=AT("§",cTexto)
Local dbarras:= substr(cTexto,INI0016+1,1)
Local INI0017:=AT("³",cTexto)
Local dgps:= substr(cTexto,INI0017+1,1)
Local INI0018:=AT("¨",cTexto)
Local Lsc:= substr(cTexto,INI0018+1,1)
Local INI0019:=AT("²",cTexto)
Local EstMaq:= substr(cTexto,INI0019+1,2)
Local INI0020:=AT("å",cTexto)
Local Estqui:= substr(cTexto,INI0020+1,2)
Local INI0020a:=AT("|",cTexto)
LocaL INI0021:=substr(cTexto,INI0020a+1,2)
Local Lineas:=substr(cTexto,INI0020a+3,val(INI0021))
Local INI0022:=AT("Ô",cTexto)
Local Sent:= substr(cTexto,INI0022+1,3)
Local INI0023:=AT("Ç",cTexto)
Local Horas:= substr(cTexto,INI0023+1,5)
Local NueVPa:=alltrim( STRTRAN(dultParada, "0", " "))
Local Nuevapla:=alltrim( STRTRAN(dPlacas, "0", " "))
aColumnas := {"placa", "chofer", "versionsw", "latitud", "longitud", "barras", "gps", "lector", "ultimaparada", "speed", ;
"estadocomdo", "estadoequipo", "carrerasopen", "mensajes", "horaservicio",;
"lineaservicio", "sentidoservicio", "pasajeroservicio", "fecha", "hora", "carreraspend", "iplocal", "ipext", "versiontar" }
aValues := { Nuevapla,dOpusuario,dvsw,dlati,dLong, dbarras,dgps, Lsc, NueVPa,dSpeed, EstMaq,Estqui,0,"mens", Horas,Lineas,Sent,;
0,date() ,dhora ,dSindescar, dInter,dExter, dtarver}
LoadServer( aColumnas, aValues, h["cTable"] )
UpdateBrowse( Nuevapla )
return nil
//-------------------------------------------//
Function LoadServer(aColumnas, aValues,cTable)
if h["oSrv"]:lConnect
h["oSrv"]:InsertRow( cTable, aColumnas, aValues )
endif
return NIl
//-------------------------------------------//
static Function ValidaTabla( cTable )
Local cStruct
TEXT INTO cStruct
CREATE TABLE IF NOT EXISTS %1
( placa CHAR(13) default ' ' ,
chofer CHAR(13) default ' ' ,
versionsw CHAR(13) default ' ' ,
latitud CHAR(15) ,
longitud CHAR(15) ,
barras CHAR(1) ,
gps CHAR(1) ,
lector CHAR(1) ,
ultimaparada CHAR(25) ,
speed DECIMAL(5,2) ,
estadocomdo CHAR(3) ,
estadoequipo CHAR(3) ,
carrerasopen INT ,
mensajes TEXT ,
horaservicio CHAR(5) ,
lineaservicio CHAR(25) ,
sentidoservicio CHAR(3) ,
pasajeroservicio CHAR(5) ,
fecha DATE ,
hora CHAR(10) ,
carreraspend INT ,
iplocal CHAR(15) ,
ipext CHAR(15) ,
versiontar CHAR(20) ,
versiontsw CHAR(20) ,
auto INT NOT NULL AUTO_INCREMENT,
INDEX (placa, chofer ),
PRIMARY KEY (auto)
) COLLATE = 'latin1_spanish_ci' ENGINE = InnoDB
ENDTEXT
// latin1_spanish_ci
// CASE SENSITIVE (diferencia entre mayuscula y minisculas)
// CASE INSENSITIVE (no diferencia)
cStruct := StrFormat( cStruct, cTable )
h["oSrv"]:VerifyTable( cTable, cStruct )
Return Nil
//-------------------------------------------//
static Function UpdateBrowse( cData )
Local aArray := h["oBrw"]:aArrayData
Local nIdClien := ATail( h["aClient"] )
Local nPos
nPos := AScan( aArray, {|a| a[1] == nIdClien } )
If nPos==0
AAdd( aArray, { nIdClien, cData, Date(), Time() } )
h["oBrw"]:SetArray( aArray )
h["oBrw"]:Refresh()
endif
return Nil
//-------------------------------------------//
static Function DeleteItem( nIdClien )
Local nPos
Local aArray := h["oBrw"]:aArrayData
nPos := AScan( aArray, {|a| a[1] == nIdClien } )
if nPos > 0
ADel( aArray, nPos, .T. )
// MsgInfo("Registro Borrado")
endif
h["oBrw"]:SetArray( aArray )
h["oBrw"]:Refresh()
return Nil
//-------------------------------------------//
Static Function EnvioCom()
Local comandos:="COM:DESTAR"
oClient:SendData( comandos )
return NIl
//-------------------------------------------//
static Function EnvioMensa()
Local cCmdStr := Space(40)
Local comandos:="COM:MENSA"
MsgGet( "Mensaje", "Enviar : ", @cCmdStr )
if !Empty( cCmdStr )
Mensaje:= comandos+cCmdStr
oClient:SendData(Mensaje )
endif
Return Nil
Code: Select all
#include "FiveWin.ch"
#include "TSocket.ch"
#define ST_COMMAND 1
#define ST_SENDFILE 2
#define FILE_BLOCK 8000
static oSocket
//-----------------------------------------//
Function MainSocket()
if oSocket != NIL
oSocket:End()
endif
oSocket = TSocket():New( TSOCK_CLI, 5000, "soc2cli.ini" )
oSocket:bRead = { | oSocket | HandleRecived( oSocket ) }
// oSocket:bConnect = { || MsgInfo( "Conectado !!!" ) ) }
// oSocket:bClose = { || MsgInfo( "Servidor Inactivo !!!" ) }
oSocket:Connect()
Return Nil
//-------------------------------------------//
static Function HandleRecived( oSocket )
Local cData := oSocket:GetData()
if cData = "ok"
LogFile( "socket_server.txt", "Connected !!" )
else
// MSGWait("No conecto server Fail",1)
// LogFile( "socket_server.txt", "Fallo coneccion "+ cData )
// Return nil
endif
If alltrim(cData)=="COM:DESTAR"
// revisar el estado de las tarifas en el server local
FuerzaTarifas()
elseif substr(cData,1,9) =="COM:MENSA"
SndPlaySound(".\SOUND\mensaje01.WAV")
GrabarMEnsajes(cData)
elseif alltrim(cData)==""
elseif alltrim(cData)==""
Endif
Return nil
//-------------------------------------------//
Function SendMsg(cMsg)
Local lSucess :=.T.
// Local cMsg := Space(40)
// MsgGet( "Send Message", "Message : ", @cMsg )
if !Empty( cMsg )
oSocket:SendData( "MSG " + cMsg )
endif
Return lSucess
Last edited by albeiroval on Mon May 21, 2018 2:41 pm, edited 1 time in total.
- Busmatic_wpb
- Posts: 162
- Joined: Wed Feb 22, 2017 2:19 am
Re: La magia de los Sockets
Muchas gracias compañero Albiero Valencia
Se le agaracede por sus aportes , te comento que la implentacion fue cero errores , muy eficiente y rapido, muchas gracias.
Atentamente.
_ Chacon.
www.Situ.com
Se le agaracede por sus aportes , te comento que la implentacion fue cero errores , muy eficiente y rapido, muchas gracias.
Atentamente.
_ Chacon.
www.Situ.com
Regards.
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: La magia de los Sockets
Otro ejemplo distinto de uso de Sockets ( una curiosidad ), basado también el los ejemplos de samples
En este caso, envías desde el servidor la informacion necesaria para crear en el cliente una ventana que tenemos pintada en el servidor.
Lógicamente, es un primer paso, ya que para poder implementar el pintado de los controles, etc, el tema se complica, teniendo que hacer uso para mejor implementación, de multihilos y sobre todo de mutex ( para proteger los valores de datas y variables, y poder realizar el pintado de la ventana convenientemente, bueno, asi es como lo entiendo yo ), pero quizás lo encontréis "curioso".
El array aOrders, lo que contiene, es el número de orden que tiene esa DATA en el array aDatas, o el valor que ha de tener el parámetro que he de pasar al método New de TWindow ( para entenderlo quizás mejor, ejecuta la instrucción Xbrowse( aDatas ) que aparece comentada y mira la definición del método New en la clase TWindow, aunque se me han ocurrido otras formas de hacerlo
Si alguien lo encuentra interesante y se anima, pues podemos seguir desarrollando cosillas
Funcionamiento:
1.- Ejecutar el programa servidor y pulsar sobre "Listen"
2.- Ejecutar el programa cliente y pulsar sobre "Connect"
3.- Puedes pulsar en ambos sobre los botones "Send" en el servidor "Test Msg" en el cliente para comprobar que están conectados
4.- Pulsar en el cliente sobre "Request Window", y aparecerá un mensaje en el servidor que enviará la información al cliente en el que se pintará la ventana.
Ahora el cliente
En este caso, envías desde el servidor la informacion necesaria para crear en el cliente una ventana que tenemos pintada en el servidor.
Lógicamente, es un primer paso, ya que para poder implementar el pintado de los controles, etc, el tema se complica, teniendo que hacer uso para mejor implementación, de multihilos y sobre todo de mutex ( para proteger los valores de datas y variables, y poder realizar el pintado de la ventana convenientemente, bueno, asi es como lo entiendo yo ), pero quizás lo encontréis "curioso".
El array aOrders, lo que contiene, es el número de orden que tiene esa DATA en el array aDatas, o el valor que ha de tener el parámetro que he de pasar al método New de TWindow ( para entenderlo quizás mejor, ejecuta la instrucción Xbrowse( aDatas ) que aparece comentada y mira la definición del método New en la clase TWindow, aunque se me han ocurrido otras formas de hacerlo
Si alguien lo encuentra interesante y se anima, pues podemos seguir desarrollando cosillas
Funcionamiento:
1.- Ejecutar el programa servidor y pulsar sobre "Listen"
2.- Ejecutar el programa cliente y pulsar sobre "Connect"
3.- Puedes pulsar en ambos sobre los botones "Send" en el servidor "Test Msg" en el cliente para comprobar que están conectados
4.- Pulsar en el cliente sobre "Request Window", y aparecerá un mensaje en el servidor que enviará la información al cliente en el que se pintará la ventana.
Code: Select all
// Socket server connection sample
#include "FiveWin.ch"
#define ST_COMMAND 1
#define ST_SENDFILE 2
#define FILE_BLOCK 8000
static oWnd, oSocket, oClient
Static aDatas
static aSockets
static aClients
static aPorts
//------------------------------------------------------------------------//
function Main()
local oBar
aPorts := { 2000 }
aSockets := Array( Len( aPorts ) )
aClients := Array( Len( aPorts ) )
DEFINE WINDOW oWnd TITLE "Server Socket"
DEFINE BUTTONBAR oBar OF oWnd SIZE 60, 32
DEFINE BUTTON OF oBar PROMPT "Listen" ACTION Server() TOOLTIP "Listen" GROUP ;
WHEN Hb_IsNil( oSocket )
DEFINE BUTTON OF oBar PROMPT "Send" ACTION oClient:SendData( "Hello!" ) ;
TOOLTIP "Talk to client" GROUP
DEFINE BUTTON OF oBar PROMPT "Close" ACTION Cierra() TOOLTIP "Cierra" GROUP
ACTIVATE WINDOW oWnd
return nil
//------------------------------------------------------------------------//
function Server()
local x
oSocket = TSocket():New( 2000 )
oSocket:bAccept = { | oSock | oClient := TSocket():Accept( oSocket:nSocket ),;
oClient:Cargo := ST_COMMAND,;
oClient:bRead := { | oSock | OnRead( oSock ) },;
oClient:bClose := { | oSock | OnClose( oSock ) } }
oSocket:Listen()
return nil
//------------------------------------------------------------------------//
Function Cierra()
oSocket:End()
Return nil
//----------------------------------------------------------------------------//
function OnRead( oSocket )
local cData := oSocket:GetData()
local cToken
LogFile( "sockserv.txt", { Len( cData ), cData } )
do case
case oSocket:Cargo == ST_COMMAND
cToken = StrToken( cData, 1 )
do case
case cToken == "TWINDOW:"
? "Sending TWindow"
oClient:SendData( "TWINDOW|" + MyDatas( oWnd ) )
case cToken == "SENDFILE"
oSocket:Cargo = ST_SENDFILE
oSocket:hFile = fcreate( StrToken( cData, 2 ) )
case cToken == "MSG"
MsgInfo( SubStr( cData, 5 ) )
endcase
case oSocket:Cargo == ST_SENDFILE
fwrite( oSocket:hFile, cData, Len( cData ) )
LogFile( "sockserv.txt", { "writting..." } )
if Len( cData ) < FILE_BLOCK
// fclose( oSocket:hFile )
// MsgInfo( Len( cData ) )
// oSocket:Cargo = ST_COMMAND
endif
endcase
return nil
//------------------------------------------------------------------------//
function OnClose( oSocket )
MsgInfo( "Client has closed!" )
do case
case oSocket:Cargo == ST_SENDFILE
fclose( oSocket:hFile )
endcase
oSocket:End()
return nil
//------------------------------------------------------------------------//
Function MyDatas( oObj )
local aOrders
local aEnvio := {}
local x
local cVar
local nPosV := 0
local cCad := ""
local aDatas
local cClase := ""
cClase := oObj:ClassName()
aDatas := MObjData( oOBj, .T. )
aOrders := { 106, 96, 86, 102, 61, 104, 120, 110, 117, 135, nil, nil, 90, 89, ;
113, nil, nil, nil, nil, nil, .T., 91, 63, 93, 81 }
//XBrowse( aDatas )
For x = 1 to Len( aOrders )
if hb_IsNil( aOrders[ x ] )
AAdd( aEnvio, nil )
else
if Valtype( aOrders[ x ] ) == "N"
AAdd( aEnvio, aDatas[ aOrders[ x ] ][ 3 ] )
else
AAdd( aEnvio, aOrders[ x ] )
endif
endif
cCad += cValToStr( ATail( aEnvio ) ) + if( x < Len( aOrders ), "|", "" )
Next x
Return cCad
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
// From XBrowse function
//----------------------------------------------------------------------------//
Function MObjData( oObj, lValues )
local n, v
local aData := AOData( oObj )
DEFAULT lValues := .T.
for n := 1 to Len( aData )
TRY
v := OSend( oObj, aData[ n ] )
CATCH
v := '<protected>'
END
if lValues
aData[ n ] := Lower( Left( aData[ n ], 1 ) ) + ;
SubStr( aData[ n ], 2 , 1 ) + ;
Lower( SubStr( aData[ n ], 3 ) )
aData[ n ] := { n, aData[ n ], v }
endif
next n
return aData
//----------------------------------------------------------------------------//
Code: Select all
// Client: Socket server connection sample
#include "FiveWin.ch"
static oWnd, oSocket
function Main()
local oBar
DEFINE WINDOW oWnd TITLE "Client socket"
DEFINE BUTTONBAR oBar OF oWnd SIZE 60, 32
DEFINE BUTTON OF oBar PROMPT "Connect" GROUP ACTION Client() TOOLTIP "Connect" ;
WHEN Hb_IsNil( oSocket )
DEFINE BUTTON OF oBar PROMPT "Msg Test" GROUP ;
ACTION oSocket:SendData( "MSG This is a test" ) ;
TOOLTIP "Send data"
DEFINE BUTTON OF oBar PROMPT "Request Window" GROUP ;
ACTION ( oSocket:SendData( "TWINDOW: " ) ) ;
TOOLTIP "Request Window"
//DEFINE BUTTON OF oBar GROUP ;
// ACTION SendFile() TOOLTIP "Send file"
DEFINE BUTTON OF oBar PROMPT "Close" GROUP ;
ACTION oSocket:End() TOOLTIP "End Socket"
ACTIVATE WINDOW oWnd
return nil
function Client()
oSocket = TSocket():New( 2000 )
oSocket:bRead = { | oSocket | GetMsgFromServer( oSocket ) }
// Never use a MsgInfo() here because it hangs Windows!!!
oSocket:bConnect = { || oWnd:SetText( "Connected!" ) }
oSocket:bClose = { || MsgInfo( "Server has closed!" ) }
oSocket:Connect( "127.0.0.1" ) // use the server IP address here
//oSocket:Connect( "192.168.1.10" ) // Internal IP
//oSocket:Connect( "85.52.108.210" ) // External/Public IP
return nil
//----------------------------------------------------------------------------//
Function GetMsgFromServer( oSocket )
Local cCad := ""
Local aEnvio := {}
Local cVar
Local nPosV
Local cClase := ""
Local x
cCad := oSocket:GetData()
if !Empty( At( "|", cCad ) )
aEnvio := hb_ATokens( cCad, "|" )
cClase := AllTrim( aEnvio[ 1 ] )
aEnvio := ADel( aEnvio, 1 )
aEnvio := ASize( aEnvio, Len( aEnvio ) - 1 )
cVar := aEnvio[ 23 ]
For x = 1 to Len( aEnvio )
aEnvio[ x ] := if( !hb_IsNil( aEnvio[ x ] ), AllTrim( aEnvio[ x ] ), nil )
aEnvio[ x ] := if( !hb_IsNil( aEnvio[ x ] ) .and. ( Asc( Left( aEnvio[ x ], 1 ) ) >= 48 .and. ;
Asc( Left( aEnvio[ x ], 1 ) ) <= 57 ), Val( aEnvio[ x ] ), aEnvio[ x ] )
if !hb_IsNil( aEnvio[ x ] ) .and. Valtype( aEnvio[ x ] ) == "C"
if !( "TBRUSH" $ aEnvio[ x ] ) .and. !( "TMENU" $ aEnvio[ x ] ) .and. ;
!( "TMENU" $ aEnvio[ x ] )
if aEnvio[ x ] == ".T."
aEnvio[ x ] := .T.
else
if aEnvio[ x ] == ".F."
aEnvio[ x ] := .F.
endif
endif
if Valtype( aEnvio[ x ] ) != "L" .and. Empty( aEnvio[ x ] )
aEnvio[ x ] := nil
endif
else
aEnvio[ x ] := nil
endif
endif
Next x
hb_ExecFromArray( &( cVar ) := &( cClase )(), "New", aEnvio )
Do Case
Case cClase == "TWINDOW"
ACTIVATE WINDOW &cVar
EndCase
else
MsgInfo( cCad )
endif
Return nil
//----------------------------------------------------------------------------//
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
- ruben Dario
- Posts: 986
- Joined: Thu Sep 27, 2007 3:47 pm
- Location: Colombia
Re: La magia de los Sockets
Excelente Trabajo, cada dia se aprende mas.
Segun el Ejemplo
cuando haces la conexion la clase que usas TSituMySQL() es de Tdolphin
h["oSrv"] := TSituMySQL():New( "localhost", "root", "pampa36", "situ" )
Gracias
Segun el Ejemplo
cuando haces la conexion la clase que usas TSituMySQL() es de Tdolphin
h["oSrv"] := TSituMySQL():New( "localhost", "root", "pampa36", "situ" )
Gracias
- Busmatic_wpb
- Posts: 162
- Joined: Wed Feb 22, 2017 2:19 am
Re: La magia de los Sockets
Estimado Ruben,
Si esta clase me ayudo a desarrollarla Alberio Valencia para facilitarme la coneccion al MYSQL es hererada TDolphy te comento que trabaja de perillas.
_ Chacon.
http://www.Situ.com
Si esta clase me ayudo a desarrollarla Alberio Valencia para facilitarme la coneccion al MYSQL es hererada TDolphy te comento que trabaja de perillas.
_ Chacon.
http://www.Situ.com
Regards.
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
S.I.T.U.
Sistemas Inteligentes de transporte urbano
http://www.situcr.com
_@Situcr.com
Desarrollos BA4/B4j androide
Re: La magia de los Sockets
El problema de usar la clase sockets, es que va a través de un contexto de ventana, usando la que viene con FW.
Mi opinión es que montando un simple servidor restful y peticiones http, es más robusto y más simple que usar sockets, y una
razón sencilla es el uso de threads y lo puedes montar como un servicio, y ya lo tienes todo completito.
Ala, ya tienes tema para investigar
Mi opinión es que montando un simple servidor restful y peticiones http, es más robusto y más simple que usar sockets, y una
razón sencilla es el uso de threads y lo puedes montar como un servicio, y ya lo tienes todo completito.
Ala, ya tienes tema para investigar
Saludos
Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)