Javascript

En este articulo se muestra como podemos agregar un socket (winsock) a una pagina HTML (tambian ASP, PHP, etc.) y poner manupularlo utilizando lenguajes del explorador (IE, FireFox) como javascript o vbscript.

La manera en que vamos a agregar sockets en este articulo es utilizando ActiveX, asi que aplicara unicamente a clientes que utilicen Internet Explorer


Este es el ejemplo que se ira describiendo.

Ejemplo

Aunque aqui se utiliza javascript, sera unicamente para validaciones (aunque se podrian haber hecho tambien con vbscript). Mayormente se utilizara vbscript para modificar parametros del socket, tambien para enviar/recibir informacion asi como responder a los eventos que se generen.

Para agregar un socket a nuestra pagina tenemos que utilizar el tag OBJECT de esta manera:

<OBJECT id="socket" classid="clsid:248DD896-BB45-11CF-9ABC-0080C7E7B78D">
 <PARAM NAME="_ExtentX" VALUE="0">
 <PARAM NAME="_ExtentY" VALUE="00">
 <PARAM NAME="_Version" VALUE="0">
 <PARAM NAME="Protocol" VALUE="0">
 <PARAM NAME="RemoteHost" VALUE="">
 <PARAM NAME="RemotePort" VALUE="0">
 <PARAM NAME="LocalPort" VALUE="0">
</OBJECT>

El parametro mas importante que tenemos que observar es classid. Si este parametro estuviera incorrecto simplemente no podriamos hacer nada. A este socket se le ha asignado el nombre socket.

Los parametros que debemos cambiar con nuestro codigo son RemoteHost y RemotePort. En ellos pondremos el nombre/IP del servidor al que nos queremos conectar asi como el puerto en ese servidor.

Tenemos que declarar las funciones que procesaran los eventos que genere el socket. Son 3 principalmente:

  1. Connect. Se ejecuta cuando el socket logro conectarse exitosamente al servidor
  2. Close. Cuando se pierde la conexion
  3. DataArrival. Ocurre cuando el socket detecta que hay datos que fueron recibidos y deben leerse

Con este codigo declaramos las funciones que procesaran los eventos:

<script language="vbscript" for='socket' event='Connect'>conectadoVB</script>
<script language="vbscript" for='socket' event='Close'>desconectadoVB</script>

El atributo for indica para cual de los objetos se esta declarando el evento.
El atributo event indica cual es el evento que se procesara
Entre los tag SCRIPT se pone el nombre de la funcion

En la pagina de ejemplo aparece un SELECT en el que las opciones son distintas direcciones (FTP y HTTP) y el puerto al que se deben conectar. Si se selecciona la primer opcion, la pagina intentara conectarse por FTP a la pagina indicada utilizando el usuario y la contraseƱa que aparecen ahi mismo. Cuando seleccionamos la segunda opcion, la pagina se conectara e intentara mostrar el codigo HTML de la pagina principal del sitio indicado.

La pagina incluye otro archivo con las funciones que realizaran todo el trabajo: 55_socket.vbs

dim horaInicio, timeout
timeout = 10

sub conectarSocketVB(servidor,puerto)
 dim n
 if document.socket <> null then 'verificar si el socket esta creado
 'verificar si el socket esta conectado
 if document.socket.state <> 0 then desconectarSocket 
 end if
 with document.socket
 .Protocol = 0
 .RemoteHost = servidor
 .RemotePort = puerto
 .Connect
 end with
 horaInicio = Now 'hora actual
 setTimeout "conectarSocket2VB()", 100
end sub

Se declaran 2 variables. La primera guarda la hora en que se inicia la conexion y la segunda el tiempo maximo que debera intentarse abrir la conexion.

La funcion recibe como parametros el servidor y el puerto al que se tendra que conectar el socket. Primero se verifica que el socket en realidad exista. Luego, si el socket esta aun conectado, cerrar la conexion. Despues cambiamos los parametros necesarios (RemoteHost y RemotePort), luego intentar abrir la conexion. Guardamos la hora actual. Por ultimo se crea un timer que se estara ejecutando mientras dure el intento de conexion.

Esta es la segunda parte de la conexion. Se ejecutara cada 100 ms hasta que se logre conectar o se alcance el tiempo maximo.

sub conectarSocket2VB
 dim continuar
 'si ya esta conectado, salir del procedimiento
 if document.socket.state = 7 then exit sub
 select case document.socket.state
 'case 0: resul="Closed"
 'case 1: resul="Opened"
 'case 2: resul="Ready"
 case 3: continuar = 1 'Connection in progress"
 case 4: continuar = 1 'Domain is changeing into IP address"
 case 5: continuar = 1 'Domain changed into IP adress"
 case 6: continuar = 1 'Connection to remote host in progress"
 'case 7: resul="Successfully connected"
 'case 8: resul="Connection is broken"
 case 9: continuar = 2 'Error"
 end select
 'continuar intentando conectarse?
 if continuar = 1 then
 if DateDiff("s",horaInicio,now) >= timeout then
 msgbox "Error en la conexion" & vbcrlf & "Se alcanzo el tiempo maximo"
 desconectarSocketVB
 else
 setTimeout "conectarSocket2VB()", 100
 exit sub
 end if
 end if
end sub

Verificamos los distintos estados del socket. Solamente en los que se este aun intentando hacer la conexion, asignamos el valor 1 a la variable continuar. En la parte donde se verificar continuar = 1, se revisa si se alcanzo el tiempo maximo para la conexion. Si es asi, entonces se muestra un mensaje de error. En caso contrario, se crea de nuevo un timer para continuar intentado conectarnos.

Cuando se ejecuta el evento Connect, se manda llamar esta funcion:

sub conectadoVB
 document.forma.btnConectar.disabled = true
 document.forma.btnDesconectar.disabled = false
 document.forma.btnDesconectar.focus
 select case split(document.forma.direc_servidor.value,":")(1)
 case 22: escribirVB "user " & document.forma.usuario_ftp.value
 case 80: escribirVB "GET http://localhost/socket/index.html"
 end select
end sub

Se verifica a que puerto se esta conectando y dependiendo de eso, el socket enviara una cadena distinta.

La siguiente funcion se ejecuta cuando el socket lanza el evento Close.. Unicamente mostramos un mensaje

sub desconectadoVB
 msgbox "desconectado"
 document.socket.close
end sub

La funcion leerVB se manda llamar cuando el evento DataArrival es lanzado por el socket. Esto significa que hay que leer datos del buffer. El texto leido se coloca en el TEXTAREA de la pagina. Si tratamos de conectarnos por FTP, se recibiran otros mensajes del servidor pidiendo usuario. O si ya logramos conectarnos, simplemente mandamos el comando QUIT para cerrar la conexion.

sub leerVB
 dim texto, comando
 document.socket.GetData texto,vbstring
 document.forma.texto.value = document.forma.texto.value & texto
 comando = left(texto,3)
 select case comando
 case "230" :
 escribirVB "QUIT"
 case "331" :
 escribirVB "pass " & document.forma.pwd_ftp.value
 end select
end sub

Por ultimo, la funcion escribirVB unicamente escribe en el socket la cadena que recibe como parametro.

sub escribirVB(cadena)
 document.socket.sendData cadena & vbcrlf
end sub

Category: Javascript