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
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.
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.
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