[go: up one dir, main page]

0% encontró este documento útil (0 votos)
119 vistas61 páginas

Visual Basic

Este documento describe la evolución del lenguaje de programación BASIC. BASIC se creó en 1964 para principiantes y usaba instrucciones sencillas en inglés. En los años 70 ganaron popularidad lenguajes como FORTRAN y COBOL. Con la llegada de los PC, versiones como BASICA y GW-BASIC se usaron pero tenían desventajas frente a otros lenguajes. Visual Basic combinó la sencillez de BASIC con las capacidades de Windows, recuperando el crédito de BASIC entre los profesionales.

Cargado por

incaurco
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
119 vistas61 páginas

Visual Basic

Este documento describe la evolución del lenguaje de programación BASIC. BASIC se creó en 1964 para principiantes y usaba instrucciones sencillas en inglés. En los años 70 ganaron popularidad lenguajes como FORTRAN y COBOL. Con la llegada de los PC, versiones como BASICA y GW-BASIC se usaron pero tenían desventajas frente a otros lenguajes. Visual Basic combinó la sencillez de BASIC con las capacidades de Windows, recuperando el crédito de BASIC entre los profesionales.

Cargado por

incaurco
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 61

Visual Basic

Introducción.-

El lenguaje de programación BASIC (Beginner's All purpose Symbolic Instruction Code ) nació en el
año 1964 como una herramienta destinado a principiantes, buscando una forma sencilla de realizar
programas, empleando un lenguaje casi igual al usado en la vida ordinaria ( en inglés), y con
instrucciones muy sencillas y escasas. Teniendo en cuenta el año de su nacimiento, este lenguaje
cubría casi todas las necesidades para la ejecución de programas. Téngase en cuenta que las
máquinas existentes en aquella época estaban estrenando los transistores como elementos de
conmutación, los ciclos de trabajo llegaban a la impensable cifra de 10.000 por segundo y la
memoria no pasaba de unos pocos k´s en toroides de ferrita.
La evolución del BASIC por los años 70 fue escasa, dado el auge que tomaron en aquella época
lenguajes de alto nivel como el FORTRAN y el COBOL. En 1978 se definió una norma para unificar
los Basics existentes creándose la normativa BASIC STANDARD
Con la aparición de los primeros ordenadores personales, dedicados comercialmente al usuario
particular, allá por la primera mitad de los ochenta, el BASIC resurgió como lenguaje de
programación pensado para principiantes, y muchos de estos pequeños ordenadores domésticos lo
usaban como único sistema operativo.
Con la popularización del PC, salieron varias versiones del BASIC que funcionaban en este tipo de
ordenadores (Versiones BASICA, GW-BASIC), pero todas estas versiones del BASIC no hicieron
otra cosa que terminar de rematar este lenguaje. Los programadores profesionales no llegaron a
utilizarlo, habida cuenta de las desventajas de este lenguaje respecto a otras herramientas
(PASCAL, C, CLIPPER). El BASIC con estas versiones para PC llegó incluso a perder crédito entre
los profesionales de la informática.
Las razones para ello eran obvias:
- No era un lenguaje estructurado.
- No existían herramientas de compilación fiables.
- No disponía de herramientas de intercambio de información.
- No tenía librerías.
- No se podía acceder al interior de la máquina.
- Un largo etcétera de desventajas respecto a otros lenguajes de programación.
Tal fue ese abandono por parte de los usuarios, que la aparición del Quick-BASIC de Microsoft, una
versión ya potente del BASIC, que corregía casi todos los defectos de las versiones pasó
prácticamente inadvertida, a no ser porque las últimas versiones del sistema operativo MS-DOS
incluían una versión de Quick-BASIC algo recortada (Q-Basic) como un producto mas dentro de la
amplia gama de ficheros ejecutables que acompañan al sistema operativo, y aprovecha de él el
editor de textos (Cada vez que se llama al EDIT estamos corriendo el editor del Q-Basic).
Esta versión del popular BASIC ya es un lenguaje estructurado, lo que permite crear programas
modularmente, mediante subrutinas y módulos, capaz de crear programas ya competitivos con otros
lenguajes de alto nivel. Sin embargo llegaba tarde, pues los entornos MS-DOS estaban ya
superados por el entorno gráfico Windows.
Sin embargo algo había en el BASIC que tentaba a superarse: su gran sencillez de manejo. Si a esto
se le añade el entorno gráfico Windows, el aprovechamiento al máximo de las posibilidades de
Windows en cuanto a intercambio de información, de sus librerías, de sus drivers y controladores,
manejo de bases de datos, etc. el producto resultante puede ser algo que satisfaga todas las
necesidades de programación en el entorno Windows. La suma de todas estas cosas es VISUAL -
BASIC. Esta herramienta conserva del BASIC de los años 80 únicamente su nombre y su sencillez,
y tras su lanzamiento al mercado, la aceptación a nivel profesional hizo borrar por fin el "mal
nombre" asociado a la palabra BASIC.

Configurar el programa

Para evitar cambios en los programas:


Herramientas -> opciones – Entorno Activar preguntar si se guardan los cambios.

Herramientas -> Opciones –Editor Activar requerir declaración de variables.


Herramientas -> Opciones –Editor Activar ancho de tabulación 4.
Herramientas -> Opciones –Editor Activar sangría automatica.
Herramientas -> Opciones –Editor-opciones de la venta:
Activar ver modulo completo de forma predeterminada.
Separador de procedimiento.

Como se ve en:
Interfaz del programa:

Propiedad
Métodos

.show

Eventos
_click

Declaracion de Variables

Sintaxis: Dim nombre de la variable As String

TIPOS DE VARIABLES

TIPO COMENTARIO

BOOLEAN Sólo admite 2 valores TRUE o FALSE

BYTE admite valores entre 0 y 255

INTEGER admite valores entre -32768 y 32767

LONG admite valores entre -2.147.483.648 y 2.147.483.647

SINGLE admite valores decimales con precisión simple

DOUBLE admite valores decimales de doble precisión

CURRENCY válido para valores de tipo moneda

STRING cadenas de caracteres

DATE fechas, permite operar con ellas

Output

MsgBox “Gracias “, , “titulo”


F5 correr programa.
F8 correr programa paso a paso.
‘ Comentario
Unload me – cerrar formulario

Sub ( ) procedimiento, Function ( ) función.

Variable Global, variable local.

Ejemplo 1.

Dim U As Double
Sub g()
Dim x As Integer
U = 4: x = 5
End Sub
Private Sub Form_Load()
g
Dim Y As Double
Y=7
MsgBox U
MsgBox Y
MsgBox x
Unload Me
End Sub

Función:

Ejemplo 2.

Option Explicit
Function suma(a, b) As Double
suma = a + b
End Function
Private Sub Form_Load()
Dim S As Double
S = suma(3, 2)
MsgBox suma(5, 6)
MsgBox suma(4, 3)
suma 6, 7
MsgBox S

Unload Me
End Sub

Imput
Ejemplo 3.

ption Explicit
Function suma(a, b) As Double
suma = a + b
End Function
Private Sub Form_Load()
Dim S As Double
Dim S1 As Double
S = InputBox("numero", "titulo", "12")
S1 = InputBox("numero", "titulo", "default")
MsgBox suma(S, S1)
MsgBox "la suma de" & S & "+" & S1 & "es" & S + S1
Unload Me

End Sub

Concatenación: &

Estructuras de control:

IF condición A them = igual, < > distinto, < menor, mayor >,<=,>=.
Else

End if

Ejemplo 4.

Private Sub Form_Load()


Dim A As Integer
A = InputBox("ingrese nota")
If A >= 51 Then
MsgBox "aprobado"
Else
MsgBox "reprobado"
End If
Unload Me
End Sub
For:

For var=0 to 100

Next var

Ejemplo 5.
Option Explicit

Private Sub Form_Load()


Dim s As String
s = ""
Dim var As Integer
For var = 1 To 100
s = s & "Num" & var

Next var
MsgBox s
Unload Me

End Sub

While

While ( )
Condicion de salida
Wend

Ejemplo 6.

Private Sub Form_Load()


Dim S As String
S = ""
Dim M As Integer
While (S = "")
M = InputBox("Mostrar tabla")
If (M = 1) Then
MsgBox "Hola"
Else
S = "n"
End If
Wend
Unload Me
End Sub

Arreglos

Dim A (1 to 5) as Integer

Inicializar:

A(1)=4
A(2)=8…
Select Case

Su nombre casi nos define lo que es: Selecciona, dependiendo del caso, un determinado juego de
instrucciones:

Select Case variable ' variable es una variable que puede tomar los valores (p.e.) de 1 a 4

Case 1

Instrucciones a ejecutar en caso de que variable = 1

Case 2

Instrucciones a ejecutar en caso de que variable = 2

Case 3

Instrucciones a ejecutar en caso de que variable = 3

Case 4

Instrucciones a ejecutar en caso de que variable = 4

End Select
Manejo de puerto Paralelo

Configuración de Puerto.-

El Puerto paralelo también llamado lpt usado anteriormente para la conexión de impresoras, escáner ,etc.
Tiene muchas aplicaciones en esta sección veremos como podemos controlarlo.
Para empezar con el uso debemos tener en cuenta la configuración de los pines del puerto que nos servira
para construir nuestro cable. En el puerto existen tos registros que se denominan puertos o PORT., y cada
uno de sus bits, representa un pin determinado del puerto. Los pin's que van del 18 al 25
(18,19,20,21,22,23,24,25): Son para masa, y sirven para conectar las descargas de los circuitos.
Nota.-El Cpu puede tener tanto conectores hembras como machos debemos tener en cuenta que los machos
son seriales y nos interesan los conectores hembras que son para transmisión paralela.

Veamos ahora los tres registros

Puerto de datos (Pin 2 al 9): Es el PORT 888 este puerto se lo puede usar tanto como entrada o como salida,
debemos saber que por default esta configurado como salida si se quiere usar como entrada se debe
programar el puerto de control que veremos después.
Puerto de estado (Pin 15, 13, 12, 10 y 11): Es el PORT 889 y es de solo lectura, por aquí enviaremos señales
eléctricas al ordenador, de este registro solo se utilizan los cinco bits de más peso, que son el bit 7, 6, 5, 4 y 3
teniendo en cuenta que el bit 7 funciona en modo invertido.

Puerto de control (Pin 1, 14, 16 y 17): Es el correspondiente al PORT 890, y es de lectura/escritura, es decir,
podremos enviar o recibir señales eléctricas, según nuestras necesidades. De los 8 bits de este registro solo
se utilizan los cuatro de menor peso o sea el 0, 1, 2 y 3, con un pequeño detalle, los bits 0, 1, y 3 están
invertidos.

En esta imagen puedes ver los tres registros, sus bits y los pines asignados a cada uno de ellos. La imagen
corresponde a un conector DB-25 (Hembra).
Nota1.No olvidarse que si se convierte el nombre de los puertos a Hexadecimal respectivamente seria 888-
>&H378, 889->&H379, 890->&H37A esto porque ha veces es mas comodo llamar al puerto en Hexadecimal.
Para el uso del puerto paralelo tenemos que tener en cuenta que este trabaja con 5 voltios la siguiente
configuración sirve para salida de datos:

Configuración Port 888 como salida


‘El pin 25 es tierra

Esta para entrada de datos:


Port 889 entrada
‘El pin 25 es Tierra

Nota2.- Los circuitos de arriba no necesitan fuente externa pero si se quiere interactuar con otro CI como ser
un Pic,etc. Se recomienda el uso de optóacopladores que son muy buenos porque nos ayudan a aislar tierras.

Nota3.-Se recomienda usar el parmon que es un programita encontrado en la web que sirve como testeador
del puerto paralelo , inclusive se puede mandar datos por el Por888.(Es decir si ya armaste los circuitos de
arriba ya podrías ver en acción tu puerto si haces correr el Parmon.exe)
Programación.-
Para programar puertos en Visual Basic 6.0 tenemos que tener en cuenta que visual Basic solo no puede
manejar puertos , para manejar debemos recurrir a un dll o a un componente externo el cual nos permita
interactuar directamente con el sistema operativo.
Existen muchos Dll como ser el inpout32.dll, el port.dll, el port1.dll,el io.dll etc.
Uso del IO.Dll
Para usar este dll en Visual Basic se carga en un modulo el siguiente codigo, que prácticamente son todas las
funciones que tiene el dll. Por ejemplo para mandar al puerto de datos solo deberíamos llamar a la funcion de
la siguiente manera:
Call PortOut(888,0) ‘Este codigo nos manda puros ceros al puerto
Codigo del dll que se carga en el modulo
'********************************************************************
'Declarations for direct port I/O in 32-bit Visual Basic 6 programs.
' Funciona en W9x, ME, NT, 2000 y XP
'********************************************************************

Public Declare Sub PortOut Lib "IO.DLL" (ByVal Port As Integer, ByVal Data As Byte)
Public Declare Sub PortWordOut Lib "IO.DLL" (ByVal Port As Integer, ByVal Data As Integer)
Public Declare Sub PortDWordOut Lib "IO.DLL" (ByVal Port As Integer, ByVal Data As Long)
Public Declare Function PortIn Lib "IO.DLL" (ByVal Port As Integer) As Byte
Public Declare Function PortDWordIn Lib "IO.DLL" (ByVal Port As Integer) As Long
Public Declare Sub SetPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Public Declare Sub ClrPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Public Declare Sub NotPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte)
Public Declare Function GetPortBit Lib "IO.DLL" (ByVal Port As Integer, ByVal Bit As Byte) As Boolean
Public Declare Function RightPortShift Lib "IO.DLL" (ByVal Port As Integer, ByVal Val As Boolean) As Boolean
Public Declare Function LeftPortShift Lib "IO.DLL" (ByVal Port As Integer, ByVal Val As Boolean) As Boolean
Public Declare Function IsDriverInstalled Lib "IO.DLL" () As Boolean

'********************************************************
'********* Function Descriptions *******************
'********************************************************

'PortOut - Outputs a byte to the specified port.

'PortWordOut - Outputs a word (16-bits) to the specified port.

'PortDWordOut - Outputs a double word (32-bits) to the specified port.

'PortIn - Reads a byte from the specified port.

'PortWordIn - Reads a word (16-bits) from the specified port.

'PortDWordIn - Reads a double word (32-bits) from the specified port.

'SetPortBit - Sets the bit of the specified port.

'ClrPortBit - Clears the bit of the specified port.

'NotPortBit - Nots (inverts) the bit of the specified port.

'GetPortBit - Returns the state of the specified bit.

'RightPortShift - Shifts the specified port to the right. The LSB is


' returned, and the value passed becomes the MSB.

'LeftPortShift - Shifts the specified port to the left. The MSB is


' returned, and the value passed becomes the LSB.

'IsDriverInstalled - Returns non-zero if io.dll is installed and


' functioning. The primary purpose of this function
' is to ensure that the kernel mode driver for
' NT/2000/XP has been installed and is accessible.

Nota4.-Para usar este codigo deberiamos copiar el archivo io.dll en c:\Windowa\System


o en d:\Windowa\System (Dependiendo donde esta el sistema operativo),Si no se quiere sobrecargar el
sistema operativo se puede tener el io.dll donde sea pero en la declaracion del modulo se debe dar el path o
la direccion donde esta el io.dll.
ejemplo.-Si tenemos el io.dll en e:\carpeta\io.dll el codigo en el modulo cambiaria a:
'********************************************************************
'Declarations for direct port I/O in 32-bit Visual Basic 6 programs.
' Funciona en W9x, ME, NT, 2000 y XP
'********************************************************************

Public Declare Sub PortOut Lib " e:\carpeta\IO.dll " (ByVal Port As Integer, ByVal Data As Byte)
Public Declare Sub PortWordOut Lib " e:\carpeta\IO.dll " (ByVal Port As Integer, ByVal Data As Integer)
Public Declare Sub PortDWordOut Lib " e:\carpeta\IO.dll " (ByVal Port As Integer, ByVal Data As Long)
.
.
.
Y asi sucesivamente
Programación de un Juego de Luces Código
Supongamos que queremos el siguiente juego de luces HEX

1 80

2 40

3 20

4 10

5 08

6 04

7 02

8 01

9 02

10 04

11 08

12 10

Nota5.-Podemos Notar que nuestro juego de luces tiene 12 estados y también se saco el Hex del Byte.
Idea de programación usando un contador mandar si el cont=1 mando el Hex 80 cuando es 2 mando el Hex
40 y asi sucesivamente hasta llegar al 12 donde seria mi condición de reseteo.

En el formulario primero nos vamos a crear:


1 Frame(Caption Port888)
1 Timer (Interval->10(Que seria 10ms),Enabled->true)
8 Shapes(Backstyle->1 Opaque,shape->Circle)
1 label

Este Frame nos sevira par saver el estado del puerto.

Su codigo del timer1 es:


Private Sub Timer1_Timer()
Label1.Caption = PortIn(888) 'Testeando todo el Byte y mostrándolo
'*********Ahora testeamos Bit por Bit**********
Dim c1 As Variant
c1 = vbRed
Dim c2 As Variant
c2 = vbGreen

If GetPortBit(888, 7) = True Then


Shape1.BackColor = c1
Else
Shape1.BackColor = c2
End If

If GetPortBit(888, 6) = True Then


Shape2.BackColor = c1
Else
Shape2.BackColor = c2
End If

If GetPortBit(888, 5) = True Then


Shape3.BackColor = c1
Else
Shape3.BackColor = c2
End If

If GetPortBit(888, 4) = True Then


Shape4.BackColor = c1
Else
Shape4.BackColor = c2
End If

If GetPortBit(888, 3) = True Then


Shape5.BackColor = c1
Else
Shape5.BackColor = c2
End If

If GetPortBit(888, 2) = True Then


Shape6.BackColor = c1
Else
Shape6.BackColor = c2
End If

If GetPortBit(888, 1) = True Then


Shape7.BackColor = c1
Else
Shape7.BackColor = c2
End If

If GetPortBit(888, 0) = True Then


Shape8.BackColor = c1
Else
Shape8.BackColor = c2
End If

End Sub

Ahora Adicionamos otro reloj donde programaremos el juego de luces

Timer2(enabled->False,Interval->300)
2 commandButton (Caption->Inicio el otro Pause )‘ Estos botones uno nos serira para Iniciar nuestro juego y el
otro
para que lo coloquemos en pausa
El código en el timer 2 es: Antes declaramos cont como variable global (Arriba de todo nuestro codigo)

Option Explicit
Dim cont As Integer

Private Sub Form_Load()


cont = 1
Call PortOut(888, 0)
End Sub

Private Sub Command1_Click()


Timer2.Enabled = True 'Habilito el reloj
End Sub

Private Sub Command2_Click()


If Timer2.Enabled = True Then 'Cuando haga click habilita otro click deshabilita
Timer2.Enabled = False
Else
Timer2.Enabled = True
End If
End Sub

Private Sub Timer2_Timer()


Select Case cont
Case 1:
Call PortOut(888, &H80)
Case 2:
Call PortOut(888, &H40)
Case 3:
Call PortOut(888, &H20)
Case 4:
Call PortOut(888, &H10)
Case 5:
Call PortOut(888, &H8)
Case 6:
Call PortOut(888, &H4)
Case 7:
Call PortOut(888, &H2)
Case 8:
Call PortOut(888, &H1)
Case 9:
Call PortOut(888, &H2)
Case 10:
Call PortOut(888, &H4)
Case 11:
Call PortOut(888, &H8)
Case 12:
Call PortOut(888, &H10)
cont = 0 ' Condicon de reseteo
End Select
cont = cont + 1
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call PortOut(888, 0)
End Sub

Entrada de datos.

Para la entrada es muy importante tener en cuenta que al mandar pulsos hay flanco tanto de subida como de
bajada y para poder controlarla solo debemos recurrir a uno de los siguientes pseudocodigos:
Flanco Negativo
INICIO

1
Bit?

Estado=1
0

0
Estado?

Estado=0

1
Deteccion(Cont=Cont+1)
Estado=0
Flanco Positivo
INICIO

0
Bit?

Estado=0
1

1
Estado?

Estado=1
0

Deteccion(Cont=Cont+1)
Estado=1
Flanco Negativo y
Positivo INICIO

0
Bit?

1
0
Estado?
1
Estado? 1
Estado=0
Detección(Cont=Cont+0.5)
0 Estado=0
Estado=1
Deteccion(Cont=Cont+0.5)
Estado=1

Nota 6.- Estos diagramas sirven para Un bit si se recuperaria todo el byte con el truco de enmascaramiento se
filtra el bit Por ejemplo si recuperaríamos 00001010 para filtrar el bit1 hago un and .( 00001010 and
00000010 )

Programa de velocímetro con el bit 7


Idea Testeo el bit 7 y cada que haya un pulso lo cuento y con otro reloj reinicio cada segundo de esta manera
saco cuantos pulsos se hace en un segundo
Timer1
Label1 (interval->10)

Label2
Timer2
(interval->10)

Label3

Nota7.Los shapes tienen sus propiedad shape en circle y su backstyle en 1-Opaque Timer3
'********************************************************* (interval->1000)
'Programa que nos da el estado del pin7 suponiendo que cada
'que se igresa un pulso es 1 vuelta
'*********************************************************
'Variables Globales
Dim cont As Double 'contador del bit de entrada
Dim estado As Integer ' Para controlar si era cero o uno el bit en cuestion
Dim vel As Double 'velocidad de entrada
Private Sub Timer1_Timer() ‘Para tener un testeador de mi Puerto 889

'********
Label1.Caption = PortIn(889) 'Testeando el Byte de entrada
'********

'*********Ahora testeamos Bit por Bit**********


Dim c1 As Variant
c1 = vbRed
Dim c2 As Variant
c2 = vbGreen

If GetPortBit(889, 7) = verdadero Then


Shape1.BackColor = c1
Else
Shape1.BackColor = c2
End If
If GetPortBit(889, 6) = verdadero Then
Shape2.BackColor = c1
Else
Shape2.BackColor = c2
End If

If GetPortBit(889, 5) = verdadero Then


Shape3.BackColor = c1
Else
Shape3.BackColor = c2
End If

If GetPortBit(889, 4) = verdadero Then


Shape4.BackColor = c1
Else
Shape4.BackColor = c2
End If

If GetPortBit(889, 3) = verdadero Then


Shape5.BackColor = c1
Else
Shape5.BackColor = c2
End If
End Sub

Private Sub Timer2_Timer() 'flanco negativo


If ((GetPortBit(889, 7) = verdadero)) Then
If (estado = 1) Then
estado = 1
Else
cont = cont + 0.5
co1 = co1 + 0.5
estado = 1
End If
Else
If (estado = 1) Then
cont = cont + 0.5
co1 = co1 + 0.5
estado = 0
Else
estado = 0
End If
End If
End Sub

Private Sub Timer3_Timer()


Label2.Caption = cont & " Hz"
vel = cont
vel = vel * 60 'por si quiero en rpm *60 si no en Hz
Label3.Caption = vel & " RPM"
cont = 0
End Sub

Nota8.-Si se Quiere testear mas bits se deberia en el mismo reloj de testeo copiar el detector de flanco y
hacerlo para otro bit y asi sucesivamente.Por si Quieren hacer otra cosa que no sea contar por ejemplo que
apague el formulario cuando haga clic en un pulsador solo se debe cambiar el cont=cont+1 por lo que quieren
hacer.
EL CONTROL MICROSOFT COMM

El control MSComm no está normalmente en la caja de herramientas, por lo que será necesario
introducirlo mediante Proyecto | Componentes.

En el formulario solamente se le ve en tiempo de diseño. El icono que lo representa en la caja de


herramientas coincide con el que presenta en el formulario:

Al tratarse de un control personalizado, presenta dos formas de ver las propiedades. Si hacemos
click con el botón derecho del ratón sobre el control y vamos a propiedades, nos presenta tres
cuadros de configuración de los típicos de los controles personalizados. Si seleccionamos el control
MSComm y pulsamos F4 , aparecerá la caja de propiedades típica de los controles VB.

PRPIEDADES

Existen propiedades que pueden establecerse en tiempo de diseño o en tiempo de ejecución, y otras
que solamente se pueden ejecutar o consultar en solamente en tiempo de ejecución. Se detallan a
continuación las primeras. Las segundas se enumerarán tras estas, aunque se nombran algunas de
estas últimas al explicar cada una de las propiedades del primer tipo.

CommPort
Indica el número del puerto serie usado. Admite los valores de 1 a 255. Cambiando esa propiedad
podemos cambiar el puerto de comunicación que vamos a usar (Un PC tiene normalmente 2 puertos
serie : El Com1 y el Com2. Puede tener sin grandes problemas Hardware hasta 4 (Com3 y Com4)
Si le damos a ese valor un número de puerto inexistente, dará error.

Settings

Sintaxis Velocidad, Paridad, Bits de información, Bits parada

Indica la velocidad, paridad, número de bits y bits de stop (parada) que se van a usar en la
comunicación.

Los valores posibles para velocidad son : Indica la velocidad en baudios.

50 100 110 300 600 1200 2400 4800 9600 14400 19200 y 28800

Los valores posibles para paridad son :

N - No envía bit de paridad ni hace comprobación de paridad en la recepción.


O - Envía y comprueba paridad, con el criterio de paridad IMPAR
E - Envía y comprueba paridad, con criterio de paridad PAR

Los valores para el parámetro Bits de Información pueden ser :

7 - Se envían / reciben 7 bits por trama de información.


8 - Se envían / reciben 8 bits por trama de información
5 - Se envían / reciben 5 bits por trama de información. Este valor de 5 bits es el típico del
sistema Baudot para transmisión telegráfica (Teletipos) que se ha conservado en las
comunicaciones informáticas por pura tradición. Si se eligen 5 bits, los bits de parada se ponen
automáticamente a 1,5 (Típico también del sistema Baudot.)

Los valores para el parámetro Bits de parada pueden ser :

1 - Se envía un bit de parada


2 - Se envían 2 bits de parada

(No es posible programar 1,5 bits de parada. Sólo lo hace cuando se programan 5 bits de
información y lo hace automáticamente).

Handshaking

Especifica el método de control sobre el flujo de información. En una comunicación serie se necesita
conocer si el puerto puede enviar información (necesita saber si el módem está preparado para
recibirla) y necesita indicarle al módem que él está preparado para recibir información. A este
proceso se le denomina Handshaking. (Handshaking = Control de Flujo)
(Como sabrá por sus conocimientos de inglés, Handshaking significa apretón de manos, ponerse de
acuerdo. Y ponerse de acuerdo entre dos terminales que van a comunicarse es establecer las
condiciones de control que uno va a tener sobre otro.)

El Control de Flujo puede hacerse de dos formas : Una mediante las señales auxiliares del puerto
(RTS, CTS, DSR, DTR), que son cables adicionales que tendrán una tensión positiva respecto a los
0V del equipo si esa señal está activada, o una tensión negativa si no lo está. Este tipo de control del
flujo de información es el típico para comunicarse el ordenador con un módem.

Existe otra forma de controlar el flujo de información : mediante señales especiales que se envían
por los dos cables que transportan la información. Mediante estas dos señales podemos controlar
que el ordenador envíe información o deje de enviarla. De igual forma, podemos indicarle al módem
que envíe o no envíe. Estas señales especiales se denominan X-ON y X-OFF.

La propiedad Handshaking controla la forma de realizar este proceso. Puede tomar los siguientes
valores :

0 - No existe Control de Flujo


1 - Control de Flujo mediante XON - XOFF
2 - Control de Flujo mediante Request To Send (RTS) y Clear To Send (CTS)
3 - Control de Flujo mediante XON - XOFF y RTS - CTS
Los tres tipos de Control de Flujo tiene cada uno su aplicación.

InBufferSize

Mediante esta propiedad establecemos el tamaño del Buffer (almacén de datos) de entrada. Este
Buffer sirve para poder recibir datos sin que tenga que intervenir la aplicación continuamente para
controlar el puerto de entrada.

Puede conocerse el número de caracteres presentes en el Buffer de entrada consultando el valor de


la propiedad InBufferCount.

OutBufferSize

Mediante esta propiedad controlamos el tamaño del Buffer de salida.

El tamaño de los Buffers dependerá de la aplicación y de la velocidad de comunicación. Si la


aplicación tiene muchas cosas que hacer, aparte de controlar el puerto de comunicaciones, se
deberá poner un Buffer grande. Tanto mas grande cuanta mayor sea la velocidad de transferencia
de datos.

Puede conocerse el número de caracteres presentes en el Buffer de salida (los que aún están por
transmitir), consultando el valor de la propiedad OutBufferCount.

RThreshold, SThreshold

Estas dos propiedades especifican el número de caracteres que deben estar presentes en los
Buffers de Recepción y Transmisión respectivamente, para que se produzca el evento OnComm
relativo a recepción y transmisión de caracteres. (Eventos EvReceive y EvSend) Si el valor de una
de estas propiedades está a 0, no se produce el evento OnComm correspondiente.

El valor que se debe dar a estas dos propiedades depende de la aplicación y del tiempo que
queramos que la aplicación está atendiendo al puerto de comunicaciones. Concretamente para la
propiedad RThreshold debemos pensar muy bien el valor que se le pone. Si ponemos un valor corto
(1 es el mínimo), cada vez que reciba un carácter se producirá el evento OnComm. (Vea la
descripción de eventos mas adelante). Al producirse este evento, ejecutará el procedimiento
asociado a él, lo que hará perder tiempo a la aplicación, impidiéndole realizar otras funciones. Si se
pone un valor muy alto, el puerto no avisará que tiene caracteres recibidos hasta que reciba un
número igual al programado en esta propiedad, por lo que no podremos procesar los datos recibidos
hasta que el buffer tenga ese número de caracteres en su interior. En número adecuado dependerá
del tipo de aplicación que vayamos a realizar. En cualquier caso, este número será inferior al número
programado para la longitud del buffer, (InBufferSize)
InputLen

Por defecto, cuando se lee el Buffer de recepción, se leen todos los caracteres, quedando el Buffer
vacío. Si se le asigna a esta propiedad un valor distinto de 0, cada vez que leamos el Buffer de
recepción leerá un número de caracteres igual a esa cantidad, permaneciendo los caracteres
restantes en el Buffer a la espera de una nueva lectura. Asignándole el valor 0 (Valor por defecto), el
buffer se lee completo.

ParityReplace

Si la comunicación se realiza con bit de paridad (Par o Impar), en recepción se comprueba byte a
byte la recepción de la paridad correcta. Si se recibe un Byte que no tiene paridad correcta, lo mas
probable es que ese Byte (carácter) se haya recibido defectuoso. Esta propiedad nos permite
sustituir un carácter que ha llegado con bit de paridad incorrecto por otro carácter. ( ?
predeterminado). Se puede sustituir por una cadena de caracteres (Error, por ejemplo).

NullDiscard

Cuando se recibe el carácter nulo (00000000) puede ser que no sirva para nada a efectos de
nuestra aplicación, o que este carácter sea un dato mas. Esta propiedad acepta los valores True /
False. Si es True se desprecia el carácter Nulo. Si es False, se toma como un carácter mas.

CTSTimeout

Es el tiempo (en milisegundos) que permanece esperando la señal CTS (Señal CTS - Dispuesto
para enviar), señal de entrada al ordenador que debe estar presente antes de que el puerto
comience a enviar información. El tiempo se mide desde que se pone activa la señal de salida RTS
(Petición de envío). Si se supera este tiempo entre el instante de activación de la señal RTS y la
recepción de la señal CTS, se produce el evento CTSTO. Poniendo 0 en esta propiedad, se
deshabilita, y en estas condiciones no se producirá nunca el evento CTSTO.

CDTimeout

Es el tiempo máximo de espera (en milisegundos) desde que se activa la señal DTR hasta que se
recibe la señal CD (Carrier Detect - Detección de portadora). Este tiempo solamente tendrá
importancia en ciertas aplicaciones donde se espere recibir CD continuamente. No tendrá sentido
cuando la aplicación se queda en espera a recibir una comunicación, pero sin saber cuando la tiene
que recibir. Si transcurre el tiempo programado en esta propiedad, ocurrirá el evento CDTO.
Poniendo el valor 0 se deshabilita esta propiedad y no se producirá nunca el evento CDTO.

DSRTimeout

Similar a la anterior, pero en vez de esperar la señal CD se espera la señal DSR. Esta propiedad sí
tiene sentido, ya que si, por ejemplo, estamos conectados con un módem, y nuestra aplicación se
pone a la espera de recibir alguna llamada, activa la salida DTR, y espera recibir inmediatamente la
respuesta de que el módem está dispuesto, mediante la línea DSR. Si transcurre el tiempo
programado sin recibir la señal DSR se producirá el evento DSRTO . Poniéndola a 0, se deshabilita
esta propiedad y nunca ocurrirá el evento DSRTO.

RTSEnable

Activa (Pone a 1) la señal RTS (Request To Send - Petición de envío) Esta señal debe ponerse a 1
para indicar al módem (o al equipo que va a recibir nuestra comunicación) que deseamos enviar
datos. Debe estar activada durante toda la transmisión de datos.

Cuando se pone la propiedad Handshaking a 2 (control con RTS / CTS) ó 3 (Control con RTS / CTS
y con X-ON / X-OFF) no debemos preocuparnos de poner a 1 la señal RTS, pues lo hace
automáticamente el puerto de comunicaciones. Esta propiedad está ahí para aplicaciones donde no
se emplee ese tipo de Handshaking y necesitemos activar algo antes de transmitir. (Caso por
ejemplo de transmisión de datos por radio, donde podemos usar esta señal de salida para activar el
PTT (Push To Talk - Pulse para hablar) y poner el transmisor en marcha)

DTREnable

Activa (Pone a 1) la salida DTR (Data Terminal Ready - Terminal de Datos Listo). Esta señal se
emplea para decirle al módem que el terminal (Ordenador) está preparado para recibir datos.

Se hace la misma observación que para la propiedad anterior respecto a los valores de la propiedad
Handshaking

Interval

Indica el tiempo (en milisegundos) del intervalo entre una y otra comprobación del estado de
recepción del puerto. El valor mínimo es de 55 ms.

El análisis del puerto de comunicación no tiene nada que ver con la generación del evento OnComm.
Este evento se producirá cuando se cumplan las condiciones para ello, independientemente del
tiempo programado en esta propiedad. La comprobación del puerto cada intervalo de tiempo
marcado por esta propiedad solamente afecta a averiguar el estado de las líneas auxiliares CD, DSR
y CTS, y para saber el número de caracteres existentes en los Buffers de transmisión y recepción.

Las siguientes propiedades no difieren en nada respecto a otros controles :

Left, Name, Index, Top, Tag

Propiedades propias del tiempo de ejecución

PortOpen
Abre el puerto de comunicación. Puede tener los valores True (Para abrirlo) y False (Para cerrarlo)
Si tenemos un MSComm con Nombre (Name) MSComm1, para abrirlo ejecutaremos la siguiente
sentencia :

MSComm1.PortOpen = True

Para cerrarlo, ejecutaremos :

MSComm1.PortOpen = False

InBufferCount.

Nos permite averiguar cuantos caracteres tenemos en el Buffer de entrada. Con el mismo MSComm
anterior, comprobaremos el número de caracteres sin leer con la sentencia :

caracteressinleer = MSComm1.InBufferCount

OutBufferCount

Nos permite conocer cuantos caracteres quedan por transmitir en el Buffer de salida. Emplearemos
la sentencia :

caracteressinenviar = MSComm1.OutBufferCount

Output

Envía caracteres al Buffer de salida. Debe existir un signo igual ( = ) entre Output y lo que se envía al
Buffer. Para enviar la frase Curso de Visual Basic ejecutaremos la sentencia :

MSComm1.Output = “Curso de Visual Basic”

Si deseamos enviar el contenido de una variable

MSComm1.Output = variable

Input

Lee el Buffer de recepción. El número de caracteres leídos dependerá del valor de la propiedad
InputLen. Cuando la propiedad InputLen tiene el valor 0, el Buffer se lee completo. Si InputLen tiene
un valor distinto de 0, se leerá un número de caracteres igual al valor de esta propiedad.

CommEvent

Devuelve el evento mas reciente que ha ocurrido para generar el evento general OnComm (Vea
mas adelante). Esta propiedad no está disponible en tiempo de diseño y es de sólo lectura en tiempo
de ejecución.

Sintaxis NombredelMSComm.CommEvent

Break

Devuelve un valor (True / False) que indica que se ha recibido la señal Break.

variable = MSComm1.Break

CDHolding

Devuelve el estado de la línea de control CD (Detección de Portadora) Si es True, esa entrada está
activada, si es False, la entrada está desactivada.
variable = MSComm1.CDHolding

CTSHolding

Devuelve el estado de la línea de control CTS (Dispuesto para enviar) Si es True, esa entrada está
activada, si es False, la entrada está desactivada.
variable = MSComm1.CTSHolding

DSRHolding

Devuelve el estado de la línea de control DSR (Data Set Ready ) Si es True, esa entrada está
activada, si es False, la entrada está desactivada.
variable = MSComm1.DSRHolding

EVENTOS DEL MSComm

El MSComm tiene varios eventos, pero un solo Procedimiento : el Procedimiento OnComm. Este
procedimiento se ejecuta cada vez que se produce alguno de los eventos del MSComm.
Esto quiere decir que para escribir el código apropiado en el procedimiento del MSComm será
necesario analizar qué evento se ha producido y colocar, mediante una sentencia If .. Then el
código apropiado para cada uno de los eventos que se produzcan.

Para averiguar qué evento se ha producido puede hacerse consultando el valor de la propiedad
CommEvent. (Se toma como nombre del MsComm el de MsComm1)

If MsComm1.CommEvent = ComEvRing Then

'Se ha consultado si el evento particular que ha producido el evento general OnComm


'ha sido el ComEvRing (Se está recibiendo la llamada del teléfono). En esta sentencia
‘If Then deberemos colocar el código necesario para que la aplicación se prepare para
‘recibir una comunicación a través del módem.

End If

Los eventos del Comm pueden identificarse por una constante o un número. La constante, como
todas las de Visual Basic, tiene una expresión bastante difícil. Se pone entre paréntesis el número
que identifica a ese evento. Este número debe declararse como Integer.

Se ejecutará el Procedimiento OnComm cuando ocurra alguno de los siguientes eventos :

ComEvCD (5) Cambio en la línea CD. Para conocer el estado actual de esa línea
(Activado/Desactivado) deberemos invocar la propiedad CDHolding

ComEvCTS (3) Cambio en la línea CTS. Igual que la anterior, este evento solamente
nos indica que ha existido un cambio. Para averiguar el estado en que
se encuentra esta línea, debemos invocar la propiedad CTSHolding

ComEvDSR (4) Cambio en la línea DSR. Igual que las anteriores. Debemos invocar la
propiedad DSRHolding para averiguar su estado actual.

ComEvRing (6) Cambio en la línea de detección de llamada (Ring). Este evento se


produce cuando hay un cambio en la línea Ring (Detección de
llamada en el módem)
No existe una propiedad para averiguar el estado de la línea Ring
pues no es necesario. Lo importante de esta línea es que está
cambiando, es decir, el teléfono está sonando y poco importa que
analicemos si la línea Ring está a 1 o a 0, pues toda llamada
telefónica es intermitente. Dependiendo de la UART de su PC, puede que
este evento no lo soporte.

ComEvReceive( 2 ) Cuando se recibe un número igual o mayor de caracteres que el


indicado en la Propiedad RThreshold

ComEvSend (1) Cuando quedan en el búfer de transmisión menos caracteres que los
indicados en la Propiedad SThreshold

ComEvEOF (7) Recibido un carácter de fin de archivo (carácter ASCII 26) .

comEventBreak (1001) Se ha recibido una señal de interrupción. (Break)

ComEventCDTO (1007) Tiempo de espera de Detección de portadora. La línea


Detección de portadora (CD) estuvo baja durante el periodo de tiempo
especificado en la Propiedad CDTimeout, mientras se intentaba transmitir
un carácter.
ComEventCTSTO 1002 Tiempo de espera de Preparado para enviar. La línea
Preparado para enviar (CTS) estuvo baja durante el periodo de tiempo
especificado en la propiedad CTSTimeout mientras se intentaba
transmitir un carácter.

ComEventDSRTO 1003 Tiempo de espera de Equipo de datos preparado. La línea


Equipo de datos preparado (DSR) estuvo baja durante el periodo de
tiempo especificado en la Propiedad DSRTimeout mientras se
intentaba transmitir un carácter.

ComEventOverrun 1006 Se sobrepasó la capacidad del Buffer de entrada sin haber


leído todos los caracteres. Los caracteres no leídos se han perdido.
Debemos aprovechar este evento para solicitar al colateral una
repetición de los datos perdidos.

ComEventRxOver 1008 Desbordamiento del búfer de recepción. No hay espacio para


más datos en el búfer de recepción.

ComEventRxParity 1009 Error de paridad. El hardware ha detectado un error de


paridad.

ComEventTxFull 1010 Búfer de transmisión lleno. El búfer de transmisión estaba


lleno cuando se ha intentado agregar un carácter a la cola de
transmisión. Este error es fácil de evitar, analizando el valor
de la propiedad OutBufferCount antes de enviar mas datos al buffer
de salida.

ComEventDCB 1011 Error inesperado al recuperar el Bloque de control de


dispositivos (DCB) para el puerto.

ComEventFrame 1004 Error de trama. El hardware ha detectado un error de trama.

NOTA ADICIONAL El puerto de comunicaciones.

El puerto de comunicaciones de un PC está formado por varias entradas / salidas. El soporte físico
es un conector tipo Sub-D de 9 ó 25 contactos, macho en ambas versiones. Se necesita por tanto un
cable con conector Sub-D hembra de 9 o 25 pines para acceder a él.

La distribución de las señales en cada uno de sus pines es la siguiente :

GND (Potencial de 0 V.).

TxD Transmisión de datos. Es una salida del ordenador. Por ella salen los datos en serie.

RxD Recepción de datos. Es una entrada del ordenador. Por ella entran los datos en serie.
RTS Request To Send. Petición de envío. Es una salida del ordenador. El ordenador pone a
1 esta señal cuando quiere enviar datos.

CTS Clear To Send. Dispuesto para enviar. Es una entrada del ordenador. Si está a 1
significa que el ordenador puede enviar datos pues el módem (o el dispositivo que
vaya a recibirlos) está preparado para hacerlo.

DSR Data Set Ready. Dispositivo de datos preparado. Es una entrada del ordenador. Le
indica que el módem está encendido y listo para funcionar.

DCD o CD Carrier Detect. Detección de portadora. Es una entrada del ordenador. Le


indica al ordenador que el módem está detectado señal de audio (tonos) válida.

DTR Data Terminal Ready. Terminal de datos listo. Es una salida del ordenador. Indica que
está listo para trabajar. Suele emplearse para indicar al módem que el ordenador está
dispuesto para recibir información.

Otra señal (disponible sólo en los ordenadores que tengan conector de 25 pines, y no en todos) es la
señal RING (timbre del teléfono) Es una entrada del ordenador. Le indica que está sonando el timbre
de la línea telefónica del módem.

Disposición de los pines en el ordenador

Dependiendo de si tiene conector de 9 pines o de 25, la distribución de estas señales físicamente en


el conector es :

Conector de 9 pines Conector de 25 pines

Pin Señal Pin

3 TxD 2
2 RxD 3
7 RTS 4
8 CTS 5
6 DSR 6
5 GND 7
1 CD 8
4 DTR 20
RING 22
Tierra de protección 1
(La señal RING no está disponible en el conector de 9 pines. La detección del Ring del teléfono se
realiza directamente por la línea RxD. El módem envía la palabra RING cuando suena el timbre del
teléfono. La tierra de protección tampoco se usa en este conector.

Null modem, an introduction

Serial communications with RS232. One of the oldest and most widely spread communication
methods in computer world. The way this type of communication can be performed is pretty well
defined in standards. I.e. with one exception. The standards show the use of DTE/DCE
communication, the way a computer should communicate with a peripheral device like a modem. For
your information, DTE means data terminal equipment (computers etc.) where DCE is the
abbreviation of data communication equipment (modems). One of the main uses of serial
communication today where no modem is involved—a serial null modem configuration with DTE/DTE
communication—is not so well defined, especially when it comes to flow control. The terminology null
modem for the situation where two computers communicate directly is so often used nowadays, that
most people don't realize anymore the origin of the phrase and that a null modem connection is an
exception, not the rule.

In history, practical solutions were developed to let two computers talk with each other using a null
modem serial communication line. In most situations, the original modem signal lines are reused to
perform some sort of handshaking. Handshaking can increase the maximum allowed communication
speed because it gives the computers the ability to control the flow of information. High amounts of
incomming data is allowed if the computer is capable to handle it, but not if it is busy performing other
tasks. If no flow control is implemented in the null modem connection, communication is only possible
at speeds at which it is sure the receiving side can handle the amount information even under worst
case conditions.

Original use of RS232

When we look at the connector pinout of the RS232 port, we see two pins which are certainly used
for flow control. These two pins are RTS, request to send and CTS, clear to send. With DTE/DCE
communication (i.e. a computer communicating with a modem device) RTS is an output on the DTE
and input on the DCE. CTS is the answering signal comming from the DCE.

Before sending a character, the DTE asks permission by setting its RTS output. No information will
be sent until the DCE grants permission by using the CTS line. If the DCE cannot handle new
requests, the CTS signal will go low. A simple but useful mechanism allowing flow control in one
direction. The assumption is, that the DTE can always handle incomming information faster than the
DCE can send it. In the past, this was true. Modem speeds of 300 baud were common and 1200
baud was seen as a high speed connection.

For further control of the information flow, both devices have the ability to signal their status to the
other side. For this purpose, the DTR data terminal ready and DSR data set ready signals are
present. The DTE uses the DTR signal to signal that it is ready to accept information, whereas the
DCE uses the DSR signal for the same purpose. Using these signals involves not a small protocol of
requesting and answering as with the RTS/CTS handshaking. These signals are in one direction
only.

The last flow control signal present in DTE/DCE communication is the CD carrier detect. It is not used
directly for flow control, but mainly an indication of the ability of the modem device to communicate
with its counter part. This signal indicates the existence of a communication link between two modem
devices.

Null modem without handshaking

How to use the handshaking lines in a null modem configuration? The simplest way is to don't use
them at all. In that situation, only the data lines and signal ground are cross connected in the null
modem communication cable. All other pins have no connection. An example of such a null modem
cable without handshaking can be seen in the figure below.

Simple null modem without handshaking

Connector 1 Connector 2 Function


2 3 Rx Tx
3 2 Tx Rx
5 5 Signal ground
Compatibility issues

If you read about null modems, this three wire null modem cable is often talked about. Yes, it is
simple but can we use it in all circumstances? There is a problem, if either of the two devices checks
the DSR or CD inputs. These signals normaly define the ability of the other side to communicate. As
they are not connected, their signal level will never go high. This might cause a problem.

The same holds for the RTS/CTS handshaking sequence. If the software on both sides is well
structured, the RTS output is set high and then a waiting cycle is started until a ready signal is
received on the CTS line. This causes the software to hang because no physical connection is
present to either CTS line to make this possible. The only type of communication which is allowed on
such a null modem line is data-only traffic on the cross connected Rx/Tx lines.

This does however not mean, that this null modem cable is useless. Communication links like present
in the Norton Commander program can use this null modem cable. This null modem cable can also
be used when communicating with devices which do not have modem control signals like electronic
measuring equipment etc.
As you can imagine, with this simple null modem cable no hardware flow control can be
implemented. The only way to perform flow control is with software flow control using the XOFF and
XON characters.

Null modem with loop back handshaking

The simple null modem cable without handshaking shows incompatibilities with common software.
The main problem with this cable is that there is a possibility for the software to hang if it checks the
modem signal lines in a proper way. I.e. with this null modem cable, good written programs will
perform worse than badly written programs.

To overcome this problem and still be able to use a cheap null modem communication cable with
only three lines in it, a fake null modem cable layout has been defined. The null modem cable with
loop back handshaking resulted from this.

Null modem with loop back handshaking

Connector 1 Connector 2 Function


2 3 Rx Tx
3 2 Tx Rx
5 5 Signal ground
1+4+6 - DTR CD + DTR
- 1+4+6 DTR CD + DTR
7+8 - RTS CTS
- 7+8 RTS CTS

The main purpose of this null modem cable is to let well defined software think there is handshaking
available, with a null modem cable which has no provisions for it.

Compatibility issues

Consider first the DSR signal (pin 6). This input indicates that the other side is ready to start
communicating. In the layout, the line is linked back to the DTR output (pin 4). This means, that the
software doesn't see the ready signal of the other device, but its own. The same holds for the CD
input (pin 1). The assumption is, that if software has been written to check the DSR line to test
communication availability, it will probably also set the DTR output to indicate its own state. This is
true for at least 99% of all serial communication software. This implies that at least 99% of all serial
communication software is capable of faking its own DSR check with this null modem cable.
The same trick is used with the CTS input. In the original use, RTS is set, and then CTS is checked
before starting the communication. By setting the RTS output (pin 7) the CTS input on the same
connector (pin 8) is receiving clearance immediately. There is no possibility of a software hangup
because of dangling RTS requests.

Other issues to consider

The null modem cable with loop back handshaking is often advised as the best low cost available null
modem cable. But, is it really so good? The simple null modem cable without handshaking has the
disadvantage that it does not permit proper written software to communicate with it. Software which is
aware of the lack of handshaking signals can however use it without problems.

The null modem cable with loop back handshaking can be used with more software, but it has no
functional enhancements over the simple cable! There is no way both devices can control data flow,
other than by using XON/XOFF handshaking. If the software is designed for using hardware flow
control it seems to work with this null modem cable, but on unpredictable moments, data loss may
occur. This means that the null modem cable allows communication as long as no flow control is
needed, but when data speeds reach the limit the receivers can handle, communication may stop
immediately without an assignable reason. Therefore, although this null modem cable is cheap and
easy to make, use it with care! Despite these warnings, this type of null modem cable has been used
successfully between Windows 95/98/ME computers with a Direct Cable Connection.

Null modem with partial handshaking

The simple null modem cable and the null modem cable with loop back handshaking are useful, but
have no provisions for hardware flow control. If it is absolutely necessary that hardware flow control is
used, the null modem with partial handshaking can be an alternative.

Null modem with partial handshaking

Connector 1 Connector 2 Function


1 7+8 RTS2 CTS2 + CD1
2 3 Rx Tx
3 2 Tx Rx
4 6 DTR DSR
5 5 Signal ground
6 4 DSR DTR
7+8 1 RTS1 CTS1 + CD2
Compatibility issues

This null modem cable is the best of two worlds. There is the possibility of hardware flow control
without being incompatible with the original way flow control was used with DTE/DCE
communication. Let us first consider the RTS/CTS flow control lines present on pins 7 and 8. As with
the loop back null modem cable, these signals are not connected to the other device, but directly
looped back on the same connector. This means, that RTS/CTS flow control is allowed to be used in
the software, but it has no functional meaning. Only when the software at the other side checks the
CD signal at pin 1, the RTS information will reach the other device. This would however be only the
case in specifically developed software which uses the CD input for this purpose.

More important however is the cross connection of the DSR (pin 6) and DTR (pin 4) lines. By cross
connecting these lines, their original function is simulated pretty well. The DTR output is used to
signal the other device that communication is possible. This information is read on the DSR input, the
same input used for this purpose with modem communication. Because of this cross connection, the
DTR output line can be used for simple flow control. Incomming data is allowed when the output is
set, and blocked if the output is not set.

Software using only the RTS/CTS protocol for flow control cannot take advantage of the partial
handshaking null modem cable. Most software however will also check the DSR line and in that case
—when using the null modem cable with partial handshaking—the best possible hardware flow
control can be achieved which is still compatible with the original use with modems.

Null modem with full handshaking

The most expensive null modem cable is the null modem cable suitable for full handshaking. In this
null modem cable, seven wires are present. Only the ring indicator RI and carrier detect CD signal
are not linked. The cable is shown in the following figure.

Null modem with full handshaking

Connector 1 Connector 2 Function


2 3 Rx Tx
3 2 Tx Rx
4 6 DTR DSR
5 5 Signal ground
6 4 DSR DTR
7 8 RTS CTS
8 7 CTS RTS
Compatibility issues

The null modem cable with full handshaking does not permit the older way of flow control to take
place. The main incompatibility is the cross connection of the RTS and CTS pins. Originally, these
pins are used for a question/answer type of flow control. When the full handshaking null modem
cable is used, there is no request anymore. The lines are purely used for telling the other side if
communication is possible.

The main advantage of this cable is, that there are two signalling lines in each direction. Both the
RTS and DTR outputs can be used to send flow control information to the other device. This makes it
possible to achieve very high communication speeds with this type of null modem cable, provided
that the software has been designed for it. Because of the high possible connection speed, this null
modem cable can be used with Interlink to connect two MS-DOS PC's.

This is the type of cable Microsoft recommends for the direct cable connection in their knowledge
base article. For the DB9 connector they also added a connection of DTR to CD on each connector
but they didn't define this connection for the DB25 connector version and they also didn't mention the
CD input in the descriptive text, so it is safe to leave the CD input disconnected.

Null modem layout selection table

The right null modem cable to choose mainly depends on the application and the software that will be
used. As a general guide line, I would advise the following.

Choose your null modem cable


Cable without Loop back Partial Full
 
handshaking handshaking handshaking handshaking
Software flow
+++ ++ + +
control only
DTE/DCE compatible
hardware flow control - +++ ++ -
at low speeds
DTE/DCE compatible
hardware flow control - + +++ -
at high speeds
High speed
communication - - ++ +++
using special software
+++ Recommended cable
++ Good alternative
+ Works, but not recommended
- Does not work

The null modem cable with partial handshaking works in most cases. If you are developing software
which must work with all kinds of cables, it is best to use software flow control only and ignore all
modem control inputs.

Ejemplo.

Codigo:

Option Explicit
Dim puertoabierto As Boolean

Private Sub abrirpuerto_Click()


If puertoabierto = True Then Exit Sub
' Usar COM#
MSComm1.CommPort = Text3.Text
' 9600 baudios, sin paridad, 8 bits de datos y 1
' bit de parada.
MSComm1.Settings = "9600,N,8,1"
' abrir puerto
MSComm1.PortOpen = True ' Abrir puerto
puertoabierto = True
lab_estado.Caption = "Puerto Abierto"
End Sub
Private Sub borrar_Click()
'borrar caracteres
texto_a_rec.Text = ""
texto_a_env.Text = ""
End Sub

Private Sub cerrarpuerto_Click()


If puertoabierto = False Then Exit Sub
MSComm1.PortOpen = False 'cerrar puerto
puertoabierto = False
lab_estado.Caption = "Puerto Cerrado"
End Sub

Private Sub salir_Click()


'salir
Unload Me
End Sub

Private Sub texto_a_env_KeyPress(KeyAscii As Integer)


If puertoabierto = False Then Exit Sub
' Envía la pulsación al puerto.
MSComm1.Output = Chr$(KeyAscii)
End Sub

'coloca el cursor en texto_a_env cuando se pulsa en texto_a_rec


Private Sub texto_a_rec_GotFocus()
texto_a_env.SetFocus
End Sub

Private Sub Timer1_Timer()


Dim d As String
If puertoabierto = False Then Exit Sub
d = MSComm1.Input
If d = Chr(13) Then d = Chr(13) + Chr(10) ' para detectar el enter
texto_a_rec.Text = texto_a_rec & d
End Sub
Control Microsoft Winsock

El control WinSock permite conectarse a un equipo remoto e intercambiar datos con los Protocolos
UDP y TCP. Ambos protocolos se pueden usar para crear la comunicación con cualquier servicio de
los expresados anteriormente. Podemos crear también aplicaciones que residan en un servidor al
que accedemos desde varios clientes. Estamos en ese caso creando aplicaciones Cliente - Servidor

El control Winsock podríamos decir que es el control más elemental de los controles que VB dedica
a las redes IP, ya que lo único que hace por sí es conectarnos.

El control Winsock hay que meterlo en la caja de herramientas. (Proyecto | Componentes) El nombre
del control es Microsoft Winsock Control 6.0 Solamente se ve en tiempo de diseño. Tiene esta
forma:

Primera tarea ¿Qué dirección IP tiene mi equipo?


Esa es la primera pregunta que se le puede ocurrir. Decíamos más atrás que cuando nos
conectamos a Internet a través de conexión telefónica a redes no sabemos en principio que
dirección IP tenemos. Incluso cuando hacemos un programa para instalarlo en una Red de Area
Local (RAL) que tiene un número IP fijo, a lo mejor nos interesa obtener automáticamente ese
número para evitar tener que personalizar el programa para cada uno de los ordenadores. El control
WinSock nos permite conocer el número IP de nuestra conexión. Esto se logra mediante la
propiedad LocalIP
Propiedad LocalIP
Devuelve la dirección IP de la máquina local en el formato xxx.xxx.xxx.xxx Es de sólo lectura y no
está disponible en tiempo de diseño.

Sintaxis MiVariable = NombredelWinSock.LocalIP

MiVariable será una variable de tipo String. Si la dirección de su equipo es la 127.0.0.1 significa que
no está conectado.
Segunda tarea ¿Qué nombre tiene mi equipo?
Cuando nos conectamos a otro equipo, necesitaremos decirle quien somos. Esto se logra buscando
el nombre de nuestro equipo. Ese nombre se lo hemos introducido al instalar Windows. Vea un poco
mas adelante como se hace eso. Para leer el nombre de nuestro equipo utilizaremos la propiedad
LocalHostName del control Winsock.

Propiedad LocalHostName
Devuelve el nombre de la máquina local. Es de sólo lectura y no está disponible en tiempo de
diseño.

Sintaxis MiVariable = NombredelWinsock.LocalHostName

(MiVariable será una variable tipo String)

Tercera tarea: Establecer el protocolo


El protocolo es el tipo de comunicación que se va a establecer, UDP o TCP. Esto se realiza
mediante la propiedad Protocol. Puede establecerse en tiempo de diseño, en la ventana de
propiedades, o en tiempo de ejecución. Normalmente una aplicación trabaja solamente en UDP o en
TCP, por lo que esta propiedad debe establecerse o bien en diseño, o inmediatamente después de
iniciarse.

Propiedad Protocol

Devuelve o establece el protocolo, TCP o UDP

Sintaxis NombredelControlWinsock.Protocol = Valor

Donde Valor = 0 (sckTCPProtocol) para establecer protocolo TCP


Valor = 1 (sckUDPProtocol) para establecer protocolo UDP

El control debe estar cerrado para poder establecer esta propiedad. Si lo tiene abierto, debe cerrarlo
previamente mediante el método Close.

Cuarta tarea: Establecer los datos del equipo remoto

Aquí debemos distinguir si queremos enviar información o si deseamos recibirla. Ya tenemos que
comenzar a pensar en un concepto que seguro que le suena: cliente y servidor.

Cuando un equipo quiere enviar información debe conocer la dirección completa del equipo al que
va a llamar. La dirección completa es su dirección IP y el puerto al que va dirigida la información. Si
el equipo va a recibir, lo único que debemos decirle es el puerto por el que debe estar escuchando.
No necesita conocer más datos, ya que la dirección IP propia ya la conoce y no necesita conocer
ningún dato del equipo que le va enviar información.

Para el equipo cliente.

Si queremos enviar información, es decir, si queremos que nuestra aplicación sea una aplicación
cliente, debemos indicarle al Winsock el número IP o el DNS de la máquina con la que queremos
conectar. Esto lo establecemos con la propiedad RemoteHost. También le debemos indicar el
número del puerto en el que nos está esperando esa máquina. Esta información se la introducimos
con la propiedad RemotePort. Nunca le debemos forzar el puerto propio.

Propiedad RemoteHost

Devuelve o establece el equipo remoto al que se van a enviar los datos, o el equipo del que los
recibe. El equipo remoto se le puede identificar por su número IP o por su DNS.

Sintaxis NombredelControlWinsock.RemoteHost = “217.126.179.96”


NombredelControlWinsock.RemoteHost = “FTP://ftp.laguiadelestudiante.com”

VariableTipoString = NombredelControlWinsock.RemoteHost

Esta propiedad puede cambiarse en tiempo de ejecución cuantas veces sea necesario, para
encaminar los datos transmitidos a uno u otro equipo remoto.

Otro parámetro que es necesario introducir al Winsock cuando nuestra aplicación es una aplicación
cliente (envía información) es el puerto del equipo remoto al que vamos a enviar información. El
puerto destino dependerá del servicio que estamos implementando en nuestra aplicación. Este
parámetro se introduce en la propiedad RemotePort.

Propiedad RemotePort
Devuelve o establece el número del puerto remoto con el que conectar. El valor pasado en esta
propiedad es un Long comprendido entre 1 y 65535. El numero predeterminado es el 80.

Sintaxis NombredelControlWinsock.RemotePort = puerto

En una aplicación cliente (recibe información) no se puede establecer esta propiedad.

Ya tenemos establecidas las propiedades que necesita un control Winsock para enviar datos a un
equipo remoto. Veamos ahora como se establece la comunicación.

Para el equipo servidor

El equipo que va a recibir información solamente necesita conocer el puerto por el que debe
escuchar. Esto se lo decimos mediante la propiedad LocalPort.
Propiedad LocalPort
Devuelve o establece el puerto local que desea usar. Es de lectura y escritura, y está disponible
tanto en tiempo de diseño como en tiempo de ejecución.

Esta propiedad solamente debe utilizarse para poner Winsock a recibir. Cuando va a transmitir
datos, aunque puede asignar un puerto determinado para enviarlos es mucho mas prudente dejar al
Winsock que utilice el que quiera. De esta forma se asegura que siempre emitirá a través de un
puerto libre. (Experiencia propia: Si asigna un puerto determinado para transmitir lo mas probable
que le va a pasar es que se le cuelgue el ordenador) Para asegurarse de que no ha asignado
ningún puerto, basta con poner el valor 0 en esta propiedad.

El valor devuelto por esta propiedad es un Long.

Sintaxis NombredelWinsock.LocalPort = Número

Quinta tarea: Establecer comunicación con el equipo remoto

Para esta tarea también debemos distinguir si vamos a recibir información o a enviarla y el protocolo
que estemos usando (TCP o UDP)

Comunicación por UDP

Vamos a comenzar a ver como nos podemos comunicar con el Winsock a través de UDP. El
protocolo UDP permite enviar y recibir información sin establecer previamente una comunicación .
Así de simple. Una vez establecidos las propiedades descritas mas atrás, tanto el equipo
transmisor como el receptor están ya preparados para trabajar. No hace falta ni poner a escuchar al
receptor ni ordenar al transmisor que contacte con el receptor, cosa que como veremos mas
adelante, es necesario cuando se trata de una comunicación mediante el protocolo TCP.

Esta sencillez del protocolo UDP hace que sea muy válido para una aplicación en la que no sea
imprescindible la seguridad de la comunicación. Un ejemplo de aplicación con transmisión con
protocolo UDP podría ser el comprobar que ordenadores de están encendidos en un determinado
momento, envío de mensajería interna a través de Red de Area Local, etc. Pero eso sí, UDP no
sirve para conectarse a través de Internet, ya que los servidores de Internet cortan el paso a los
paquetes UDP. Pero el hecho de que no sirvan para Internet no debe hacernos olvidar este
protocolo tan sencillo para comunicaciones a través de una RAL interna.

Por lo tanto, para paquetes UDP no hace falta hacer nada para establecer la comunicación con el
equipo remoto, ni para transmitir ni para recibir.

Comunicación por TCP

Aquí sí debemos establecer previamente la conexión. De hecho, se dice de TCP que es un protocolo
orientado a conexión. Veamos que hay que hacer para transmitir y recibir con TCP
Para el equipo cliente (Transmisor)

El equipo que desea enviar datos debe solicitar la conexión. Si existe un equipo destino con
dirección IP y el puerto adecuado, este equipo le contestará. (Vea mas adelante el método Accept)
También puede ocurrir que el equipo destino o no existe, o reciba la solicitud de conexión y no la
acepte. Veremos más adelante qué ocurre en el caso de que nadie atienda la solicitud.

La solicitud de conexión se realiza mediante el método Connect

Método Connect
Solicita una conexión con un equipo remoto.

Sintaxis NombredelcontrolWinsock.Connect hostRemoto, puertoRemoto

Donde hostRemoto es la dirección IP o DNS del equipo remoto, y puertoRemoto es el puerto por
donde esperamos nos esté escuchando ese equipo remoto.

Este método no devuelve ningún dato.

Comentarios
Debe invocar el método Connect cuando intente establecer una conexión TCP.

Para el equipo servidor (Receptor)

Para recibir, primero hace falta poner el Winsock a escuchar, y una vez que reciba una
comunicación de un equipo llamante aceptarla. Para poner a escuchar al Winsock basta con invocar
el método Listen.

Método Listen
Crea un socket y lo establece a modo de escucha. (Sólo para conexiones TCP).

Sintaxis NombredelWinsock.Listen

No lleva ningún argumento ni devuelve ningún valor. Simplemente pone a la escucha al Winsock.

Ya con el Winsock a la escucha, ya está dispuesto para recibir una comunicación. Y no le importará
de quien venga, basta con que lleve su dirección IP y el puerto en el escucha el Winsock.

Cuando el Winsock recibe un intento de conexión se produce el evento ConnectionRequest. Para


aceptarla hay que usar el método Accept, pero aquí es donde se empiezan a complicar (solo un
poquito) las cosas.
Un Winsock solamente puede recibir una comunicación. Por lo tanto, solamente podrá atender a un
corresponsal. Esto no es lo que se busca en la mayor parte de los casos, sino que lo que se
pretende es estar a la escucha, y atender a todas las llamadas que entren, pudiendo atender a dos o
más comunicaciones simultáneamente.

Para lograr esto lo que hacemos es tener un Winsock permanentemente a la escucha para recibir
los sucesivos intentos de conexión de los corresponsales, y una vez que se recibe uno, se crea una
instancia del winsock, y es, con esta instancia, con la que le invocamos el método Accept para
aceptarla. De esta forma tendremos tantas instancias (copias) del winsock como comunicaciones
activas, más el winsock original que es el que se queda a la escucha de nuevos intentos de
conexión. Ni que decir tiene que, una vez terminada la conexión, debe cerrarse la instancia
correspondiente a esa conexión.

La instancia debe crearse en el procedimiento ConnectionRequest del winsock original. La forma de


crear esta instancia es mediante el procedimiento Load. Para ello, el winsock original debe tener la
propiedad Index para que de esta forma sea una matriz de controles, aunque originalmente solo
exista un elemento de esa matriz, con Index = 0. Las instancias van a tener un nombre (Propiedad
Name) igual a la del original, y un índice (Propiedad Index) que tendremos que ponerle en el
momento de crear ese nuevo winsock. Esto implica que deberemos llevar una lista con los índices
de las instancias creadas para no repetir ninguno. No sirve aumentar una unidad el número del
índice, ya que no podemos dejar que el número del índice crezca hasta el infinito.

Evento ConnectionRequest
Se produce en el equipo local cuando el equipo remoto solicita una conexión.

Sólo para aplicaciones de servidor TCP. El evento se activa cuando llega una solicitud de conexión.
A partir de la activación de este evento, las propiedades RemoteHostIP y RemotePort almacenan la
información acerca del cliente.

Este evento pasa como parámetro un número Long con el identificador de la solicitud de conexión.
Este identificador (IdSolicitud) lo genera el servidor (el equipo que recibe) y lo necesitaremos para
aceptar la conexión mediante el método Accept.

NombredelcontrolWinsock_ConnectionRequest (IdSolicitud As Long)

Metodo Accept

Este método se utiliza para aceptar una conexión entrante cuando se está tratando un evento
ConnectionRequest.. Sólo se usa con el protocolo TCP.

Sintaxis NombredelWinsock.Accept IdSolicitud


Donde IdSolicitud es el número identificador de la solicitud de conexión que pasa el evento
ConnectionRequest como parámetro.

El método Accept debe hacerse sobre una nueva instancia del control Winsock. No es estrictamente
necesario cuando se está utilizando una conexión en la que sabemos con certeza que no vamos a
recibir más de una llamada. En el caso de que se produzca un nuevo intento de conexión mientras
atiende a una conexión aceptada, además de no poder atenderlo, la experiencia nos dice que se
producen problemas, que terminan generalmente haciendo que el programa no responda e incluso
colgando el equipo, Recomiendo encarecidamente que la conexión se establezca con una nueva
instancia del winsock. Dicho en otras palabras, que el método Accept se ejecute sobre una nueva
instancia, aunque la información de Microsoft esté un poco indefinida en este aspecto.

Veamos como se crea una nueva instancia del control. Se usa el método Load. Para ello, en el
Winsock que colocamos en el proyecto le ponemos, en su propiedad Index el valor 0. Con esto le
estamos indicando que es una matriz de controles, pero solamente existe uno, cuyo índice es el 0.
Cuando utilizamos el método Load lo que hacemos es añadir un elemento más a esa matriz de
controles.
Si el control que hemos introducido en el formulario se llamaba Wsk, y le hemos puesto su propiedad
Index = 0, para añadir el segundo elemento de esa matriz, que tendrá la propiedad Index = 1,
ejecutaremos la siguiente línea de código:

Load Wsk (1)

Ahora ya tenemos una matriz con dos controles. (Indices 0 y 1) Dejaremos el winsock con índice 0
para seguir recibiendo peticiones de comunicación y ejecutaremos el método Accept sobre el
segundo winsock (el de Index = 1)

Wsk (1).Accept IdSolicitud


A partir de este momento, todo lo que tengamos que hacer para recoger la información recibida,
enviar respuestas al corresponsal, cerrar la comunicación lo haremos con la instancia creada para
esa conexión. No se nos puede olvidar cerrar el winsock una vez terminada la conexión y
descargarlo a continuación. Para descargarlo utilizamos la instrucción Unload

Unload Wsk(1)

El winsock original lo seguiremos dedicando a recibir nuevas solicitudes de conexión, que a su vez
crearán nuevas instancias del winsock.

En principio no hay problema para que cada nueva instancia lleve un Index incrementado en 1
respecto a la conexión anterior. Basta con declarar una variable tipo Long para introducir ese índice,
y previsiblemente nunca llegaremos a superar los límites del Long. Ahora bien, es mucho mas
elegante reutilizar los números de las instancias que se van cerrando. Para esto es necesario
utilizar una variable o una matriz, donde llevemos la cuenta de las instancias todavía abiertas del
winsock original.
Cada una de las instrucciones anteriores se deberán hacer en los eventos apropiados del winsock.
Así, el crear un nuevo winsock lo haremos en el evento ConnectionRequest, y el descargarlo lo
haremos en el evento Close.
Ya tenemos la conexión establecida. Veamos ahora otras propiedades y métodos que nos permitirán
conocer la identidad del corresponsal y lo que hay que hacer para enviar y recibir información.

Una vez establecida la conexión, mediante el método Connect por parte del cliente, y el método
Accept por parte del servidor, ya podemos conocer la identidad del corresponsal mediante la
propiedad RemoteHostIP

Evento Connect
Este evento ocurre en el Winsock que ha solicitado la conexión, cuando ésta se ha completado.
Ocurre por lo tanto cuando el winsock remoto invoca el método Accept. Puede usar este evento
parta conformar que se ha realizado la conexión.

Propiedad RemoteHostIP
Devuelve una cadena de caracteres con la dirección IP del equipo remoto.

En las aplicaciones de cliente, después de establecer la conexión con el método Connect, esta
propiedad contiene la cadena IP del equipo remoto.

En las aplicaciones de servidor, después de la llegada de una solicitud de llamada (evento


ConnectionRequest), esta propiedad contiene la cadena IP del equipo remoto que inició la conexión.

Cuando utiliza el protocolo UDP, después de producirse el evento DataArrival, esta propiedad
contiene la dirección IP del equipo que ha enviado los datos UDP.

Propiedad State
Permite conocer el estado del winsock y de la conexión que está realizando. Es sólo de lectura y no
está disponible en tiempo de diseño. Devuelve un integer

Siantaxis Variabletipointeger = NombredelWinsock.State

Nos puede devolver uno de los siguientes valores que corresponden a las siguientes constantes

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
Propiedad SocketHandle
Esta propiedad se usa para utilizarla con las Apis de Windows. Devuelve el manipulador del
Winsock. Es de sólo lectura y no está disponible en tiempo de diseño.

Sintaxis VariableTipoLong = NombredelWinsock(I) .SocketHandle

Donde I es el índice del Winsock. Como se decía más atrás, esta propiedad solamente se emplea
usando APIS

Propiedades, Métodos y Eventos del control Winsock usados en la comunicación

Hemos visto varias propiedades, métodos y eventos del control Winsock. Hasta ahora hemos visto:

Propiedades: LocalIP, LocalHostName, Protocol, RemoteHost, RemotePort, LocalPort, State


Métodos: Connect, Listen y Accept.
Eventos ConnectionRequest, Connect

Mediante estas propiedades y métodos establecemos la conexión. Nos falta ahora por ver aquellos
métodos usados durante la transmisión o recepción de datos.

Método SendData
Envía datos a un equipo remoto. Se emplea tanto en UDP como en TCP. No devuelve ningún valor.

Sintaxis NombredelWinsock(I).SendData datos

Donde NombredelWinsock es el nombre del winsock que debe enviar los datos, I es el índice de
ese control (en el caso de que el winsock sea una instancia de un winsock original, como se explicó
más atrás) y Datos son los datos a enviar, por ejemplo el nombre de una variable que los contiene o
la propiedad text de un textbox donde se han escrito los datos a enviar.

Si los datos a enviar son binarios, deberán enviarse como una matriz de bytes.
Cuando pasa una cadena UNICODE, se convierte a cadena ANSI antes de enviarla a la red.

Método GetData
Recupera los datos existentes en el búffer de recepción del winsock, lo almacena en una variable y
borra el contenido del búffer.
Sintaxis NombredelWinsock(I).GetData datos, [tipo,] [longMáx]

Donde datos es el nombre de la variable donde se almacenarán los datos recogidos


tipo (Opcional) es el tipo de datos a recuperar (Vea tabla)
longMáx (Opcional) Tamaño en bytes a recuperar. Si se omite este
parámetro, se
recuperan todos los datos existentes en el búffer de recepción. Si se
especifica un número inferior a los bytes existentes en el búffer, el
resto de los datos se perderán.

Los tipos de datos que se pueden usar en el parámetro tipo son:

Byte VbByte Entero vbInteger Long vbLong


Single vbSingle Simple vbDouble Double vbDouble
Moneda vbCurrency Fecha vbDate Booleano vbBoolean
Cadena vbString Matriz de bytes vbArray + vbByte

El método GetData se suele usar con el evento DataArrival, que incluye el argumento bytesTotales.
Si especifica una longMáx menor que el argumento bytesTotales, obtendrá el mensaje de
advertencia 10040, que indica que se perderán los bytes restantes.

Evento DataArrival
Se produce cuando llegan nuevos datos. Pasa como parámetro un Long con el número de bytes
recibidos. (NombredelWinsock _DataArrival (bytesTotales As Long)

Este evento no se producirá si no recupera todos los datos con una llamada GetData. Sólo se activa
cuando hay datos nuevos. Utilice la propiedad BytesReceived para comprobar la cantidad de datos
disponibles en cualquier momento.

Propiedad BytesReceived
Devuelve un Long la cantidad de datos recibidos (que están actualmente en el búffer de recepción).
Lógicamente es sólo de lectura y no está disponible en tiempo de diseño.

Sintaxis NombredeWinsock.BytesReceived

Método PeekData
Este método es similar a GetData, pero no elimina los datos extraídos del búffer de recepción. Exixte
otra diferencia, PeekData solamente funciona en las conexiones TCP.
La sintaxis es similar a la de GetData.

Sintaxis NombredelWinsock.PeekData datos, [tipo,] [longMáx]

Los parámetros de este método son los mismos que para GetData.
Evento SendProgress
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 búffer de
transmisión (bytesRest)

(NombredelWinsock_SendProgress (bytesEnv As Long, bytesRest As Long)

Evento SendComplete
Se produce cuando termina una operación de envío. No pasa argumentos.

NombredelWinsock_SendComplete()

Evento 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. (Los parámetros de fichero de ayuda y
contexto de ayuda, personalmente no los he visto en ninguno de los ejemplos preparados.

NombredelWinsock_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.

Evento Close
Se produce cuando el equipo remoto cierra la conexión. Las aplicaciones deben usar el método
Close para cerrar correctamente una conexión TCP.
El Método Bind
El método Bind sirve para reservar un puerto local cuando estamos trabajando en una comunicación
UDP. Esto puede ser muy útil para evitar que haya otra aplicación escuchando en ese mismo puerto.
Hay que darse cuenta que en UDP puede haber muchas aplicaciones escuchando el mismo puerto
ya que al no establecerse una comunicación, la información que llega pueden tomarla mas de una
aplicación. (Es idéntico al caso en el que una persona hable y muchas escuchan) Si reserva un
determinado puerto a un Winsock, a ese puerto no se le puede conectar otro Winsock a escuchar a
partir de ese momento. Hay que invocar el método Bind antes de invocar el método Listen.

También puede usar el método Bind en una comunicación TCP. Se emplea cuando hay más de un
adaptador de red en el equipo (Un equipo con dos placas de red, y cada una de ellas con un número
IP). Si en ese equipo hay un Winsock, ¿Qué número IP tiene?. Podría tomar uno de los dos
indistintamente. Mediante Bind podemos asignar uno de esos números IP a un Winsock.

Método Bind
Especifica el puerto local y la dirección IP local a usar en las conexiones TCP.

Sintaxis NombreDelWinsock.Bind puertoLocal, IPLocal

Donde:
PuertoLocal: Puerto utilizado para realizar una conexión.
IPLOcal: Dirección IP local sobre la que se va a establecer la conexión.

Nota adicional los puertos de comunicación en redes:

Los 1024 primeros puertos están reservados para distintos servicios de comunicación dentro de la
máquina. No los use para sus aplicaciones. Los servicios más conocidos utilizan los siguientes
puertos:

1 - tcpmux 5 - rje 7 - echo 9 - discard 11 - systat 13 - daytime


15 - netstat 17 - qotd 18 - send/rwp 19 - chargen 20 - FTP (data) 21 - FTP (control)
22 - ssh, pcAnywhere 23 - Telnet 25 - SMTP 27 - ETRN 29 - msg-icp
31 - msg-auth 33 - dsp 37 - time 38 - RAP 39 - rlp
42 - nameserv/WINS 43 - whois, nickname 49 - TACACS/Login Host Protocol
50 - RMCP 53 - DNS 57 - MTP 59 - NFILE 63 - whois++ 66 - sql*net
67 - bootps 68 - bootpd/dhcp 69 - Trivial File Transfer Protocol (tftp)
70 - Gopher 79 - finger 80 - www-http 88 - Kerberos, WWW 95 supdup
96 – DIXIE 98 - linuxconf 101 - HOSTNAME 102 - ISO, X.400, ITOT
105 - cso 106 – poppassd 109 - POP2 110 - POP3
111 - Sun RPC Portmapper 113 - identd/auth 115 - sftp 117 - uucp
119 - NNTP 120 - CFDP 123 – NTP 124 - SecureID 129 - PWDGEN
133 - statsrv 135 loc-srv/epmap 137 - netbios-ns 138 - netbios-dgm (UDP)
139 - NetBIOS 143 – IMAP 144 NewS 152 BFTP 153 - SGMP 161 - SNMP
175 – vmnet 177 - XDMCP 178 -NextStep Window Server 179 - BGP 180 - SLmail admin
199 - smux 210 - Z39.50 218 – MPP 220 - IMAP3 259 - ESRO 264 -FW1_topo
311 Apple WebAdmin 350 - MATIP type A 351 - MATIP type B
363 - RSVP tunnel 366 - ODMR (On-Demand Mail Relay)
387 - AURP (AppleTalk Update-Based Routing Protocol) 389 - LDAP 407 - Timbuktu
434 - Mobile IP 443 – ssl 444 - snpp, Simple Network Paging Protocol 445 - SMB
458 - QuickTime TV/Conferencing 468 - Photuris 500 - ISAKMP, pluto
512 - biff, rexec 513 who, rlogin 514 - syslog, rsh 515 - lp, lpr, line
printer
517 - talk 520 - RIP (Routing Information Protocol) 521 – RIPng 522 - ULS
543 - KLogin, AppleShare over IP 545 – QuickTime 548 AFP
554 - Real Time Streaming Protocol 555 - phAse Zero 563 NNTP over
SSL
575 - VEMMI 581 Bundle Discovery Protocol 593 - MS-RPC 608 - SIFT/UFT
626 Apple ASIA 631 - IPP (Internet Printing Protocol) 635 - mountd
(Linux)
636 – sldap 642 - EMSD 648 - RRP (NSI Registry Registrar Protocol)
660 - Apple MacOS Server Admin 666 - Doom 674 - ACAP
687 - AppleShare IP Registry 705 - AgentX for SNMP 901 - ISS Real Secure Sensor Port
993 - s-imap 995 - s-pop 1080 - SOCKS 1085 - WebObjects 1243 - SubSeven
1338 - Millennium Worm 1352 - Lotus Notes 1381 - Apple Network License
Manager
1417 - Timbuktu 1418 - Timbuktu 1419 - Timbuktu 1433 - Microsoft SQL
Server
1434 - Microsoft SQL Monitor 1503 - T.120 1521 - Oracle SQL 1525 - prospero
1526 - prospero 1527 - tlisrv 1645 - RADIUS Authentication
1646 - RADIUS Accounting 1680 - Carbon Copy 1701 - L2TP/LSF
1717 - Convoy 1720 - H.323/Q.931 1723 - PPTP control port
1755 - Windows Media .asf 1758 - TFTP multicast 1812 - RADIUS server
1813 - RADIUS accounting 1818 - ETFTP 1973 - DLSw DCAP/DRAP
1985 - HSRP 1999 - Cisco AUTH 2001 - glimpse 2049 - NFS
2064 - distributed.net 2065 - DLSw 2066 – DLSw 2106 - MZAP 2140 – DeepThroat
2301 Compaq Insight Management Web Agents 2336 - Apple UG Control
2427 - MGCP gateway 2504 – WLBS 2535 - MADCAP 2543 - sip
2727 - MGCP call agent 2592 netrek 2628 - DICT
2998 - ISS Real Secure Console Service Port 3000 - Firstclass 3031 - Apple AgentVU
3128 squid 3130 - ICP 3150 - DeepThroat 3283 - Apple NetAssitant
3288 COPS 3305 – ODETTE 3306 - mySQL 3389 - NT Terminal Server
4321 rwhois 4333 - mSQL 4827 - HTCP 5004 - RTP 5005 – RTP
5010 - Yahoo! Messenger 5060 - SIP 5190 – AIM 5500 - securid 5501 - securidprop
5423 - Apple VirtualUser 5631 - PCAnywhere data 5632 - PCAnywhere
5800 – VNC
5801 – VNC 5900 - VNC 5901 - VNC 6000 - X Windows 6667 – IRC
6670 - VocalTec Internet Phone, DeepThroat 6699 – napster 6776 - Sub7 6970 - RTP
7007 - MSBD, Windows Media encoder 7070 RealServer/QuickTime
7648 - CU-SeeMe 7649 - CU-SeeMe 8010 - WinGate 2.1 8080 - HTTP 8181 –
HTTP
8383 - IMail WWW 13223 - PowWow 13224 – PowWow 14237 – Palm
14238 - Palm 18888 - LiquidAudio 23213 – PowWow 23214 - PowWow 23456 –
EvilFTP
26000 – Quake 27001 - QuakeWorld 27015 - Half-Life 27960 - QuakeIII
30029 - AOL Admin 31337 - Back Orifice 40193 – Novell
45000 - Cisco NetRanger postofficed Multicast hidden ICMP Type hidden
32773 - rpc.ttdbserverd 32776 - rpc.spray 32777 - rpc.walld 32779 - rpc.cmsd
38036 - timestep

(Si quiere una información mayor acerca del número de los puertos, busque en su ordenador un
fichero llamado Services. Ese fichero es el que tiene los números de los puertos correspondientes a
cada servicio instalado en su ordenador.

Ejemplo 1:
Cliente - servidor TCP:
Cliente - tcp:

Codigo:

Option Explicit

Private Sub enviar_Click()


Dim mensaje As String
mensaje = Text1.Text
Winsockcliente.SendData mensaje
End Sub

Private Sub conectar_Click()


Winsockcliente.Connect
End Sub

Private Sub cerrar_sock_Click()


Winsockcliente.Close
End Sub

Private Sub Form_Load()


'Propiedades por defecto del Host remoto
Winsockcliente.RemoteHost = "127.0.0.1"
Winsockcliente.RemotePort = 1001
Winsockcliente.Protocol = sckTCPProtocol
End Sub

Private Sub Winsockcliente_DataArrival(ByVal bytesTotal As Long)


Dim mensaje As String
Winsockcliente.GetData mensaje 'lee socket
Text2.Text = mensaje
End Sub

Servidor - tcp:

Codigo:

Option Explicit
Private Sub enviar_Click()
Dim mensaje As String
mensaje = Text1.Text
winsockserver.SendData mensaje
End Sub

Private Sub escuchar_Click()


winsockserver.Listen
End Sub
Private Sub Form_Load()
'Propiedades de la máquina local
winsockserver.Protocol = sckTCPProtocol
winsockserver.LocalPort = 1001
End Sub

Private Sub winsockserver_ConnectionRequest(ByVal requestID As Long)


If winsockserver.State <> 0 Then '0 socket cerrado
winsockserver.Close
End If
winsockserver.Accept requestID
End Sub

Private Sub winsockserver_DataArrival(ByVal bytesTotal As Long)


Dim mensaje As String
winsockserver.GetData mensaje
Text2.Text = mensaje
End Sub

Ejemplo 2:

Cliente serividor UDP:

Cliente:

Codigo:

Option Explicit

Private Sub Form_Load()


Winsockclient.RemoteHost = "127.0.0.1"
Winsockclient.Protocol = sckUDPProtocol
Winsockclient.RemotePort = 2001
Winsockclient.Bind 2000
End Sub

Private Sub Text1_Change()


Dim cadena1 As String
cadena1 = Text1.Text
Winsockclient.SendData cadena1
End Sub

Private Sub Winsockclient_DataArrival(ByVal bytesTotal As Long)


Dim mensaje As String
Winsockclient.GetData mensaje
Text2.Text = mensaje
End Sub

Servidor:

Codigo:

Option Explicit

Private Sub Form_Load()


Winsockserver.RemoteHost = "127.0.0.1"
Winsockserver.Protocol = sckUDPProtocol
Winsockserver.RemotePort = 2000
Winsockserver.Bind 2001
End Sub
Private Sub Text1_Change()
Dim cadena As String
cadena = Text1.Text
Winsockserver.SendData cadena
End Sub

Private Sub Winsockserver_DataArrival(ByVal bytesTotal As Long)


Dim mensaje As String
Winsockserver.GetData mensaje
Text2.Text = mensaje
End Sub

También podría gustarte