Sie sind auf Seite 1von 34

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.

com Tipo de documento: Tutorial Winsock

Tutorial de Introduccin a WINSOCK

El presente manual es una referencia terica/practica para la introduccin a la POO, bsicamente desde el entorno de desarrollo tecnolgico Microsoft Visual Basic Este manual fue desarrollado exclusivamente como gua de educacin, siendo su uso permitido para tales efectos y sin fines de lucro. El material terico y prctico fue revisado por el Ing. Remmy Fuentes T.

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

CAPTULO 1 Arquitectura Cliente Servidor mediante Sockets


ESTE CAPTULO INTRODUCTORIO ACERCA AL LECTOR ALGUNOS CONCEPTOS BSICOS.
1.1 Introduccin Un socket, es un mtodo para la comunicacin entre un programa cliente y un servidor en una red, se define, por tanto, como el punto final en una conexin.

Este mecanismo surge a principios de los 80 con el sistema Unix de Berkeley, para proporcionar un medio de comunicacin entre procesos y presentan la misma funcionalidad que tiene la comunicacin por correo o por telfono (de un buzn se extraen mensajes completos, mientras que el telfono permite el envo de flujos de informacin que no tienen una estructura claramente definida), es decir permiten que un proceso hable (emita o reciba informacin) con otro incluso estando estos en distintas mquinas. Esta caracterstica de interconectividad hace que el concepto de socket sea de gran utilidad.

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

1.2 Arquitectura de un socket Un socket queda definido por un par de direcciones IP local y remota, un protocolo de transporte y un par de nmeros de puerto local y remoto. Para que dos programas puedan comunicarse entre s es necesario que se cumplan ciertos requisitos: Que un programa sea capaz de localizar al otro. Que ambos programas sean capaces de sincronizar la conexin. Un protocolo de comunicaciones, que permite el intercambio de datos. Un par de direcciones del Protocolo de Red (Direccin IP, si se utiliza el Protocolo TCP/IP), que identifica la computadora de origen y la remota. Un par de nmeros de puerto, que identifica a un programa dentro de cada computadora.

Los sockets permiten implementar una arquitectura cliente-servidor o peer to peer. La comunicacin debe ser iniciada por uno de los programas que se denomina programa cliente. El segundo programa espera (listen) a que otro inicie la comunicacin, por este motivo se denomina programa servidor. Un socket es un proceso o hilo existente en la mquina cliente y en la mquina servidora, que sirve en ltima instancia para que el programa servidor y el cliente lean y escriban la informacin. Esta informacin ser la transmitida por las diferentes capas de red. Cuando un cliente conecta con el servidor se crea un nuevo socket, de esta forma, el servidor puede seguir esperando conexiones en el socket principal y comunicarse con el cliente conectado, de igual manera se establece un socket en el cliente en un puerto local. Una aplicacin servidor normalmente escucha por un puerto especfico esperando una peticin de conexin de un cliente, una vez que se recibe, el cliente y el servidor se conectan de forma que les sea posible comunicarse entre ambos. Durante este proceso, el cliente es asignado a un nmero de puerto, mediante el cual enva peticiones al servidor y recibe de este las respuestas correspondientes. Similarmente, el servidor obtiene un nuevo nmero de puerto local que le servir para poder continuar escuchando cada peticin de conexin del puerto original. De igual forma une un socket a este puerto local. 1.3 Puertos TCP-UDP Un puerto de red es una interfaz para comunicarse con un programa a travs de una red. En el modelo OSI quien se preocupa de la administracin de los puertos y los establece en el encabezado de los segmentos es la capa de transporte o capa 4, administrando as el envo y re-ensamblaje de cada segmento enviado a la red haciendo uso del puerto 4

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

especificado. Un puerto suele estar numerado para de esta forma poder identificar la aplicacin que lo usa. La implementacin del protocolo en el destino utilizar ese nmero para decidir a qu programa entregar los datos recibidos. Esta asignacin de puertos permite a una mquina establecer simultneamente diversas conexiones con mquinas distintas, ya que todos los paquetes que se reciben tienen la misma direccin, pero van dirigidos a puertos diferentes. Los nmeros de puerto se indican mediante una palabra, 2 bytes (16 bits), por lo que existen 65535. Aunque podemos usar cualquiera de ellos para cualquier protocolo, existe una entidad, la IANA, encargada de su asignacin, la cual cre tres categoras: Puertos bien conocidos: Los puertos inferiores al 1024 son puertos reservados para el sistema operativo y usados por "protocolos bien conocidos" como por ejemplo HTTP (servidor Web), POP3/SMTP (servidor de e-mail) y Telnet. Si queremos usar uno de estos puertos tendremos que arrancar el servicio que los use teniendo permisos de administrador. Puertos registrados: Los comprendidos entre 1024 (0400 en hexadecimal) y 49151 (BFFF en hexadecimal) son denominados "registrados" y pueden ser usados por cualquier aplicacin. Existe una lista pblica en la web del IANA donde se puede ver qu protocolo usa cada uno de ellos. Puertos dinmicos o privados: Los comprendidos entre los nmeros 49152 (C000 en hexadecimal) y 65535 (FFFF en hexadecimal) son denominados dinmicos o privados, normalmente se asignan en forma dinmica a las aplicaciones de clientes al iniciarse la conexin. Su uso es poco comn son usados en conexiones peer to peer (P2P).

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

CAPTULO 2 Conexin mediante win-socket en Visual Basic .Net empleando el namespace System.Net.Sockets
ESTE CAPTULO INTRODUCTORIO ACERCA AL LECTOR ALGUNOS ASPECTOS BSICOS QUE DEBE CONOCER ANTES DE MANEJAR SOCKETS DESDE.NET
2.1 Introduccin A partir de Microsoft Visual Studio .Net, Microsoft incorpor un Namespace para trabajar con Socket: System.Net.Sockets, este Namespace lo emplearemos para realizar una aplicacin de ejemplo que utilice Socket para conectar dos PCs a travs de Internet o de la red LAN y enviar mensajes de texto. Empleando sockets tambin se pueden enviar archivos. El namespace System.Net.Sockets es mucho ms "potente" que el antiguo Winsock (incluso el componente OCX para .NET), proporciona ms funciones, propiedades, eventos y mtodos ms eficientes. Aunque no existe un componente que nos facilitara la programacin. A continuacin explicaremos cmo desarrollar la aplicacin servidor y la aplicacin cliente. Veremos que es un poco "arduo" debido a que no incorpora un componente para este hecho. 2.2 Aplicacin servidor para conexin por socket con Visual Basic .Net Vamos a crear un nuevo proyecto en vb.NET el cual lo llamaremos SERVIDOR PASO 1: En el formulario servidor agregaremos los siguientes componentes:

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 2: Lo siguiente que tenemos que hacer es crear una clase, que la llamaremos ClaseServidorSocket:

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 3: Una vez que tenemos la clase habilitada procedemos a programar nuestras funciones en la misma, en el editor de cdigo de la clase procedemos a definir las siguientes propiedades, funciones y los namespaces con los cuales vamos a trabajar: Antes de la definicin de la clase importamos lo siguiente: Agregaremos el cdigo necesario para interactuar con el Namespace System.Net.Sockets:
Imports Imports Imports Imports System.Net.Sockets System.Threading System.Text System.IO

Quedando similar a:

A continuacin agregamos el siguiente cdigo, observe cada seccin con detenimiento para su anlisis:
'Esta estructura permite guardar la informacin sobre un cliente Private Structure datosClienteConectado Public socketConexion As Socket 'Socket para mantener la conexin con cliente Public Thread As Thread 'Hilo para mantener escucha con el cliente Public UltimosDatosRecibidos As String 'ltimos datos enviados por el cliente End Structure Private clientes Private Private Private Private tcpLsn As TcpListener 'Para realizar la escuchas de conexiones de Clientes As New Hashtable() 'Datos de los clientes conectados tcpThd As Thread IDClienteActual As Net.IPEndPoint 'ltimo cliente conectado m_PuertoDeEscucha As String

Public Event NuevaConexion(ByVal IDTerminal As Net.IPEndPoint) Public Event DatosRecibidos(ByVal IDTerminal As Net.IPEndPoint) Public Event ConexionTerminada(ByVal IDTerminal As Net.IPEndPoint)

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

'Propiedad para establecer el puerto por el que se realizar la escucha Property Puerto() As Integer Get Puerto = m_PuertoDeEscucha End Get Set(ByVal Value As Integer) m_PuertoDeEscucha = Value End Set End Property 'Procedimiento para establecer el servidor en modo escucha Public Sub IniciarEscucha() tcpLsn = New TcpListener(Puerto) 'Iniciar escucha tcpLsn.Start() 'Crear hilo para dejar escuchando la conexin de clientes tcpThd = New Thread(AddressOf EsperarConexionCliente) tcpThd.Start() End Sub

'Procedimiento para detener la escucha del servidor Public Sub DetenerEscucha() CerrarTodosClientes() tcpThd.Abort() tcpLsn.Stop() End Sub

Public Function ObtenerDatos(ByVal IDCliente As Net.IPEndPoint) As String Dim InfoClienteSolicitado As datosClienteConectado 'Obtengo la informacion del cliente solicitado InfoClienteSolicitado = Clientes(IDCliente) ObtenerDatos = InfoClienteSolicitado.UltimosDatosRecibidos End Function 'Cierra la conexin de un cliente conectado Public Sub cerrarConexionCliente(ByVal IDCliente As Net.IPEndPoint) Dim InfoClienteActual As datosClienteConectado 'Obtener informacin del cliente indicado InfoClienteActual = Clientes(IDCliente) 'Cerrar conexin con cliente InfoClienteActual.socketConexion.Close() End Sub

'Cerrar todas la conexin de todos los clientes conectados

10

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Public Sub CerrarTodosClientes() Dim InfoClienteActual As datosClienteConectado 'Cerrar conexin de todos los clientes For Each InfoClienteActual In Clientes.Values Call cerrarConexionCliente(InfoClienteActual.socketConexion.RemoteEndPoint) Next End Sub 'Enviar mensaje a cliente indicado Public Sub enviarMensajeCliente(ByVal IDCliente As Net.IPEndPoint, ByVal Datos As String) Dim Cliente As datosClienteConectado 'Obtener informacin del cliente al que se enviar el mensaje Cliente = Clientes(IDCliente) 'Enviar mensaje a cliente Cliente.socketConexion.Send(Encoding.ASCII.GetBytes(Datos)) End Sub 'Enviar mensaje a todos los clientes conectados al servidor Public Sub enviarMensajeTodosClientes(ByVal Datos As String) Dim Cliente As datosClienteConectado For Each Cliente In Clientes.Values enviarMensajeCliente(Cliente.socketConexion.RemoteEndPoint, Datos) Next End Sub 'Procedimiento que inicia la espera de la conexin de un cliente 'para ello inicia un hilo (thread) Private Sub EsperarConexionCliente() Dim datosClienteActual As datosClienteConectado While True 'Se guarda la informacin del cliente cuando se recibe la conexin 'Quedar esperando la conexin de un nuevo cliente datosClienteActual.socketConexion = tcpLsn.AcceptSocket() 'Con el IDClienteActual se identificar al cliente conectado IDClienteActual = datosClienteActual.socketConexion.RemoteEndPoint 'Crear un hilo para que quede escuchando los mensajes del cliente datosClienteActual.Thread = New Thread(AddressOf LeerSocket) 'Agregar la informacin del cliente conectado al array SyncLock Me Clientes.Add(IDClienteActual, datosClienteActual) End SyncLock 'Generar evento NuevaConexion RaiseEvent NuevaConexion(IDClienteActual)

11

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

'Iniciar el hilo que escuchar los mensajes del cliente datosClienteActual.Thread.Start() End While End Sub 'Procedimiento para leer datos enviados por el cliente Private Sub LeerSocket() Dim IDReal As Net.IPEndPoint 'ID del cliente que se va a escuchar Dim Recibir() As Byte 'Array donde se guardarn los datos que lleguen Dim InfoClienteActual As datosClienteConectado 'Datos del cliente conectado Dim Ret As Integer = 0 IDReal = IDClienteActual InfoClienteActual = Clientes(IDReal)

While True If InfoClienteActual.socketConexion.Connected Then Recibir = New Byte(100) {} Try 'Esperar a que lleguen un mensaje desde el cliente Ret = InfoClienteActual.socketConexion.Receive(Recibir, Recibir.Length, SocketFlags.None) If Ret > 0 Then 'Guardar mensaje recibido InfoClienteActual.UltimosDatosRecibidos = Encoding.ASCII.GetString(Recibir) Clientes(IDReal) = InfoClienteActual 'Generar el evento DatosRecibidos 'para los datos recibidos RaiseEvent DatosRecibidos(IDReal) Else 'Generar el evento ConexionTerminada 'de finalizacin de la conexin RaiseEvent ConexionTerminada(IDReal) Exit While End If Catch e As Exception If Not InfoClienteActual.socketConexion.Connected Then 'Generar el evento ConexionTerminada 'de finalizacin de la conexin RaiseEvent ConexionTerminada(IDReal) Exit While End If End Try End If End While Call CerrarThread(IDReal) End Sub 'Procedimiento para cerrar el hilo (thread) Private Sub CerrarThread(ByVal IDCliente As Net.IPEndPoint)

12

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Dim InfoClienteActual As datosClienteConectado 'Finalizar el hilo (thread) iniciado ' encargado de escuchar al cliente InfoClienteActual = Clientes(IDCliente) Try InfoClienteActual.Thread.Abort() Catch e As Exception SyncLock Me 'Eliminar el cliente del array Clientes.Remove(IDCliente) End SyncLock End Try End Sub

_____________________________________________________ El cdigo quedara similar a:

ANALICE EL CDIGO A DETALLE SI QUIERE OPTIMIZAR EL USO DE SOCKETS.

13

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 4: A continuacin agregamos el cdigo completo para el formulario de la aplicacin e incluimos los eventos necesarios para el botn "Escuchar", el botn "Enviar datos", Salir, etc. Instanciamos un objeto del tipo SocketServidor del tipo de la clase que hemos creado: Despus de la clase Form1 de nuestro proyecto agregamos:
Dim WithEvents socketServidor As New ServidorSocket()

Quedando similar a:

PASO 5: Vamos a programar el cdigo del evento clic del botn de escuchar. Agregamos:
'Iniciar el servidor, establecer el modo escucha 'para recibir conexin de clientes If (Button_escuchar.Text = "Escuchar") Then If TextBox_puerto.Text <> "" Then Try socketServidor.Puerto = TextBox_puerto.Text socketServidor.IniciarEscucha() Button_escuchar.Text = "Cerrar" TextBox_puerto.Enabled = False Catch err As Exception MsgBox("Se ha producido un error al intentar " & _ "establecer escucha por el puerto " & _ TextBox_puerto.Text & vbCrLf & vbCrLf & err.Message, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly) End Try Else MsgBox("Debe indicar el puerto por el que establecer la escucha.", MsgBoxStyle.Information + MsgBoxStyle.OkOnly)

14

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

TextBox_puerto.Focus() End If Else Button_escuchar.Text = "Escuchar" TextBox_puerto.Enabled = True TextBox_mensaje.Enabled = False Button_enviar.Enabled = False Try socketServidor.DetenerEscucha() Catch err As Exception MsgBox("Error al detener la escucha:" + vbCrLf + vbCrLf + err.Message, MsgBoxStyle.Information + MsgBoxStyle.OkOnly) End Try

End If

Quedar similar a:

Ejecutamos el programa, cuidado el FIREWALL detectara que una nueva aplicacin quiere tener acceso a la red, debe permitir el acceso, en caso de bloquearla el programa no podr enviar datos a travs de la red. 15

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Verificamos el estado de los puertos con la herramienta determinada Netstat

PASO 6: Vamos a programar el cdigo del evento clic del botn de enviar. Agregamos:
socketServidor.enviarMensajeTodosClientes(TextBox_mensaje.Text) TextBox_mensaje.Text = "" TextBox_mensaje.Focus()

16

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Quedando similar a:

PASO 7: Vamos a programar el botn de salir con el siguiente cdigo:


If (Button_escuchar.Text = "Escuchar") Then Me.Dispose() Else Try socketServidor.DetenerEscucha() Me.Dispose() Catch err As Exception MsgBox("Error al detener la escucha:" + vbCrLf + vbCrLf + err.Message, MsgBoxStyle.Information + MsgBoxStyle.OkOnly) End Try

End If

Se debe ver similar a:

PASO 8: hasta ac terminamos con la programacin de los eventos de botones, pasaremos a programar el evento LOAD del formulario principal, en el editor de cdigo con el selector de objetos y eventos escogemos el form1 en su evento LOAD como se ve en la figura: 17

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Y agregamos el siguiente cdigo:


'estas son las funciones que se cargan por defecto cuando se inicia el programa CheckForIllegalCrossThreadCalls = False TextBox_mensaje.Enabled = False Button_enviar.Enabled = False

Quedar similar a:

PASO 9: Terminaremos programando los eventos de nuestro socket, vamos a comenzar con el evento de nueva conexin, el mismo ocurre cuando se detecta un cliente que requiere una conexin: Elegimos el objeto socketServidor y su evento NuevaConexion como se ve en la figura:

En ese espacio agregamos el siguiente cdigo:


'Evento que se ejecutar cuando un nuevo cliente se conecte

18

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Dim CadenaConexion As String CadenaConexion = Date.Now & " Cliente conectado: " & IDTerminal.Address.ToString & ", Puerto: " & IDTerminal.Port ListBox1.Items.Add(CadenaConexion) TextBox_mensaje.Enabled = True Button_enviar.Enabled = True

Deber ser similar a:

PASO 10: Vamos a ver el cdigo para el evento de conexin terminada, el mismo ocurre cuando un cliente se desconecta del servidor: Elegimos el objeto socketServidor y su evento ConexionTerminada como se ve en la figura:

En ese espacio agregamos el siguiente cdigo:


'Evento que se ejecutar cuando finalice la conexin de un cliente Dim cadenaConexion As String cadenaConexion = Date.Now & " Cliente Desconectado: " & IDTerminal.Address.ToString & ", Puerto: " & IDTerminal.Port ListBox1.Items.Add(cadenaConexion) Button_enviar.Enabled = False TextBox_mensaje.Enabled = False

19

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Se ver como:

PASO 11: Pasamos a programar el cdigo para el evento de datos recibidos, el mismo ocurre cuando el servidor detecta la llegada de datos: Elegimos el objeto socketServidor y su evento DatosRecibidos como se ve en la figura:

Agregamos el siguiente cdigo:


Dim mensaje As String 'Mensaje recibido del cliente mensaje = IDTerminal.Address.ToString & " " & Now & " " & socketServidor.ObtenerDatos(IDTerminal) ListBox1.Items.Add(mensaje)

Se debe ver similar a:

20

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 12: El ltimo paso ser cerrar el hilo que hemos abierto con el programa, pasa esto escogemos el objeto form y el evento FormClosed como se ve en la figura:

Agregamos simplemente el comando End como ve en la figura


End

21

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

2.3 Aplicacin cliente para conexin por socket con Visual Basic .Net Abrimos otra instancia del visual studio (mantenemos el servidor abierto en otra instancia u otra ejecucin del vs). Vamos a crear un nuevo proyecto en vb.NET el cual lo llamaremos CLIENTE. PASO 1: En el formulario cliente agregaremos los siguientes componentes:

PASO 2: Lo siguiente que tenemos que hacer es crear una clase, que la llamaremos ClaseClienteSocket:

22

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

23

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 3: Una vez que tenemos la clase habilitada procedemos a programar nuestras funciones en la misma, en el editor de cdigo de la clase procedemos a definir las siguientes propiedades, funciones y los namespaces con los cuales vamos a trabajar: Antes de la definicin de la clase importamos lo siguiente: Agregaremos el cdigo necesario para interactuar con el Namespace System.Net.Sockets:
Imports Imports Imports Imports System.Net.Sockets System.Threading System.Text System.IO

24

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Quedando similar a:

PASO 4: Ya con las importaciones correctas, lo siguiente ser introducir el cdigo de nuestra clase para poder interactuar con los sockets, agregamos lo siguiente:
Private mensajesEnviarRecibir As Stream 'Para enviar y recibir datos del servidor Private ipServidor As String 'Direccin IP Private puertoServidor As String 'Puerto de escucha Private clienteTCP As TcpClient Private hiloMensajeServidor As Thread 'Escuchar mensajes enviados desde el servidor

Public Event ConexionTerminada() Public Event DatosRecibidos(ByVal datos As String) 'Direccin IP del servidor al que nos conectaremos Public Property IP() As String Get IP = ipServidor End Get Set(ByVal Value As String) ipServidor = Value End Set End Property 'Puerto por el que realizar la conexin al servidor Public Property Puerto() As Integer Get Puerto = puertoServidor End Get Set(ByVal Value As Integer)

25

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

puertoServidor = Value End Set End Property 'Procedimiento para realizar la conexin con el servidor Public Sub Conectar() clienteTCP = New TcpClient() 'Conectar con el servidor clienteTCP.Connect(IP, Puerto) mensajesEnviarRecibir = clienteTCP.GetStream() 'Crear hilo para establecer escucha de posibles mensajes 'enviados por el servidor al cliente hiloMensajeServidor = New Thread(AddressOf LeerSocket) hiloMensajeServidor.Start() End Sub 'Procedimiento para cerrar la conexin con el servidor Public Sub Desconectar() 'desconectamos del servidor clienteTCP.Close() 'abortamos el hilo (thread) hiloMensajeServidor.Abort() End Sub

'Enviar mensaje al servidor Public Sub EnviarDatos(ByVal Datos As String) Dim BufferDeEscritura() As Byte BufferDeEscritura = Encoding.ASCII.GetBytes(Datos) If Not (mensajesEnviarRecibir Is Nothing) Then mensajesEnviarRecibir.Write(BufferDeEscritura, 0, BufferDeEscritura.Length) End If End Sub

Private Sub LeerSocket() Dim BufferDeLectura() As Byte While True Try BufferDeLectura = New Byte(100) {} 'Esperar a que llegue algn mensaje mensajesEnviarRecibir.Read(BufferDeLectura, 0, BufferDeLectura.Length) 'Generar evento DatosRecibidos cuando se recibien datos desde el servidor RaiseEvent DatosRecibidos(Encoding.ASCII.GetString(BufferDeLectura)) Catch e As Exception

26

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Exit While End Try End While 'Finalizar conexin y generar evento ConexionTerminada RaiseEvent ConexionTerminada() End Sub

Debera quedar similar a la figura:

PASO 5: Ya con la base de nuestra clase creada, pasamos a programar en el formulario principal, para lo cual, vamos a instanciar un nuevo objeto del tipo relacionado con la clase socket que hemos, en nuestro form principal en el mdulo de cdigo despus de Public Class formSocketCliente agregamos lo siguiente:
Dim WithEvents socketCliente As New ClaseClienteSocket

27

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

Deber quedar similar a:

PASO 6: Vamos a agregar el cdigo a los botones del formulario, comenzaremos con el botn de conectar, en su evento clic:
'Conexin del cliente con el servidor (IP hostname y puerto) If (Button_conectar.Text = "Conectar") Then If TextBox_IP.Text = "" Or TextBox_puerto.Text = "" Then MsgBox("Debe indicar el servidor (IP o hostname) y " _ & "el puerto al que realizar la conexin.", MsgBoxStyle.Information + MsgBoxStyle.OkOnly) TextBox_IP.Focus() Else Try socketCliente.IP = TextBox_IP.Text socketCliente.Puerto = CInt(TextBox_puerto.Text) socketCliente.Conectar() Button_conectar.Text = "Desconectar" TextBox_IP.Enabled = False TextBox_puerto.Enabled = False Button_conectar.Text = "Desconectar" Button_enviar.Enabled = True TextBox_mensaje.Enabled = True ListBox1.Items.Add("Conectado") ListBox1.Items.Add("Conexin establecida a " & TextBox_IP.Text & ":" & TextBox_puerto.Text) Catch err As Exception ListBox1.Items.Add(Date.Now & " Error al tratar de conectar con el host remoto") MsgBox("Error al conectar al servidor " & TextBox_IP.Text & vbCrLf & vbCrLf & err.Message, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)

28

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

End Try End If

Else TextBox_IP.Enabled = True TextBox_puerto.Enabled = True Button_conectar.Text = "Conectar" Button_enviar.Enabled = False TextBox_mensaje.Enabled = False Try socketCliente.Desconectar() Catch err As Exception MsgBox("Error al desconectar del servidor " & TextBox_IP.Text & vbCrLf & vbCrLf & err.Message, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly) End Try

End If

Debe verse similar a:

29

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 7: Vamos a agregar el cdigo para el botn salir:


If (Button_conectar.Text = "Desconectar") Then Try socketCliente.Desconectar() Me.Dispose() Catch err As Exception MsgBox("Error al desconectar del servidor " & TextBox_IP.Text & vbCrLf & vbCrLf & err.Message, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly) End Try Else Me.Dispose() End If

Sera similar a la imagen siguiente:

PASO 8: El ultimo botn es el de enviar, al cual agregamos el siguiente cdigo:


Try 'Enviar mensaje al servidor socketCliente.EnviarDatos(TextBox_mensaje.Text) TextBox_mensaje.Text = "" TextBox_mensaje.Focus() Catch err As Exception MsgBox("Error al enviar mensaje al servidor." &

30

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

vbCrLf & vbCrLf & err.Message) End Try

Comparar con la figura:

PASO 9: Ahora vamos a programar los eventos, primero vamos a programar el evento para recibir datos: En el objeto socket cliente y el evento DatosRecibidos, ver figura:
'Evento que se ejecuta cuando se reciben datos ListBox1.Items.Add(Now + " Servidor: " & datos)

PASO 10: Pasamos a programar el evento de ConexionTerminada: 31

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

En el objeto socket cliente y el evento ConexionTerminada agregamos, ver figura:


ListBox1.Items.Add("Conexin finalizada") TextBox_IP.Enabled = True TextBox_puerto.Enabled = True Button_conectar.Text = "Conectar" Button_enviar.Enabled = False TextBox_mensaje.Enabled = False TextBox_IP.Focus()

PASO 11: Terminamos con los eventos del formulario, en el evento load del form agregamos
CheckForIllegalCrossThreadCalls = False TextBox_mensaje.Enabled = False Button_enviar.Enabled = False

Deber verse similar a:

32

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

PASO 12: Finalmente en el form closed agregamos un End

2.4 Ejecucin de las aplicaciones Corremos ambas aplicaciones y observamos que transmiten datos, que los botones cumplan las funciones predeterminadas.

33

Materia: Redes y Servicios de comunicacin I Docente: Ing. Remmy Fuentes T. Remmy.fuentes@gmail.com Tipo de documento: Tutorial Winsock

34