Page 1 of 1

SOCKETS

Posted: Thu Oct 10, 2019 6:14 pm
by miarcod
Hola estoy haciendo unas pruebas para poner conectar una aplicación mediante el uso de sockets y me encuentro que cuando creo el socket en el cliente e intento realizar la conexión con el servidor pero el servidor no está iniciado
el sistema se queda colgado. y aunque se cierra la ventana del programa este sigue corriendo en memoria y tengo que cerrar el proceso desde el administrador de tareas
Sin embargo si el servidor esta ejecutandose todo funciona correctamente.

¿Como puedo verificar que el servidor se encuentra escuchando las peticiones en la ip y el puerto seleccionado?

En equipo corro un pequeño ejemplo para que actue como servidor

Code: Select all

#include "FiveWin.Ch"

STATIC oWnd, oSocket, oClient, oSay, cLog

//------------------------------------------------------------------------//
Function main(cModo)
   ModoServidor()
RETURN NIL

#DEFINE PUERTO      2019

#define ST_COMMAND  1
#define ST_SENDFILE 2
#define FILE_BLOCK 8000

//------------------------------------------------------------------------//
FUNCTION GetIpMaquina()
Local cIp

If WSAStartup() != 0
   MsgAlert( "WSAStartup error" )
endif
cIp :=  GetHostByName( GetHostName() )
WSACleanUp()
return cIp

//------------------------------------------------------------------------//
FUNCTION ModoServidor()
Local cTitle, oBtn

cLog := ""

DEFINE WINDOW oWnd TITLE cTitle

cTitle := "Servidor de Sockets "
cTitle += GetIPMaquina()
cTitle += ":" + NTRIM(PUERTO)

DEFINE WINDOW oWnd TITLE cTitle FROM 0, 0 TO 24, 80
@ 1,1 SAY oSay PROMPT cLog Size  600,300 BORDER
//@ 0,0 BUTTON oBtn PROMPT "pulsar" ACTION oSay:SetText("Hola")//Pulsado(oSay)

ACTIVATE WINDOW oWnd;
          ON INIT Iniciar() ;
          VALID Cerrar()

RETURN NIL
//------------------------------------------------------------------------//
STATIC FUNCTION Iniciar()
oWnd:Move(50,50)
Server()
RETURN .F.

//------------------------------------------------------------------------//
STATIC FUNCTION Cerrar()
oSocket:End()
sayLog("Cerrando servidor")
RETURN .T.

//------------------------------------------------------------------------//
STATIC FUNCTION SayLog(cValue)
cLog += cValue + CRLF
//Depura(cLog)
//Depura(oSay)
oSay:SetText(cLog)
RETURN NIL


//------------------------------------------------------------------------//
STATIC function Server()

   oSocket = TSocket():New( PUERTO )

   oSocket:bAccept = { | oSocket | oClient := TSocket():Accept( oSocket:nSocket ),;
                       oClient:Cargo := ST_COMMAND,;
                       oClient:bRead := { | oSocket | OnRead( oSocket ) },;
                       oClient:bClose := { | oSocket | OnClose( oSocket ) } }

   oSocket:Listen()
   SayLog("Servidor iniciado")
   SayLog("Esperando peticiones")

return nil


//------------------------------------------------------------------------//
STATIC function OnRead( oSocket )

   local cData := oSocket:GetData()
   local cToken, cRespuesta

   SayLog("Datos recibidos: " +  cData)

   If cData == "GET_SRV"
      SayLog("Solicitud de conexión recibida")
      oSocket:SendData(cData +  "_OK")
      RETURN NIL
   EndIf

   SayLog("Petición desconocida: " +  cData)

return nil

//------------------------------------------------------------------------//
STATIC function OnClose( oSocket )

   sayLog("El cliente ha cerado el socket")
   //MsgInfo( "Client has closed!" )
   oSocket:End()
return nil

 
Para realizar la conexión hago lo siguiente:

Code: Select all

...

STATIC FUNCTION Crearconexion()
   Local nRet

   SayLog("Creando socket contra la IP " + cIpSrv )

   oSocket = TSocket():New( nPuerto )
   oSocket:bRead    = { | oSocket | ProcesaRespuesta( oSocket ) }

   // Never use a MsgInfo() here because it hangs Windows!!!
   oSocket:bConnect = { || Depura( "Conectado") }
   oSocket:bClose   = { || SrvClose() }
   nRet := oSocket:Connect( cIpSrv ) // use the server IP address here
   Depura(nRet, "NRet")
   Depura(oSocket:nRetCode, "osocket:nRetcode")
   //ComprobarConexion()
   SayLog("Fin creando socket contra IP")

RETURN .F.


//------------------------------------------------------------------------//
STATIC FUNCTION Cerrar()
   SayLog("oSocket:Close()")
   If lConectado
      oSocket:Close()
      oSocket:End()
   Else
      SayLog("No estamos conectados")
   EndIf
   SayLog("socket cerrado. Esperndo 1 segundo")
   syswait(1)
RETURN .T.



STATIC FUNCTION ProcesaRespuesta( cRespuesta)
// Comprobando conexión
If oSocket:Cargo = "GET_SRV"
   If cRespuesta == oSocket:Cargo + "_OK"
      lConectado := .T.
      RETURN .T.
   EndIf
EndIf

RETURN NIL

 

Re: SOCKETS

Posted: Fri Oct 11, 2019 4:24 am
by Antonio Linares
Revisa los ejemplos sockserv.prg y sockcli.prg en FWH\samples

Re: SOCKETS

Posted: Fri Oct 11, 2019 6:04 am
by miarcod
Antonio, gracias por responder

He intentado ejecutar este ejemplo pero se produce un error de ejecución


Code: Select all

  Time from start: 0 hours 0 mins 1 secs 
   Error occurred at: 10/11/19, 08:00:59
   Error description: Error BASE/1004  No exported method: SENDDATA
   Args:
     [   1] = U   
     [   2] = C   Hello from server!

Stack Calls
===========
   Called from:  => SENDDATA( 0 )
   Called from: sockserv.prg => (b)MAIN( 23 )
   Called from: .\source\classes\BTNBMP.PRG => TBTNBMP:CLICK( 471 )
   Called from: .\source\classes\BTNBMP.PRG => TBTNBMP:LBUTTONUP( 662 )
   Called from: .\source\classes\CONTROL.PRG => TCONTROL:HANDLEEVENT( 1723 )
   Called from: .\source\classes\BTNBMP.PRG => TBTNBMP:HANDLEEVENT( 1465 )
   Called from: .\source\classes\WINDOW.PRG => _FWH( 3234 )
   Called from:  => WINRUN( 0 )
   Called from: .\source\classes\WINDOW.PRG => TWINDOW:ACTIVATE( 1003 )
   Called from: sockserv.prg => MAIN( 25 )
Ejecuto el programa, pulso en botón escuchar y al pulsar el botón para hablar con el cliente se produce este error

Re: SOCKETS

Posted: Fri Oct 11, 2019 10:40 am
by Antonio Linares
Que versión de FWH estás usando ?

Re: SOCKETS

Posted: Fri Oct 11, 2019 11:31 am
by miarcod
Fivewin Harbour 13.06

Re: SOCKETS

Posted: Fri Oct 11, 2019 5:13 pm
by Verhoven
En el método SendData( cData ) de la clase solucioné el problema con la siguiente modificación.

En la clase TSocket me ha dado un fallo que dejaba colgado el programa metido en un bucle infinito.
Esto ocurría al enviar datos cuando se perdía la conexión durante el proceso la conexión de red o el ordenador que hace de servidor estaba desconectado, lo que viene a ser lo mismo.

El posible error está en el método SenData, en concreto en la siguiente sección de código:

Code: Select all

if WSAGetLastError() != WSAEWOULDBLOCK
                // exit
             endif
Conviene descomentar la línea donde dice "//exit", o bien hacer una gestión del error en esa parte, si no se descomenta se puede quedar en un bucle sin fin, que es lo que te podría estar sucediendo.

Re: SOCKETS

Posted: Sat Oct 12, 2019 7:31 am
by miarcod
Gracias voy a probar

Re: SOCKETS

Posted: Sun Oct 13, 2019 5:36 pm
by thefull
Mi consejo es que si vas hacer un servidor y un cliente, olvides el tema de los sockets, y montate un servidor resfull, tu vida te lo agracederá :lol:

Re: SOCKETS

Posted: Mon Oct 21, 2019 6:36 pm
by miarcod
No se a que te refieres,
Podrías darme más información.

De momento he conseguido la comunicación contra un dispositivo ANDROID y el programa funciona correctamente. Pero el cliente ya está pensando en nuevas funcionalidades y a lo mejor me interesaría otra solución.
Un saludo.

Re: SOCKETS

Posted: Mon Oct 21, 2019 6:48 pm
by cnavarro

Re: SOCKETS

Posted: Mon Oct 21, 2019 7:04 pm
by miarcod
Gracias voy a ver los videos
Un saludo