Social Icons

viernes, 28 de marzo de 2014

Como programar en red con visual basic 6 - Cómo crear aplicaciones que acepten varias conexiones

Estimados lectores.

Espero hayan estudiado ya las entradas anteriores, ya que a partir de este punto, entraremos en una nueva etapa del curso para programar aplicaciones en red con visual basic 6, en la cual dejaremos de lado el concepto de aplicación cliente/servidor 1 a 1, y entraremos al concepto de aplicaciones cliente/servidor 1 a muchos.

Como crear aplicaciones que aceptan varias conexiones?

Para crear este tipo de aplicaciones, se olvida el concepto 1 a 1 para convertirse en un concepto 1 a muchos, para lograr esto en nuestras aplicaciones, tenemos que pensar de la siguiente manera:

En lugar de hacer que nuestro winsock del servidor reciba una conexión y se cierre:

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
  Winsock1.Close                        ‘cierra el winsock
  Winsock1.Accept requestID     ‘Acepta la conexión
End Sub


Lo que debemos hacer es que nuestro winsock reciba la petición y cree otro winsock que aloje esa conexión, y él siga esperando más conexiones, esto lo conseguimos de la siguiente forma:

Primero seleccionamos nuestro winsock y en la propiedad index ponemos el valor de “0”, con esto indicamos que será una matriz unidimensional o un vector de winsocks, ahora al recibir una petición de conexión se utiliza este código:

Antes que nada declaramos una variable que va a llevar el conteo de las conexiones establecidas

Public contador_conexiones as integer

Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)
  Load Winsock1(contador_conexiones)  'Se crea un nuevo winsock en el vector
  Winsock1(contador_conexiones).Close 'Se cierra el winsock creado
  Winsock1(contador_conexiones).Accept requestID 'El winsock creado acepta la conexión entrante
  contador_conexiones = contador_conexiones + 1 'Aumentamos nuestra variable de conexiones

End Sub

Como programar en red con visual basic 6 - Validaciones de envío de mensajes y conexión

Hola de nuevo estimados lectores.

Suponiendo que ya leyeron mis entradas anteriores, en este punto ya debemos conocer las propiedades básicas del control Winsock, y algunas propiedades de manejo de errores.

En esta entrada, aprenderemos cómo programar validaciones en nuestras aplicaciones, para hacerlas como bien decimos en este mundo de la programación de software, aplicaciones a prueba de tontos.

Bien, empecemos:

Validaciones de envío de mensajes y conexión

Para tener un programa muy bien desarrollado y que no cause errores cuando las terminales destino se caigan, debe hacerse una buena validación en el envío de mensajes a terminales, esto es, si no se encuentra activa la terminal, no enviarle ningún tipo de mensajes hasta que esta esté activa. Esto se consigue con la propiedad “state”, tomamos algunos valores de esta propiedad para validar que la máquina esté activa.
Los valores que nos interesan de esta propiedad son los siguientes

Valor               Constante                   Estado

0                      sckClosed                   Cerrado
7                      sckConnected             Conectado

Ejemplo de envío de mensaje erroneo:

Winsock1.senddata “Hola como estás”

Este envío de mensaje funciona muy bien cuando la terminal destino está conectada, pero si se desconecta la terminal y mandamos un mensaje a ella, nuestra aplicación se traba. Entonces debemos utilizar la siguiente estructura para que nuestra aplicación no sufra ningún error de este tipo

Ejemplo de envío de mensaje correcto:

If winsock1.state=7 then
  Winsock1.senddata “Hola como estás”
endif

Ahora procedemos a validar la conexión, esto causa error si tenemos un botón de conectar y pulsamos conectar y la aplicación se conecta con el servidor, muy bien hasta ahora, pero que pasa si de casualidad se nos ocurre nuevamente pulsar el botón conectar?, nuestra aplicación sufre un error. Ahora a corregirlo.

Ejemplo de conexión erronea:

Winsock1.connect “192.168.1.6”, 10112

Funciona pero falla con la explicación que te di anteriormente

Ejemplo de conexión correcta:

If winsock1.state<>7 then
  Winsock1.close
  Winsock1.connect “192.168.1.6”, 10112

endif

Como programar en red con visual basic 6 - Propiedades del control Winsock

Estimados lectores.

Esta entrada es muy importante, ya que aprenderemos las funciones necesarias para realizar una aplicación en red totalmente validada, funcional y sin problemas de manejo de errores.

En pocas palabras, aprenderemos cómo programar una aplicación en red que no tenga fallas.

Listen

 Pone a la aplicación en espera de una conexión de un cliente, cuando el winsock recibe un intento de conexión, se produce el evento connectionRequest, entonces en este método se debe llamar al evento Accept para aceptar la conexión entrante. Se hace notar que un winsock solo pude aceptar una conexión, o sea sería conexión de computadora a computadora. No es muy común que nosotros querramos hacer aplicaciones en las que nuestro servidor solo atienda a una computadora cliente, sino que atienda a varias. Para hacer que nuestro servidor acepte a varias conexiones a la vez, lo que hacemos es establecer un winsock principal totalmente a la espera, y que éste al recibir una conexión entrante cargue otro winsock y le asigne la nueva conexión, mientras nuestro winsock principal sigue recibiendo más conexiones y asignándolas a nuevos winsocks.

El winsock original debe establecerse su propiedad index = 0  para que este winsock sea el inicial de un vector de winsocks. Cada winsock nuevo que éste cree se irá almacenando en el vector.

Winsock original
(esperando conexiones)
Winsock creado por el original
(atendiendo cliente 1)
Winsock creado por el original
(atendiendo cliente 2)
Espacio libre para winsock


LocalPort

Propiedad que debe establecerse en el servidor para que acepte conexiones de los clientes. Es de lectura y escritura, además está en disponible en tiempo de diseño y ejecución.
Ejemplo: Winsock1.LocalPort

ConnectionRequest

Evento que se activa cuando el servidor detecta que hay un cliente queriendo conectarse a él. Al aceptar la conexión con el método Accept, las propiedades RemoteHostIP guarda la IP del cliente y RemotePort guarda el puerto utilizado por el cliente.

Accept

Esta propiedad es para aceptar la conexión entrante.
Ejemplo: winsock1.accept RequestID

Dataarrival

Es cuando el servidor está recibiendo mensajes del cliente
  
GetData

Recibe el mensaje que activó a DataArrival, y lo guarda en una variable y borra lo que se recibió, ya que se queda almacenado en el buffer del sistema(memoria temporal)
Ejemplo:  dim datos as string
                 Winsock1.GetData datos

SendData

Para mandar mensajes al cliente, que puede ser texto o código binario, en caso de mandar archivos.
Ejemplo: winsock1.SendData “Mensaje”

State

Propiedad del winsock que nos permite saber el estado de la conexión, valores que puede devolver:

Valor               Constante                   Estado

0                      sckClosed                   Cerrado
1                      sckOpen                     Abierto
2                      sckListening               Escuchando
3                      sckConnectionPending          Conexión pendiente
4                      sckResolvingHost      Resolviendo Host
5                      sckHostResolved       Host resuelto 
6                      sckConnecting                       Conectando
7                      sckConnected             Conectado
8                      sckClosing                  Cerrando la conexión

9                      sckError                      Ha detectado un error

Close

Propiedad del winsock que permite cerrar el control winsock para establecer una nueva conexión, esto siempre se debe de hacer antes de invocar la propiedad connect.
Ejemplo: winsock1.close

Connect

Propiedad del winsock que permite establecer una conexión con otro programa, en la misma computadora, en la red, o en internet.
Ejemplo: winsock1.connect “148.208.196.5”, 10112

BytesReceived

Propiedad de solo lectura que almacena la cantidad de datos recibidos. Está disponible sólo en tiempo de ejecución.
Ejemplo: winsock1.BytesReceived

PeekData

Este método es similar a GetData, lo único que varía, es que el GetData elimina los datos recibidos del buffer, y el PeekData no los elimina.

SendProgress

Este método se produce mientras se están enviando datos. Pasa como parámetros los bytes enviados desde la última vez que se activó el evento (bytesEnv) y los bytes que esperan a ser enviados en el buffer de transmisión (bytesRest)

Ejemplo: winsock1_SendProgress (bytesEnv As Long, bytesRest As Long)

SendComplete

Se produce cuando en una operación de envío de datos, se han enviado todos.

Ejemplo: winsock1_SendComplete()

Error

Se produce siempre que ocurre un error en los procesos de segundo plano (por ejemplo, un fallo al conectar o un fallo al enviar o recibir en segundo plano). Pasa como parámetros el código de error, la descripción del error, el scode del error, el origen del error,  y un booleano para cancelar o aceptar el que presente un cuadro de dialogo con el aviso de error.

Winsock1_Error(número As Integer, descripción As String, scode As Long, origen As String, archivoAyuda as String, contextoAyuda As Long, cancelarVista As Boolean)


El código de error puede tomar estos valores:

Constante                                           Valor   Descripción

SckOutOfMemory                             7          Sin memoria
SckInvalidPropertyValue                  380      El valor de la propiedad no es válido
SckGetNotSupported                                    394      No se puede leer la propiedad
SckSetNotSupported                         383      La propiedad es de sólo lectura.
SckBadState                                      40006  Protocolo o estado de conexión incorrecto para
La solicitud o la transacción
requerida.
SckInvalidArg                                               40014  El argumento que se pasó a una función no
estaba en el formato correcto o en el intervalo
especificado.
SckSuccess                                        40017  Correcto
SckUnsupported                                40018  Tipo Variant no aceptado.
SckInvalidOp                                    40020  La operación no es válida en el estado actual.
SckOutOfRange                                40021  El argumento está fuera del intervalo.
SckWrongProtocol                            40026  Protocolo erróneo para la solicitud o la
transacción requerida.
SckOpCanceled                                 10004  Se canceló la operación.
SckInvalidArgument                         10014  La dirección solicitada es una dirección de
multidifusión, pero el indicador no está
activado.
SckWouldBlock                                            10035  El socket es no bloqueante y la
operación especificada se bloqueará.
SckInProgress                                    10036  Se está efectuando una operación de Winsock
bloqueante.
SckAlreadyComplete                        10037  Se completó la operación. No se están
efectuando operaciones bloqueantes.
SckNotSocket                                               10038  El descriptor no es un socket.
SckMsgTooBig                                              10040  El datagrama es demasiado grande para
el búfer y se truncará.
SckPortNotSupported                                   10043  El puerto especificado no es compatible.
SckAddressInUse                              10048  Dirección en uso.
SckAddressNotAvailable                  10049  La dirección no está disponible en la máquina
local.
SckNetworkSubsystemFailed                       10050  Error en el subsistema de red.
SckNetworkUnreachable                   10051  El host no puede encontrar la red en este
momento.
SckNetReset                                      10052  Expiró el tiempo de espera de la conexión antes
de establecer SO_KEEPALIVE.
SckConnectAborted                          10053  La conexión se ha cancelado al sobrepasar el
tiempo de espera o por otro error.
SckConnectionReset                         10054  La conexión se ha restablecido desde el lado
remoto.
SckNoBufferSpace                            10055  No hay espacio disponible en el búfer.
SckAlreadyConnected                      10056  El socket ya está conectado.
SckNotConnected                             10057  El socket no está conectado.
SckSocketShutdown                         10058  El socket se ha desactivado.
SckTimedout                                     10060  Se ha sobrepasado el tiempo de conexión.
SckConnectionRefused                     10061  Se ha forzado el rechazo de la conexión.
SckNotInitialized                              10093  Es necesario llamar primero a WinsockInit.
SckHostNotFound                            11001  Respuesta autorizada: host no encontrado.
SckHostNotFoundTryAgain             11002  Respuesta no autorizada: host no encontrado.
SckNonRecoverableError                  11003  Errores no recuperables.
SckNoData                                        11004  Nombre válido; no hay registro de datos del
tipo solicitado.

Como programar en red con visual basic 6 - Chat cliente/servidor

Hola estimados lectores.

En esta entrada, aprenderemos como programar una chat cliente/servidor, con el cuál daremos nuestros primeros pasos con las funciones de red que nos proporciona visual basic 6, a través de su control Winsock.

Configurando el sistema servidor

Este sistema servidor será el servidor para un chat entre cliente y servidor (Programa 02)

Antes debemos saber lo siguiente:
Listen

 Pone a la aplicación en espera de una conexión de un cliente, cuando el winsock recibe un intento de conexión, se produce el evento connectionRequest, entonces en este método se debe llamar al evento Accept para aceptar la conexión entrante. Se hace notar que un winsock solo pude aceptar una conexión, o sea sería conexión de computadora a computadora. No es muy común que nosotros querramos hacer aplicaciones en las que nuestro servidor solo atienda a una computadora cliente, sino que atienda a varias. Para hacer que nuestro servidor acepte a varias conexiones a la vez, lo que hacemos es establecer un winsock principal totalmente a la espera, y que éste al recibir una conexión entrante cargue otro winsock y le asigne la nueva conexión, mientras nuestro winsock principal sigue recibiendo más conexiones y asignándolas a nuevos winsocks.

El winsock original debe establecerse su propiedad index = 0  para que este winsock sea el inicial de un vector de winsocks. Cada winsock nuevo que éste cree se irá almacenando en el vector.

Winsock original
(esperando conexiones)
Winsock creado por el original
(atendiendo cliente 1)
Winsock creado por el original
(atendiendo cliente 2)
Espacio libre para winsock


LocalPort

Propiedad que debe establecerse en el servidor para que acepte conexiones de los clientes. Es de lectura y escritura, además está en disponible en tiempo de diseño y ejecución.
Ejemplo: Winsock1.LocalPort
ConnectionRequest

Evento que se activa cuando el servidor detecta que hay un cliente queriendo conectarse a él. Al aceptar la conexión con el método Accept, las propiedades RemoteHostIP guarda la IP del cliente y RemotePort guarda el puerto utilizado por el cliente.
Accept

Esta propiedad es para aceptar la conexión entrante.
Ejemplo: winsock1.accept RequestID
Dataarrival

Es cuando el servidor está recibiendo mensajes del cliente



GetData

Recibe el mensaje que activó a DataArrival, y lo guarda en una variable y borra lo que se recibió, ya que se queda almacenado en el buffer del sistema(memoria temporal)
Ejemplo:  dim datos as string
                 Winsock1.GetData datos
SendData

Para mandar mensajes al cliente, que puede ser texto o código binario, en caso de mandar archivos.
Ejemplo: winsock1.SendData “Mensaje”
State

Propiedad del winsock que nos permite saber el estado de la conexión, valores que puede devolver:



Valor               Constante                   Estado

0                      sckClosed                   Cerrado
1                      sckOpen                     Abierto
2                      sckListening               Escuchando
3                      sckConnectionPending          Conexión pendiente
4                      sckResolvingHost      Resolviendo Host
5                      sckHostResolved       Host resuelto 
6                      sckConnecting                       Conectando
7                      sckConnected             Conectado
8                      sckClosing                  Cerrando la conexión
9                      sckError                      Ha detectado un error

Entramos a lo que es el desarrollo de un sistema servidor, el cual nos ayudará a recibir a un cliente, y poder chatear con él.

Creamos lo siguiente:

-          5 etiquetas (label1, label2, label3, label4 y label5), label1 en caption “Esta es mi ip”, label2 en caption “Nombre de mi computadora”, label3 en caption “Mensaje recibido”, label4 en caption “Escribir mensaje”, label5 en caption “Estado de la conexión”.

-          5 cuadros de texto

-          3 botones de comando (command1, command2, command3), command1 en caption  “Cual es mi ip ?“, command2 en caption “Cual es mi nombre“, command3 en caption “Enviar”.

-          1 timer (timer1)
-          1 winsock (winsock1)

Debe quedar mas o menos así:





Primero configuramos la propiedad “LocalPort” del winsock1 y la ponemos en el puerto “10112”, y el timer en la propiedad interval establecemos “1”.

Ahora a programar:

Lector: Programa el command1 y command2, que ya lo hicimos en el ejemplo anterior


Debemos programar el evento LOAD del formulario:

Private Sub Form_Load()
  Winsock1.Listen   ‘El sistema se pone a la espera de conexiones
End Sub


Programando el command3 “Enviar”, que sirve para enviar mensajes al cliente

Private Sub Command3_Click()
  Winsock1.SendData Text4.Text  'Envía mensaje al cliente
  Text4.Text = ""
End Sub


Programando el evento ConnectionRequest para saber cuando un cliente se trata de conectar y aceptar la conexión:

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
  Winsock1.Close                        ‘cierra el winsock
  Winsock1.Accept requestID     ‘Acepta la conexión
End Sub

Programando el evento DataArrival, para recibir los mensajes del cliente:

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
  Dim datos As String    'Declaramos variable cadena
  Winsock1.GetData datos 'Obtenemos el mensaje recibido y lo pasamos a la variable datos
  Text3.Text = ""        'Limpiamos el text3
  Text3.Text = datos     'Pasamos el mensaje recibido al text3
End Sub

Programando el timer1, para que aparezca el estado de conexion al instante.

Private Sub Timer1_Timer()
  If Winsock1.State = 0 Then
    Text5.Text = "Conexión cerrada"
  End If
  If Winsock1.State = 7 Then
    Text5.Text = "Conexión establecida"
  End If
  If Winsock1.State = 8 Then
    Text5.Text = "Cerrando la conexión"
  End If
  If Winsock1.State = 9 Then
    Text5.Text = "Ha ocurrido un error en la conexión"
  End If
  If Winsock1.State = 2 Then
    Text5.Text = "Esperando una conexión"
  End If
End Sub

Con esto el sistema servidor está listo para recibir a un cliente.
Configurando el sistema cliente

Entramos ya de plano a configurar un sistema cliente que se conectará a un sistema servidor que también haremos, este sistema funcionará para conectarte al sistema servidor que esté instalado en la misma máquina que en el sistema cliente, o al sistema servidor que esté instalado en otra computadora en red o en internet.

Este sistema cliente será el cliente para un chat entre cliente y servidor (Programa 03)

Antes debemos saber lo siguiente:
Close

Propiedad del winsock que permite cerrar el control winsock para establecer una nueva conexión, esto siempre se debe de hacer antes de invocar la propiedad connect.
Ejemplo: winsock1.close
Connect

Propiedad del winsock que permite establecer una conexión con otro programa, en la misma computadora, en la red, o en internet.
Ejemplo: winsock1.connect “148.208.196.5”, 10112

Creamos lo siguiente:

-          4 etiquetas (label1, label2, label3, label4), label1 en caption “Conectarme a la ip”, label2 en caption “Mensaje recibido”, label3 en caption “Escribir mensaje”, label4 en caption “Estado de la conexión”.

-          4 cuadros de texto

-          2 botones de comando (command1, command2), command1 en caption  “Conectar“, command2 en caption “Enviar“.

-          1 timer (timer1)

-          1 winsock (winsock1)


Se debe ver algo como esto:



Configuramos el timer, en la propiedad interval ponemos un “1”

Programemos el command1 “Conectar”

Private Sub Command1_Click()
Winsock1.Connect Text1.Text, 10112  ‘Nos conectamos a la ip especificada por medio  del 
                                                                ‘puerto 10112
End Sub


Ahora programamos el control timer1 con los eventos más destacados

Private Sub Timer1_Timer()
  If Winsock1.State = 0 Then
    Text4.Text = "Conexión cerrada"
  End If
  If Winsock1.State = 7 Then
    Text4.Text = "Conexión establecida"
  End If
  If Winsock1.State = 8 Then
    Text4.Text = "Cerrando la conexión"
  End If
  If Winsock1.State = 9 Then
    Text4.Text = "Ha ocurrido un error en la conexión"
  End If
End Sub
Programando command2 “Enviar”

Private Sub Command2_Click()
  Winsock1.SendData Text3.Text
  Text3.Text = ""
End Sub


Programando evento DataArrival

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
  Dim datos As String    'Declaramos variable cadena
  Winsock1.GetData datos 'Obtenemos el mensaje recibido y lo pasamos a la variable datos
  Text2.Text = ""        'Limpiamos el text2
  Text2.Text = datos     'Pasamos el mensaje recibido al text2
End Sub


Ya con esto podemos intentar hacer una conexión entre cliente y servidor, por medio de la ip. Si queremos conectarnos al programa servidor que está en nuestra PC, basta con escribir la ip “127.0.0.1” y conectar y se hace la conexión.

Como programar en red con visual basic 6 - Saber nombre e ip de computadora

En esta entrada, veremos cómo programar nuestra primera aplicación con la cual nos adentraremos en el mundo de la programación en red con visual basic 6.

Primeramente, debemos buscar el control Microsoft winsock control en el menú “proyecto->componentes”, activar su casilla y pulsar el botón “Aceptar”.




El control tiene una apariencia como la siguiente figura:



Y al agregarlo aparecerá en la barra de controles.


Hecho esto procedemos a realizar nuestra primera aplicación.


Primera aplicación: saber ip y nombre de nuestra computadora (programa 01)

Para esto abrimos visual basic 6.0 y creamos lo siguiente

-          2 etiquetas  (label1 y label2), label1 en caption “Esta es mi ip”, label2 en caption “Nombre de mi computadora”
-          2 cuadros de texto (text1 y text2)
-          2 botones de comando (command1 y command2), command1 en caption “Cual es mi ip?”, command2 en caption “Cual es mi nombre”.
-          1 winsock (winsock1)


Se debe ver algo como esto:





Hecho esto programemos el command1 “Cual es mi ip?”

Private Sub Command1_Click()
  Text1.Text = Winsock1.LocalIP ‘Obtiene la ip de la computadora
End Sub

Y ahora programemos el command2 “Cual es mi nombre”

Private Sub Command2_Click()
  Text2.Text = Winsock1.LocalHostName ‘Obtiene el nombre de la computadora
End Sub

Y ahora a correr nuestra aplicación y pulsar en los dos botones, y la ejecución debe ser algo como esto:




Claro la ip que están viendo es la que tenía yo cuando ejecuté el programa, y el nombre que ven es el nombre de mi computadora, el código está muy chico y explicadas sus lineas.

El código fuente lo puedes encontrar en: http://www.como-programar.com/downloads/codigos-curso-para-programar-en-red-con-visual-basic-6.rar

Espero les sea de utilidad a quienes se inician en este mundo de la programación en red con visual basic 6.

Te invito a que nos compartas tus comentarios.
 
Blogger Templates