Documentos de Académico
Documentos de Profesional
Documentos de Cultura
03 Tutorial VBnet Socket Clases PDF
03 Tutorial VBnet Socket Clases PDF
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.
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.
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).
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:
PASO 2: Lo siguiente que tenemos que hacer es crear una clase, que la llamaremos
ClaseServidorSocket:
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
10
11
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
_____________________________________________________
El cdigo quedara similar a:
13
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
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
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
Quedando similar a:
End If
Quedar similar a:
18
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:
19
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:
20
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:
21
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
23
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
Quedando similar a:
25
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
26
Exit While
End Try
End While
'Finalizar conexin y generar evento ConexionTerminada
RaiseEvent ConexionTerminada()
End Sub
27
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
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
29
30
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 11: Terminamos con los eventos del formulario, en el evento load del form
agregamos
CheckForIllegalCrossThreadCalls = False
TextBox_mensaje.Enabled = False
Button_enviar.Enabled = False
32
33
34