Visual FoxPro Como Cliente en Internet

14

Click here to load reader

Transcript of Visual FoxPro Como Cliente en Internet

Page 1: Visual FoxPro Como Cliente en Internet

Visual FoxPro como cliente en Internet (I): Dial-Up Networking

Por Pablo Almunia© Copyrights 1997 by FoxPress, All rights reserved FoxPress, Junio 1997

Introducción

Con este artículo empezamos una serie sobre cómo Visual FoxPro puede ser un cliente de los distintos servicios de Internet e intentaremos mostrar cómo podemos contruir una aplicación elegantemente integrada con la red de redes. En los próximos artículos veremos como recibir o enviar ficheros por FTP, como manejar los visualizadores HTML o como comunicar dos aplicaciones por medio de Internet.

Para empezar nos centraremos en como podemos arrancar y manejar un acceso a Internet desde Visual FoxPro, es decir, como podemos arrancar un Dial-Up Networking (Acceso Telefónico a Redes) de Windows 95 y Windows NT para comunicarnos con un proveedor de acceso a Internet.

Una aplicación elegante no presupone que existe una conexión permantente con Internet y pregunta amablemente, si es necesario, qué configuración de conexión a Internet puede utilizar y si puede abrir una conexión con ella. No existe peor aplicación que la que hace que tu modem se dispare a llamar sin saber qué está pasando.

¿Cómo acceder a Internet?

Para acceder desde un puesto Windows 95 o Windows NT a Internet tenemos dos opciones diferentes: acceder directamente desde el puesto por medio de un Dial-Up Networking y un modem o tarjeta RDSI o acceder por medio de la red local y un Router o un Proxy que se conecta a la Internet.

Cuando un Proxy o un Router conectado a nuestra red local detecta que existe un paquete TCP/IP dirigido a una red diferente a la red local encamina ese paquete a la Internet. La conexión del Proxy o Router a Internet puede ser permanente, pero también puede hacer uso de un sistema de Dial-Up por lo que se realizará una conexión con un proveedor de acceso cuando se realice una petición y desconectará cuando se produzca un determinado tiempo de inactividad.

En caso de tener nuestro puesto configurado para realizar el acceso por medio de un Proxy o Router nuestra aplicación Visual FoxPro sólo tendrá que hacer uso de un protocolo Internet como FTP o HTTP configurado para hacer uso del Proxy o Router y los paquetes TCP/IP serán encaminados a la Internet de forma trasparente para nuestra aplicación.

Si por el contrario el acceso a Internet se realiza directamente con Dial-Up Networking desde el puesto Windows 95 o Windows NT por medio de un modem o una tarjeta RDSI, la aplicación requiere que esa conexión se realice antes que sea posible utilizar un servicio por medio de Internet.

Esta conexión con Internet puede establecerla manualmente el usuario, o establecerse automáticamente cuando realizamos una petición TCP/IP a una red externa, pero en mi

Page 2: Visual FoxPro Como Cliente en Internet

opinión es más elegante que la aplicación realice la conexión por si misma, si así lo configura el usuario.

Por otra parte, el sistema de Dial-Up Networking, que aquí vamos a describir, no sólo se utiliza para realizar una conexión a Internet. Con este mecanismo podemos conectarnos a otros ordenadores o a otras redes que dispongan de un servidor de Remote Access Service (RAS). Cualquier puesto Windows 95 o Windows NT puede ser un servidor de RAS si dispone de un modem o tarjeta RDSI y nosotros configuramos el servicio, siendo una buena solución para conectarnos a la red de la oficina desde casa.

Veremos cómo se puede manejar el Dial-Up Networking desde Visual FoxPro, ya sea para conectarse a Internet como para conectarse a un puesto o red remota, pero no vamos a explicar como configurar estos servicios. Le recomendamos se dirija a la Knowledge Base de Microsoft donde existen excelente artículos sobre la configuración de Proxys, Routers y Dial-Up Networking.

Arrancar el Dial-Up Networking

La primera aproximación al manejo del Dial-Up Networking es muy simple: arrancar una conexión del Dial-Up Networking por medio de ordenes del sistema operativo.

En Windows 95 y Windows NT utilizaremos técnicas distintas, estos dos sistemas se diferencia bastante en el uso de los del Dial-Up Networking y deberemos ver cada caso por separado.

Para saber en qué sistema operativo nos encontramos podemos hacer uso de la orden OS() de Visual FoxPro.

Windows 95

Si utilizamos Windows 95 podemos utilizar un programa del sistema llamado RunDLL32 que permite hacer una llamada a una función de una DLL. Con este programa llamaremos a la función RnaDial de la librería Rnaui.dll pasando como parámetro el nombre de la conexión del Dial-Up Networing que hayamos configurado con anterioridad.

En Visual FoxPro escribiríamos algo parecido a esto:

RUN /N Rundll Rnaui.dll,RnaDial Conexion1

En este caso estamos llamando a una conexión llamada Conexion1. Debemos escribir el nombre de la función exactamente igual, con mayúsculas y minúsculas para que funcione correctamente.

Windows NT

Si utilizamos Windows NT el sistema es muy similar, pero en este caso llamaremos a un programa del sistema directamente, este programa se llama RASDIAL.EXE. Le pasaremos como parámetro el nombre de la conexión del Dial-Networing que hayamos configurado con anterioridad.

En Visual FoxPro escribiríamos algo parecido a esto:

Page 3: Visual FoxPro Como Cliente en Internet

RUN /N RASDIAL conexion1

Esta orden permite pasar también como parámetros el nombre del usuario y la password y de esta forma evitar tener que guardarlos en la configuración de la conexión.

Evitar que salga el cuadro de diálogo

Cuando llamamos por cualquiera de los medios anteriores aparece un cuadro de diálogo con los datos de la configuración y preguntando si queremos conectar. Para evitar que aparezca ese cuadro de diálogo debemos configurar el Dial-Up Networking.

En Windows NT simplemente debemos guardar la password de la conexión y de esta forma no nos aparecerá ningún cuadro de diálogo.

En Windows 95 es un poco más complicado, pero también es posible. Debemos instalar un versión más moderna del Dial-Up Networking de la que trae por defecto el sistema. Para ello podemos obtener el fichero MSISDN11.EXE del Web de Microsoft que trae el soporte para tarjetas RDSI y la versión actualizada del Dial-Up Networking (no es necesario tener una tarjeta RDSI para instalar este complemento).

Una vez instalada la nueva versión del Dial-Up Networking podemos ir a la opción settings del mismo e indicar que no aparezca el cuadro de diálogo anterior y posterior a la conexión:

 

Si nuestra conexión requiere usuario y password debemos realizar, de forma similar a Windows NT, una conexión donde guardemos esa configuración:

 

El API del RAS

Con el sistema anterior tenemos muchas limitaciones: no podemos saber si ha funcionado correctamente la conexión, no podemos mostrar las distintas configuraciones en un cuadro de dialogo creado por nosotros para que el usuario pueda elegir cual utilizar, no podemos colgar la llamada, etc. Para realizar este tipo de operaciones debemos hacer uso del API del Remote Access Service (RAS).

Page 4: Visual FoxPro Como Cliente en Internet

Todos los ejemplos los hemos construido para Windows 95 y Windows NT 4. El API de RAS está disponible para Windows NT 3.51 y para Windows 3.x, pero las funciones, parámetros y estructuras cambian en algunas ocasiones y sería necesaria una adaptación de los ejemplos que aquí vamos a mostrar.

Obtener las entradas en la configuración del Dial-Up Networking

En primer lugar vamos a ver como podemos obtener una lista con todas las configuraciones del Dial-Up Networking configurados para este equipo. Para ello vamos a utilizar la siguiente función:

DECLARE INTEGER RasEnumEntries ;IN RASAPI32.DLL ;INTEGER reserved,;STRING PhoneBox,;STRING @ RasEntryName,;INTEGER @ SizeOfRasEntryName,;INTEGER @ Entries

Esta función tiene un primer parametro reservado, en el que pondremos un 0. Luego necesita una cadena con la dirección del phonebook. Windows NT 4 dispone de la posibilidad de tener varios un phonebook con posibles conexiones, Windows 95 guarda todas las conexiones en el Registry. Si estamos en Windows 95 o queremos utilizar el phonebook por defecto del sistema utilizaremos una cadena vacia.

Luego necesita una matriz de estructuras de tipo RASENTRYNAME. En este punto tenemos algunas dificultades desde Visual FoxPro, pues no es capaz de generar tipos de datos en forma de estructura y debemos utilizar un buffer del suficiente tamaño como para contener la estructura y luego obtener cada uno de los elementos por su posición dentro de este buffer.

Por último es necesario pasar el tamaño total de la matriz de estructuras y una variable donde almacenará el número de entradas del phonebook que se han incluido dentro de la matriz de estructuras.

Como ejemplo hemos incluido esta función dentro de un programa que requiere una cadena con el nombre de una matriz donde se almacenarán las entradas que se encuentren en la configuración del Dial-Up Networking.

************************************************ Construye una matriz con todas las*** entradas del phonebook*********************************************LPARAMETER cArrayReturn

LOCAL cStructRasEntryNameLOCAL cStructRasEntryNames, nSizeLOCAL nEntries, nResult, cRasEntryName

*** Definición de la constantes necesarias#DEFINE RAS_MAXENTRYNAME 256

Page 5: Visual FoxPro Como Cliente en Internet

*** Declaración de las funciones del APIDECLARE INTEGER RasEnumEntries ;

IN RASAPI32.DLL ;INTEGER reserved,;STRING PhoneBox,;STRING @ RasEntryName,;INTEGER @ SizeOfRasEntryName,;INTEGER @ Entries

*** Creación de una estructura tipo*** RASENTRYNAMEcStructRasEntryName = wordtoc(264) ;+ REPLICATE( CHR(0), RAS_MAXENTRYNAME )

*** Creación de una matriz con esa *** estructuracArrayRasEntryNames = REPLICATE( ;cStructRasEntryName, 255 )

*** Variable con el tamaño de la matriznSize = LEN( cArrayRasEntryNames )

*** Variable en la que se retorna el número*** de entradas encontradasnEntries = 0

*** Llamada a la función para obtener la *** informaciónnResult = RasEnumEntries( 0, "", ;@cArrayRasEntryNames, ;@nSize, ;@nEntries )

*** Dimensión de la matriz como públicaPUBLIC ARRAY &cArrayReturn.[nEntries]

*** Extracción de los datos desde la matriz*** de estructurasFOR nCont = 0 TO nEntries - 1

*** Obtener una EstructuracRasEntryName = SUBSTR( ;

cArrayRasEntryNames, ;264*nCont + 1, 264 )

*** Asignar el nombre a la matriz&cArrayReturn.[nCont+1] = SUBSTR( ;

cRasEntryName, 5, ;AT(CHR(0),SUBSTR(cRasEntryName,5))-1)

NEXT

*** Retorno del número de elementos que han *** encontradoRETURN nEntries

Page 6: Visual FoxPro Como Cliente en Internet

Gracias a este programas podemos ya mostrar todas las posibles configuraciones de conexión antes de llamar a la misma, permitiendo que el usuario seleccione cual debemos utilizar.

Realizar una llamada por RAS

Para realizar una llamada directamente desde un programa Visual FoxPro, y no por medio de llamadas a ordenes del sistema operativo, debemos hacer uso principalmente de la función siguiente:

DECLARE Integer RasDial ;IN RASAPI32.DLL ;Integer RasDialExtensions, ;Integer Phonebook, ;String @ RasDialParams, ;Integer NotifierType, ;Integer Notifier, ;Integer @ hRasConn

Esta función utiliza como primer parámetro una estructura tipo RASDIALEXTENSIONS con información extra que sólo es utilizada desde Windows NT. Como nosotros no vamos a pasar esa estructura hemos definido el dato como Integer y no como String y de esta forma pasar un 0 como valor. Su segundo parámetro es un puntero a una cadena con la ruta de un phonebook de Windows NT. Como nosotros vamos ha utilizar el phonebook por defecto o las entradas en el registro de Windows 95 lo hemos definido de tipo Integer y pasaremos un 0.

El siguiente parámetro es muy importante, es una estructura RASDIALPARAMS con los parametros de la conexión que queremos realizar. Para poder construir esta estructura podemos utilizar la función GetEntryDialParams a la que pasamos una estructura sólo con el nombre de la configuración que queremos utilizar y el recoge el resto de los datos.

Los dos parámetros siguientes se utilizan para un seguimiento asíncrono del estado de la conexión. Como desde Visual FoxPro es bastante complejo la recepción de mensajes del sistema nos centraremos en realizar conexiones donde la función no devuelva el control hasta que se realice todo el proceso.

Por último le pasaremos una variable por referencia para que introduzca en ella el manejador de la conexión establecida.

Como ejemplo hemos creado una función que recibe el nombre de la entrada en el phonebook que queremos utilizar, realiza la llamada y comprueba que ha sido satisfactoría, devolviendonos el manejador de la misma.

************************************************ Realiza una llamada y devuelve el *** manejador a la conexión*********************************************LPARAMETER cConexion

*** Declaración de las funciones del API DECLARE Integer RasDial ;

Page 7: Visual FoxPro Como Cliente en Internet

IN RASAPI32.DLL ;Integer RasDialExtensions, ;Integer Phonebook, ;String @ RasDialParams, ;Integer NotifierType, ;Integer Notifier, ;Integer @ hRasConn

DECLARE Integer RasHangUp ;IN RASAPI32.DLL ;Integer hRasConn

DECLARE Integer RasGetEntryDialParams ;IN RASAPI32.DLL ;String @ PhoneDirectory, ;String @ RasDialParams, ;Integer @ IsPassword

DECLARE Integer RasGetErrorString ; IN RASAPI32.DLL ; Integer ErrorValue, ; String @ MessageBuffer, ; Integer BufferLen

LOCAL cPhonebook, cRasDialParams, nResultLOCAL nRasConn

*** Elminar blancos en el parámetro pasadocConexion = ALLTRIM( cConexion )

*** Preparar la estructura para los*** parametros de conexióncRasDialParams = wordtoc(1052) ;+ cConexion ;+ REPLICATE( CHR(0), ;1045 - LEN( cConexion ) )cPhonebook = chr(0)nPasswords = 0

*** Obtener los parametros de conexiónnResult = RasGetEntryDialParams( ;@cPhonebook, ;@cRasDialParams, ;@nPasswords )

*** Preparar variable para el retorno *** del manejadornRasConn = 0

*** Realizar la conexiónnResult = RasDial( 0, 0, ;@cRasDialParams, 0, 0, @nRasConn )

*** Comprobar si hubo error y mostrar *** mensaje si lo huboIF nResult # 0

Page 8: Visual FoxPro Como Cliente en Internet

PRIVATE cMensajecMensaje = SPACE(256)

IF RasGetErrorString( nResult, ;@cMensaje, LEN(cMensaje) ) # 0

ERROR "Error no determinado en " ;+ "Acceso telefónico a redes. (" ;

+ LTRIM( STR( nResult ) ) + ")"ELSE

ERROR "Acceso telefónico a redes: (";+ LTRIM( STR( nResult ) ) + ") " ;

+ ALLTRIM( cMensaje )

ENDIF

*** Colgar por si quedó inestable *** la conexión

RasHangUp( nRasConn )

*** Retorno con error -2RETURN -2

ENDIF

*** Retorno del manejador de la conexiónRETURN nRasConn

Debemos hacer notar que se está utilizando un programa llamado wordtoc para convertir un número a un tipo de dato DWORD capaz de introducirse en el buffer que utilizamos como sustituto de la estructura C original. En otros ejemplos utilizaremos el programa ctoword para poder obtener un número desde el buffer. Este es el código fuente de ambos programas:

*** WORDTOC*** Combierte un número en un bufferPROCEDURE WORDTOCLPARAMETER nNumberRETURN CHR(BITAND(255,nNumber)) ;

+ CHR(BITAND(65280,nNumber)%255) ; + CHR(BITAND(16711680,nNumber)%255) ;+ CHR(BITAND(4278190080,nNumber)%255)

*** CTOWORD*** Combierte un buffer en un númeroPROCEDURE CTOWORDLPARAMETER cBufferRETURN ASC(SUBSTR(cBuffer,1,1)) ;

+ ASC(SUBSTR(cBuffer,2,1))*256 ;+ ASC(SUBSTR(cBuffer,3,1))*65536 ;+ ASC(SUBSTR(cBuffer,4,1))*16777216

Cerrar una conexión RAS

Page 9: Visual FoxPro Como Cliente en Internet

Una aplicación elegante no deja sus conexiones abiertas una vez que no le son necesarias o cuando la aplicación se cierra. Lo mejor es preguntarle al usuario si desea que cerremos la conexión o bien desea mantenerla abierta. Para cerrar una conexión abierta con RasDial utilizaremos la siguiente función:

DECLARE Integer RasHangUp ;IN RASAPI32.DLL ;Integer hRasConn

Esta función requiere el manejador de la conexión y colgará la línea. Es necesario esperar algunos segundos antes de volver a utilizar la línea, pues es habitual que ésta no se encuentre disponible inmediantemente despues de ser colgada.

Como ejemplo hemos realizado un pequeño programa que corta la conexión de la que pasemos el manejador, esperando 3 segundos antes de devolver el control.

************************************************ Cuelga una conexión realizada y de la *** que dispongamos un manejador*********************************************LPARAMETER nRasConn

*** Declaración de las funciones del API DECLARE Integer RasHangUp ;IN RASAPI32.DLL ;Integer hRasConn

DECLARE Integer Sleep ;IN Win32API ;Integer Milliseconds

LOCAL nResult

*** Realizar el cierre de la líneanResult = RasHangUp( nRasConn )

*** Realizar una pausa de tres segundos*** para asegurar el colgado

=Sleep(3000)ENDIF

*** Retornar lo devuelto por la funciónRETURN nResult

Obtener las conexiones ya establecidas

Antes de abrir una conexión por Dial-Up Networking es necesario saber si ya existía una conexión con esa configuración y de esta forma evitar intentar realizar dos veces la misma conexión. Para saber qué conexiones están abiertas se utiliza la siguiente función del API de RAS:

DECLARE INTEGER RasEnumConnections ;IN RASAPI32.DLL ;STRING @ RasConnectionsBuffer, ;

Page 10: Visual FoxPro Como Cliente en Internet

INTEGER @ dwSize, ;INTEGER @ nCount

Esta función utiliza una estructura tipo matriz de estructuras RASCONN. Como en los casos anteriores debemos crear un buffer para contener esta matriz de estructuras y luego obtener los datos por la posición de los elementos de la estructura dentro del buffer.

Como ejemplo hemos creado un programa que crea una matriz con el nombre recibido como parámetro e inserta en la misma la información sobre las conexiones activas en ese momento.

************************************************ Construye una matriz con todas las*** conexiones RAS abiertas*********************************************LPARAMETER cArrayReturn

*** Declaración de las funciones del APIDECLARE INTEGER RasEnumConnections ;

IN RASAPI32.DLL ;STRING @ RasConnectionsBuffer, ;INTEGER @ dwSize, ;INTEGER @ nCount

DECLARE INTEGER RasGetErrorString ;IN RASAPI32.DLL;INTEGER ErrorValue, ;STRING @ MessageBuffer, ;INTEGER BufferLen

*** Creación de una estructura tipo RASCONNcConexion = wordtoc(412) ;+ REPLICATE( CHR(0), 408 )

*** Creación de una matriz con esa *** estructuracConexiones = REPLICATE( cConexion, 16 )

*** Variable con el tamaño de la matriznSize = LEN( cConexiones )

*** Variable en la que se retorna el *** número de entradas encontradasnCount = 0

*** Llamada a la función para obtener *** la informaciónnResult = RasEnumConnections( ;@cConexiones, ;@nSize, ;@nCount )

*** Si existe alguna conexión abierta

Page 11: Visual FoxPro Como Cliente en Internet

IF nCount > 0

*** Dimensión de la matriz como públicaPUBLIC ARRAY &cArrayReturn.[nCount,4]

*** Extracción de los datos desde la*** matriz de estructuras

FOR nPos = 0 TO nCount - 1

*** Obtener una EstructuracConexion = SUBSTR( ;

cConexiones, ;( nPos * 412 ) + 1, ;412 )

*** Handle&cArrayReturn.[nPos+1,1] = ctoword( ;

SUBSTR(cConexion,5,4))*** Nombre&cArrayReturn.[nPos+1,2] = STRTRAN( ;

SUBSTR(cConexion,9,257), CHR(0))*** Tipo&cArrayReturn.[nPos+1,3] = STRTRAN( ;

SUBSTR(cConexion,266,17),CHR(0))*** Device&cArrayReturn.[nPos+1,4] = STRTRAN( ;

SUBSTR(cConexion,283,129),CHR(0))

NEXT

ENDIF

*** Retorno del número de elementos que ** se han encontrado

RETURN(nCount)

Algunas ideas

El espacio se acaba, pero es interesante mostrar dos cuadros de diálogo que se pueden encontrar en el disco de la revista y que ejemplifican el posible interface de una aplicación cuando esta utiliza Internet. Sólo son un esquema, pero puede servir de base para una aplicación.

Para configurar el sistema de marcado, si es que se utiliza este y no un Proxy o un Router, podemos mostrar un formulario similar a este:

Page 12: Visual FoxPro Como Cliente en Internet

 

Cuando se solicita permiso para realizar una conexión en la que realizará una comprobación de la versión de la aplicación y bajar posibles actualizaciones podría mostrar un mensaje similar a este:

 

Con estos detalles nuestra aplicación puede empezar a utilizar un sistema de Dial-Up Networking con la mayor facilidad.

El API aquí descrito no es más que una pequeña muestra de las posibilidades del RAS, pero de momento es suficiente para nuestros propositos. En los próximos artículos veremos como aprovechar esta conexión por medio de protocolos como FTP y HTTP.

Pablo Almuniapertenece al grupo de Consultoría y Control de Calidad de la Unidad de Informática de MAPFRE. Se puede entrar en contacto con él por Email en [email protected]