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.
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
Tome como referencia los ejemplos de sockserv.prg y sockcli.prg de FWH.