FoxPress – Diciembre 2000

 

Dialoga por TCP/IP

http://www.fpress.com/                                            (fuentes: winsock.zip)

 

         

 

.£¬  Hace algún tiempo se publicó en esta revista un código sobre como hacer un Chat en VB y desde entonces me había quedado con las ganas de hacer lo mismo en VFP.

 

El Chat como tal quizás no tenga un interés inmediato en tus aplicaciones pero es un buen y sencillo ejercicio para aprender a manejar el control de Winsock.

 

El control de Winsock es muy útil pues permite tener conexiones TCP o  UDP.

 

Si tienes una conexión TCP y acceso a los diversos puertos que usan las aplicaciones de Internet como Browsers, FTP, POP, etc... puedes dialogar con ellas.

 

Con Visual Studio y en concreto con Visual Basic viene un control llamado Winsock para manejo de sockets. En este artículo mostraré sus principales características y construiremos, un servidor y cliente de chat en Visual FoxPro.

 

Como decía al principio, puede que el Cliente/Servidor de Char no te atraiga especialmente pero puedes usarlo para establecer tu propio sistema de mensajería en una red extensa. Visualizar la pantalla de un usuario sin moverte de tu sitio, lanzar aplicaciones en PC’s remotos, etc... Las utilidades son muchas y quizás en próximos artículos revisemos algunas.

 

Para que todo lo que vamos a comentar te sirva debes tener en tu máquina instalado el control de Winsock (si en tu máquina sólo tienes FoxPro no lo tendrás instalado. Tienes que tener también VB para que se haya instalado en tu máquina). Primero algunos coneceptos básicos

 

El Protocolo TCP/IP 

 

TCP se refiere a un gran cumulo de protocolos de comunicación que se han desarrollado desde 1970 a partir de su predecesor ARPANET. TCP, podríamos decir que es el que se encarga de transmitir la información y el IP el que se encarga de enrutarla... Se encarga de decirnos donde está el destinatario.

 

Pero el TCP/IP sólo no es suficiente ya que se puede atacar a una gran variedad de Host en las diversas máquinas... podríamos ir al Host de Finger o al de Telnet y para eso este protocolo necesita una información adicional que es lo que llamamos puerto.

 

Los Puertos

 

El puerto se usa para identificar un servicio o aplicación concreta dentro de  una máquina. Esto es necesario porque en una misma máquina pueden estar corriendo diversos servicios. El puerto le dice al servicio de que hay un cliente que quiere conectarse.

 

Cuando se diseñaron se llegó a un acuerdo sobre la reserva de una serie de puertos como son:

 

Puerto

Aplicación

 

 

80

http

20 y 21

FTP

70

Gopher

25

SMTP

110

POP 3

23

Telnet

79

Finger

 

 

 

Los sockets nos llevan al campo más bajo de la programación en Internet. Como habrás podido suponer, programar sockets es algo bastante complejo. Sin embargo, el control para el manejo de sockets de Microsoft te da un acceso muy fácil al Windows Socket API

 

El API de Windows para sockets también llamado WinSock se basa en el estándar que marcó la Universidad de Berkeley que se usa también en las plataformas UNYS. Mientras que un socket se usa para comunicar dos aplicaciones...El Winsock encapsula todas las acciones de bajo nivel y da a los programadores que lo usen la posibilidad de manejar desde un nivel más alto estos sockets.

 

Con el Winsock te puedes comunicar con otra aplicación e intercambiar datos ya sea usando el protocolo UDP (User Datagrama Protocol) ó el TCP (Transmisión Control Protocol) los protocolos UDP y TCP son los protocolos fundamentales de Internet. Por ejemplo, el http corre sobre transferencias TCP.

 

Con el Winsock se pueden crear aplicaciones que coleccionen información y las envíen a un servidor central o que coleccionen datos de diversos clientes.

 

Una de las primeras decisiones que tendrás que hacer a la hora de usar el control de Winsock es determinar si vas a usar el protocolo TCP ó el de UDP.

 

El protocolo TCP tiene las siguientes características

 

1.- Es una conexión basada en el protocolo. Esto quiere decir que el cliente debe empezar la comunicación conectándose a un serividor.

 

2.- No hay límite en el tamaño de los mensajes. Si es necesario el protocolo romperá el mensaje en trozos más pequeños.

 

3.- Sin emargo, se basa en cadenas (como opuesto a registros) lo que quiere decir que muchas veces serán necesarias varias lecturas del socket hasta completar el mensaje.

 

4.- Garantiza que se envía el mensaje desde el cliente al servidor y si no saldrá un error.

 

 

El protocolo UDP tiene las siguientes características

 

1.- No es un protocolo basado en la conexión por lo tanto no es necesario que exista un servidor esperado una llamada

 

2.- Por tanto no se garantiza que el mensaje sea recibido. La aplicación envía el mensaje al servidor y si no lo recibe no pasa nada.

 

3.- No hay garantía en el órden de los mensajes.

 

4.- El tamaño máximo de los mensajes está limitado por la configuración de la red y de los servidores.

 

Las analogías que se suelen utilizar para estos dos protocolos son el del teléfono y el de la radio. El teléfono necesita (Protocolo TCP) necesita a alguien al otro lado de la línea pues de lo contrario no se puede establecer la comunicación. La radio, por el contrario, (Protocolo UDP) emite y le da igual que exista alguien al otro lado para recibir las señales.

 

Si tu aplicación necesita que la otra aplicación reciba la información deberás de usar el TCP y lo mismo si vas a enviar grandes cantidades de datos. No obstante, si son cantidades pequeñas y no hay nadie necesariamente esperándolo podrás usar UDP.

 

Usaremos UDP

 

Usaremos UDP pues las cadenas a enviar son pequeñas y no es necesario guardar conexiones (no hay password ni nombre) . Al usar UDP no existe propiamente una conexión. En este caso la conexión no se cierra pues se deberá continuar esperando para escuchas a otras peticiones.

 

El control Winsock

 

Este control no funciona si no tienes instalado como uno de los protocolos de tu máquina el protocolo TCP/IP.

 

1.- El control lo tienes que añadir a tu proyecto mediante la ventana de componentes (desde el menú seleccionar componentes). Necesitarás poner el control de Winsock en tu formulario que en tiempo de ejecución no tiene ningún aspecto visual. A continuación se muestran unos cuadros con sus propiedades, métodos y eventos fundamentales.

 

Propiedad

Descripción

 

 

BytesReceived

Número de Bytes recibidos

LocalHostName

Nombre de la máquina local

LocalIP

Dirección IP local

LocalPort

Establece el puerto local

Protocolo

Establece el protoclo UDP ó TCP

RemoteHost

Nombre del Host remoto

RemoteHostIP

Establece la dirección IP remota

REmotePort

Puerto remoto

State

Estado del Socket

 

 

 

 

 

 

Método

 

Descripción

 

 

Accept

Acepta una conexión entrante

Close

Cierra la conexión

Connect

Se conecta a un socket remoto

GetData

Recibe los datos enviados por el host remoto

Listen

Situación de escucha de conexiones

SendData

Envía datos a un socket remoto

 

 

Evento

 

Ocurre cuando...

 

 

Close

Cuando se cierra la conexión

Connect

La petición de conexión se completa

ConnectionRequest

Un intento remoto de conexión

DataArrival

Se reciben datos de un socket remoto

Error

Ha ocurrido un error en background

SendComplete

Se completa una operación de envío

 

En los ejemplos verás que hay dos directorios uno para el módulo Host (servidor) y otro para el módulo Cliente (Remoto). A la hora de probarlo puedes usar los dos en tu misma máquina pero deberás abrir dos Foxes

 

La Construcción del Host

1.- Crea un formulario con dos campos de edición, dos botones y ponle encima el control de Winsock. Algo parecido al siguiente gráfico:

 

 

 

 

2.- En el método DataArrival del Winsock escribe:

 

Local cRecvData, cRunCmd

cRecvData = ""

This.GetData(@cRecvData, 8, bytestotal)

If !Empty(cRecvData)

  Do Case

        Case Left(cRecvData,8) = "__TEXT__"

              If ThisForm.WindowState <> 0

                    ThisForm.WindowState = 0

              EndIf

              ThisForm.edtMensaje.Value = SubStr(cRecvData,9)

              ThisForm.edtContestacion.Enabled = .T.

              ThisForm.Visible = .T.

              ThisForm.edtContestacion.SetFocus

  EndCase

EndIf

 

3.- En el Init del formulario pon:

 

With ThisForm.WinSock1

  .RemotePort = 1001

  .Bind(1002,0)

EndWith

 

4.- Entra interactivamente en el Winsock y asegurate que está marcado como protcolo el 1 UDPProtocol (esto también se podría hacer por código)

 

5.- En el Click del botón enviar escribe:

 

Local cSendData, cCurUser

With ThisForm.WinSock1

  If !Empty(ThisForm.edtContestacion.Value)

        cCurUser = Left(Sys(0), RAT("#", Sys(0))-1)

        cSendData = Trim(ThisForm.edtContestacion.Value)+;

              " - desde "+cCurUser

        .SendData(cSendData)

  EndIf

EndWith

 

Con esto ya tienes todo el Host preparado. Observa que como hemos puesto en el INIT vamos a trabajar con el puerto 1001. Si quisieramos interactuar con los Borwsers podríamos poner el puerto 80.

 

 

La Construcción del Remoto

 

1.- Para el remoto también tienes que construir un formulario, ponerle dos cuadros de edición, un par de botones, el control Winsock y un Textbox para poner la dirección IP. Algo parecido a esto:

 

En el Textbox deberemos poner la dirección IP del lugar donde se encuentra el Host (si es en tu misma máquina, deberá haber abierto otra instancia de Fox para en uno ejecutar el Host y en otro el Remoto)

 

2.- En el Init del formulario ponemos:

 

With This.WinSock1

  .RemotePort = 1002

  .Bind(1001, 0)

EndWith

 

3.- En el DataArrival del Control ponemos:

 

Local cRecvData, cFileName, cRunCmd

cRecvData = ""

This.GetData(@cRecvData, 8, bytestotal)

If !Empty(cRecvData)

        ThisForm.edtContestacion.Value = ;

              AllTrim(ThisForm.edtContestacion.Value + Chr(13)+Chr(10)+ cRecvData)

        ThisForm.edtContestacion.Visible = .T.

EndIf

 

4.- En el click del botón de enviar:

 

If Empty(ThisForm.edtMensaje.Text)

  Wait "Escriba un Mensaje" Nowait Window

  Return

EndIf

 

*- Si está vací la dirección de Host avisamos

If Empty(ThisForm.txtHost.value)

  Wait "Tienes que poner una dirección de Host" Nowait Window

  Return

EndIf

 

ThisForm.SendToUser(alltrim(Thisform.txtHost.Value))

 

5.- Finalmente en el método SendtoUser del Formulario (que nos tenemos que haber creado previamente):

 

LPARAMETERS cSendUser

Local cSendData

With Thisform.WinSock1

  .RemoteHost = cSendUser

  If .State <> 1

        Wait "Lo siento, pero no hay disponible una conexión" Nowait Window

        Return

  EndIf

 

  cSendData = "__TEXT__"+ThisForm.edtMensaje.Text

 

  If !Empty(cSendData)

        .SendData(cSendData)

  EndIf

EndWith

 

6.- Asegúrate de que el control de Winsock está preparado para trabajar con UDP

 

Y ya está todo

 

Después de que practiques todo verás que es muy fácil y empezarás a pensar en las posibilidades que te abre esto. Una de ellas es que el Host reciba una consulta y ejecute una Select sobre los artículos y de esta forma ya tienes un catálogo puesto en la Web. Todo esto queda para ti.

 

FoxPress – Diciembre de 2000

© 2000 FoxPress. All rights reserved