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
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.
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
Posted
dom, may 7 2000 19:49
by
Maverick