Usando el control WinSock de Microsoft para realizar un chat con UDP.

Desde que publique la colaboración en la web del Guille, sois muchos los que habéis pedido información sobre el desarrollo de programas con el WinSock. Hoy vamos a desarrollar un chat usando el control WinSock de Microsoft realizando un chat con UDP.

Con el protocolo UDP podemos ahorrar mucho código, ya que nos permite poder enviar un mensaje a varios PC’s simultáneamente. Si se intentara realizar con protocolo TCP, habría que trabajar con un array de controles para crear una instancia por cada usuario que este incluido en el chat.

Detalles del Chat

  • Habrá que identificarse antes de conectarse.
  • Al conectarse enviara una notificación por UDP a todos los Chat activos indicando el nuevo usuario.
  • Los otros chats responderán indicando el usuario que tienen registrado.
  • Cuando se escriben los textos se envían por UDP a todos los programas de Chat activos, los cuales muestran el mensaje.
  • Al desconectar el chat, envía un mensaje al resto para indicar que se sale de la lista.

Protocolo de Comunicación

Son las ordenes que se envían entre si los programas para comunicar lo que están ocurriendo. En este caso son de longitud fija de 4 caracteres:

  • USER: Indica que se ha conectado un nuevo usuario al chat.
  • CONC: Es la respuesta de los chats que ya están activos cuando un usuario se conecta.
  • MENS: Los mensajes escritos por otros usuarios.
  • DISC: Cuando uno de los usuarios se desconecta.
  • QUIT: Cuando un usuario cierra el programa de Chat.

      Pseudocodigo del Chat

      Estos son los pasos principales para la creación del programa.

    • Conexión al Chat: Como podéis ver en el proceso BtnConectar_Click se activa el Socket con Protocolo UDP y la IP 255.255.255.255 (para enviar un mensaje a todos los PC’s) por el puerto 2345.
    • Recepción de datos: En el evento del socket SocketUDP_DataArrival, se hace el tratamiento a los datos que recibimos de los otro Chat’s activos, según el protocolo de comunicación indicado en el párrafo anterior, actuando en cada caso (incluyendo en la lista de usuarios o mostrando el mensaje recibido).

      Si quieres aportar algo para mejorar este proyecto escribe algún comentario a este post

      Tutorial de WinSock

      Bienvenido al mundo del Winsock ;). Este documento te enseñara las propiedades y eventos que posee este OCX. El proyecto que adjunto es simple y pequeño. Meramente te enseña como poder conectar entre distintos ordenadores y poder comunicarse entre sí.

      Propiedades Winsock

      Lo primero que debes aprender sobre el control son las propiedades. Hay que entender los pequeños detalles antes de pasar a las grandes cosas de la programación.

      LocalPort: Este es el puerto que tu ordenador usara. Se recomienda indicar un puerto de 4 dígitos (Ej. 1234). Este es el puerto por el que tu PC enviara la información.

      RemotePort: Este es el puerto por el que recibirás la información. En otras palabras, el otro ordenador que “habla” envía los datos a este puerto.

      Protocol: Hay dos tipos de protocolos que puedes seleccionar. UDP es lento y puede perder los “paquetes” de datos transmitidos, pero es más fácil de programar. TCP es mucho más rápido y no pierde tanto los paquetes como hace UDP, pero es más difícil de programar a menos que sepas como funciona, y es el utilizado para comunicaciones en Internet.

      RemoteHost: Es Host Remoto es la dirección IP a la que dirige la comunicación. Una IP es un número especial que identifica tu ordenador dentro de la red (ya sea local o internet). Es una serie de 4 grupos que pueden ser entre 1 y 255 y son divididos por períodos. Un ejemplo sería: 111.222.121.212

      LocalIP: Esta es tu dirección IP.

      Eventos

      DataArrival: Aquí es donde pones la codificación si quieres actuar cuando recibes los datos que llegan al puerto remoto.

      Connect: Este evento ocurre una vez que el usuario del otro ordenador se conecta.

      SendProgress: Esta asociado principalmente a la transferencia de datos. Aquí este al código que ejecutara mientras esta en el proceso de enviar datos.

      SendComplete: Este evento salta cuando termina de enviar los datos. Un buen ejemplo es sacar un mensaje o un sonido .wav cuando termina de transferir los datos.

      Close: Cuando se cierra la conexión. La mejor manera de usar esto es mostrando un mensaje cuando se cierra la conexión.

      GetData: Recoge la información enviada por el otro PC.

      SendData: Indica al socket que envíe los datos. Un ejemplo de esto sería:

      Winsock1.SendData “BlaBla y más BlaBla!”

      Creando un lector de IP

      Ahora que tenemos las propiedades y definiciones de los eventos, porqué no intentamos aprender como leer la IP de tu ordenador mientras usamos el control MsWinSock.Ocx.

      Lo primero que necesitas es crear un proyecto y añadirlo en la sección Componentes el control “Microsoft WinSock Control”. Selecciona el icono y arrastra sobre el formulario para crear el control en tu proyecto, y asegurate que las propiedades del control es TCP (realmente no importa cual sea).

      Lo siguiente es crear un TextBox y un CommandButton. Asegurate que la propiedad Locked del TextBox esta activado (esto significa que el usuario no puede modificar el contenido del TextBox). Ahora realiza doble click sobre el botón que has creado e introduce el código siguiente:

      Text1.Text = Winsock1.LocalIP

      Esto recoge la IP de tu ordenador (si estas conectado a Internet te devuelve la IP asignada en Internet) y lo pone en el TextBox indicado.

      Código programa Chat
      Option Explicit
      Private Sub BtnConectar_Click()
          ' Se cambia el Titulo del Formulario
          Me.Caption = App.Comments & " [" & TxtNick.Text & "]"
          ' Se activa el Socket
          SocketUDP.Protocol = sckUDPProtocol
          SocketUDP.RemoteHost = "255.255.255.255"
          SocketUDP.RemotePort = 2345
          SocketUDP.Bind 2345
          ' Limpia la lista de usuarios y activa o desactiva los
          ' controles que se estan usando
          LstUser.Clear
          TxtNick.Enabled = False
          BtnConectar.Enabled = False
          BtnDesconectar.Enabled = True
          LstChat.Enabled = True
          LstUser.Enabled = True
          TxtChat.Enabled = True
          BtnEnviar.Enabled = True
          TxtChat.SetFocus
          DoEvents
          ' Se informa al resto de chats que hay un nuevo usuario
          SocketUDP.SendData "User" & TxtNick.Text
          DoEvents
      End Sub
      Private Sub BtnDesconectar_Click()
          ' Se pone el titulo por defecto
          Me.Caption = App.Comments
          ' Se envia un mensaje a todos los usuarios
          ' que se va desconectar el usuario X y se
          ' cierra el socket
          SocketUDP.SendData "DisC" & TxtNick.Text
          DoEvents
          SocketUDP.Close
          ' Activa o desactiva los controles que se estan usando
          TxtNick.Enabled = True
          BtnConectar.Enabled = True
          BtnDesconectar.Enabled = False
          LstChat.Enabled = False
          LstUser.Enabled = False
          TxtChat.Enabled = False
          BtnEnviar.Enabled = False
      End Sub
      Private Sub Form_Load()
          ' Carga el formulario y
          ' muestra el titulo por defecto
          Me.Caption = App.Comments
      End Sub
      Private Sub Form_Unload(Cancel As Integer)
          ' Si el socket esta conectado
          If SocketUDP.State  sckClosed Then
              ' Se envia el mensaje de que va a cerrar el programa
              ' y se desactiva el socket
              SocketUDP.SendData "Quit" & TxtNick.Text
              EliminarUsuario TxtNick.Text
              DoEvents
              SocketUDP.Close
          End If
      End Sub
      Private Sub SocketUDP_DataArrival(ByVal bytesTotal As Long)
          ' Gestiona la recepción de datos
          Dim LineaDatos As String, Comando As String, Parametros As String
          ' Se carga el array
          SocketUDP.GetData LineaDatos, vbString
          Comando = UCase$(Left$(LineaDatos, 4))
          If Len(LineaDatos) > 4 Then Parametros = Mid$(LineaDatos, 5)
          Select Case Comando
          Case "MENS"
              ' Cuando llega un mensaje de otro usuario
              LstChat.AddItem Format(Now, "hh:nn:ss ") & Parametros
          Case "USER"
              ' Cuando un usuario se ha conectado
              LstChat.AddItem "Se ha conectado " & Parametros
              LstUser.AddItem Parametros
              If SocketUDP.RemoteHostIP  SocketUDP.LocalIP Then
                  SocketUDP.RemoteHost = SocketUDP.RemoteHostIP
                  SocketUDP.SendData "Conc" & TxtNick.Text
              End If
          Case "CONC"
              ' Son las ordenes de los usuarios que ya estaban conectados
              LstUser.AddItem Parametros
          Case "QUIT"
              ' El usuario X ha cerrado la aplicación
              LstChat.AddItem Parametros & " ha cerrado la aplicación."
              EliminarUsuario Parametros
          Case "DISC"
              ' El usuario X se ha desconectado del Chat.
              LstChat.AddItem Parametros & " ha desconectado."
              EliminarUsuario Parametros
          Case Else
              Debug.Print "Desconocido: " & LineaDatos
          End Select
      End Sub
      Private Sub TxtChat_GotFocus()
          TxtChat.SelStart = 0
          TxtChat.SelLength = Len(TxtChat)
      End Sub
      Private Sub TxtChat_KeyPress(KeyAscii As Integer)
          ' Si detecta un "Enter" envia el mensaje
          If KeyAscii = 13 Then BtnEnviar_Click
      End Sub
      Private Sub BtnEnviar_Click()
          ' Se conecta con el resto de Chats
          SocketUDP.RemoteHost = "255.255.255.255"
          ' y envia la información del mensaje
          SocketUDP.SendData "Mens" & TxtNick.Text & "> " & TxtChat.Text
          DoEvents
          ' Limpia la caja de texto para el siguiente mensaje
          TxtChat.Text = ""
          TxtChat.SetFocus
      End Sub
      Private Sub TxtNick_Change()
          ' Si hay algo de contenido en el Nick se activa el botón
          ' conectar
          BtnConectar.Enabled = IIf(Len(TxtNick.Text) > 0, True, False)
      End Sub
      Sub EliminarUsuario(Usuario As String)
          ' Busca el usuario indicado y lo elimina de la lista
          Dim Ic As Integer
          For Ic = 0 To LstUser.ListCount - 1
              If LstUser.List(Ic) = Usuario Then
                  LstUser.RemoveItem Ic
              End If
          Next Ic
      End Sub

      Aquí tienes el código completo

    • Anuncios

      Responder

      Introduce tus datos o haz clic en un icono para iniciar sesión:

      Logo de WordPress.com

      Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

      Google photo

      Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

      Imagen de Twitter

      Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

      Foto de Facebook

      Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

      Conectando a %s