Académique Documents
Professionnel Documents
Culture Documents
COMUNICACIN TCP/IP
MEMORIA
DESCRIPTIVA
2
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
NDICE
Objetivos del proyecto ___________________________________________ 4
Configuracin de la conexin______________________________________ 5
Fundamentos arquitectura TCP/IP___________________________________ 8
Introduccin 11
El Protocolo Internet (Internet Protocol - IP) 12
Direccionamiento IP 13
Direcciones de red y de difusin 14
Resumen de las reglas especiales de direccionamiento 15
Protocolos de Ruteo (nivel IP) 15
Protocolo de Informacin de Ruteo (RIP) 16
Protocolo SPF abierto (OSPF) 17
Protocolos de resolucin de direcciones 18
Protocolo de Asociacin de Direcciones por Rplica (RARP) 18
Mensajes de error y control en IP (ICMP) 19
Protocolo de datagrama de usuario (UDP) 20
Protocolo de control de transmisin (TCP) 22
Puertos, conexiones y puntos extremos 24
La interface socket_______________________________________________ 31
Introduccin Sockets 32
Identificacin de un socket 32
Tipos de sockets 34
Modelo de comunicacin cliente servidor 35
Proceso de conexin cliente servidor 36
Modelo de programacin 38
Byte order 39
Programacin de sockets en Windows 40
Programacin de sockets en Windows usando C++ y MFC 41
Fundamentos sobre el control MSWinsockControl______________________ 43
Diagramas de flujo_______________________________________________ 61
Introduccin 62
Aplicacin scada 63
Aplicacin cliente lectura 64
Aplicacin cliente escritura 65
Aplicacin servidor 66
Conclusiones_____________________________________________________ 68
Referencias_____________________________________________________ 71
3
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
OBJETIVOS
DEL PROYECTO
4
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
5
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CONFIGURACIN
DE LA CONEXIN
6
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
1. Intranet Local
Una Intranet es una red de ordenadores privados que utiliza tecnologa Internet para
compartir de forma segura cualquier informacin o programa del sistema operativo para
evitar que cualquier usuario de Internet pueda ingresar . En la arquitectura de las
Intranets se dividen el cliente y el servidor. El software cliente puede ser cualquier
computadora local (servidor web o PC), mientras que el software servidor se ejecuta en
una Intranet anfitriona. No es necesario que estos dos softwares, el cliente y el servidor,
sean ejecutados en el mismo sistema operativo. Podra proporcionar una comunicacin
privada y exitosa en una organizacin.
1
Figura 1.1 www.connectingworks.com/software/intranets.php
7
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
8
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
2
Figura 1.1 www.kan-ed.org/network-intro
9
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ARQUITECTURA
TCP/IP
10
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Introduccin
La arquitectura TCP/IP esta hoy en da ampliamente difundida, a pesar de ser una
arquitectura de facto, en lugar de ser uno de los estndares definidos por la ISO, IICC,
etc...
Esta arquitectura se empez a desarrollar como base de la ARPANET (red de
comunicaciones militar del gobierno de los EE.UU), y con la expansin de la
INTERNET se ha convertido en una de las arquitecturas de redes ms difundida.
Antes de continuar, pasemos a ver la relacin de esta arquitectura con respecto al modelo
de referencia OSI (Open Systems Interconnection) de la ISO.
As como el modelo de referencia OSI posee siete niveles (o capas), la arquitectura
TCP/IP viene definida por 4 niveles : el nivel de subred [enlace y fsico], el nivel de
interred [Red, IP], el protocolo proveedor de servicio [Transporte, TCP o UDP] , y el
nivel de aplicacin.
11
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
NO ORIENTADO A CONEXIN
- Transmisin en unidades denominadas datagramas.
- Sin correccin de errores, ni control de congestin.
- No garantiza la entrega en secuencia.
12
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
La entrega del datagrama en IP no est garantizada porque sta se puede retrasar, enrutar
de manera incorrecta o mutilar al dividir y reensamblar los fragmentos del mensaje. Por
otra parte, el IP no contiene suma de verificacin para el contenido de datos del
datagrama, solamente para la informacin del encabezado.
En cuanto al ruteo (encaminamiento) este puede ser :
- Paso a paso a todos los nodos
- Mediante tablas de rutas estticas o dinmicas
Direccionamiento IP
El TCP/IP utiliza una direccin de 32 bits para identificar una mquina y la red a la cual est
conectada. Unicamente el NIC (Centro de Informacin de Red) asigna las direcciones IP (o
Internet), aunque si una red no est conectada a Internet, dicha red puede determinar su
propio sistema de numeracin.
Hay cuatro formatos para la direccin IP, cada uno de los cuales se utiliza dependiendo del
tamao de la red. Los cuatro formatos, Clase A hasta Clase D (aunque ltimamente se ha
aadido la Clase E para un futuro) aparecen en la figura :
CLASE A
CLASE B
CLASE C
CLASE D
Conceptualmente, cada direccin est compuesta por un par (RED (netid), y Dir. Local
(hostid)) en donde se identifica la red y el host dentro de la red.
La clase se identifica mediante las primeras secuencias de bits, a partir de los 3 primeros bits
(de orden ms alto).
13
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Las direcciones de Clase A corresponden a redes grandes con muchas mquinas. Las
direcciones en decimal son 0.1.0.0 hasta la 126.0.0.0 (lo que permite hasta 1.6 millones de
hosts).
Las direcciones de Clase B sirven para redes de tamao intermedio, y el rango de direcciones
vara desde el 128.0.0.0 hasta el 191.255.0.0. Esto permite tener 16320 redes con 65024 host
en cada una.
Las direcciones de Clase C tienen slo 8 bits para la direccin local o de anfitrin (host) y 21
bits para red. Las direcciones de esta clase estn comprendidas entre 192.0.1.0 y
223.255.255.0, lo que permite cerca de 2 millones de redes con 254 hosts cada una.
Por ltimo, las direcciones de Clase D se usan con fines de multidifusin, cuando se quiere
una difusin general a ms de un dispositivo. El rango es desde 224.0.0.0 hasta
239.255.235.255.
Cabe decir que, las direcciones de clase E (aunque su utilizacin ser futura) comprenden el
rango desde 240.0.0.0 hasta el 247.255.255.255.
Por tanto, las direcciones IP son cuatro conjuntos de 8 bits, con un total de 32 bits. Por
comodidad estos bits se representan como si estuviesen separados por un punto, por lo que el
formato de direccin IP puede ser red.local.local.local para Clase A hasta red.red.red.local
para clase C.
A partir de una direccin IP, una red puede determinar si los datos se enviarn a travs de
una compuerta (GTW, ROUTER). Obviamente, si la direccin de la red es la misma que la
direccin actual (enrutamiento a un dispositivo de red local, llamado host directo), se evitar
la compuerta ; pero todas las dems direcciones de red se enrutarn a una compuerta para
que salgan de la red local. La compuerta que reciba los datos que se transmitirn a otra red,
tendr entonces que determinar el enrutamiento can base en la direccin IP de los datos y
una tabla interna que contiene la informacin de enrutamiento.
Otra de las ventajas que ofrece el direccionamiento IP es el uso de direcciones de difusin
(broadcast addresses), que hacen referencia a todos los host de la misma red. Segn el
estndar, cualquier direccin local (hostid) compuesta toda por 1s est reservada para
difusin (broadcast). Por ejemplo, una direccin que contenga 32 1s se considera un mensaje
difundido a todas las redes y a todos los dispositivos. Es posible difundir en todas las
mquinas de una red alterando a 1s toda la direccin local o de anfitrin (hostid), de manera
que la direccin 147.10.255.255 para una red de Clase B se recibira en todos los dispositivos
de dicha red ; pero los datos no saldran de dicha red.
En resumen:
Las direcciones IP se pueden utilizar para referirse a redes as como a anfitriones
individuales. Por regla, una direccin que tiene todos los bits del campo hostID a 0, se
reserva para referirse a la red en s misma.
Otra ventaja significativa del esquema de direccionamiento IP es que ste incluye una
direccin de difusin (BROADCAST) que se refiere a todos los anfitriones de la red. De
acuerdo con el estndar, cualquier campo hostID consistente solamente en 1s, esta
reservado para la difusin (BROADCAST). Esto permite que un sistema remoto enve
un slo paquete que ser publidifundido en la red especificada.
Como se menciona arriba, la utilizacin de todos los ceros para la red slo est permitida durante
el procedimiento de iniciacin de la maquina. Permite que una mquina se comunique
temporalmente. Una vez que la mquina "aprende" su red y dir. IP correctas, no debe utilizar la
red 0.
15
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
16
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
17
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
18
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
comunicar por medio del TCP/IP. El protocolo RARP utiliza el direccionamiento fsico
de red para obtener la direccin IP de la mquina. El mecanismo RARP proporciona la
direccin hardware fsica de la mquina de destino para identificar de manera nica el
procesador y transmite por difusin la solicitud RARP. Los servidores en la red reciben
el mensaje, buscan la transformacin en una tabla (de manera presumible en su
almacenamiento secundario) y responden al transmisor. Una vez que la mquina obtiene
su direccin IP, la guarda en memoria y no vuelve a utilizar RARP hasta que se inicia de
nuevo.
19
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
20
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Para comunicarse con un puerto externo, un transmisor necesita saber tanto la direccin
IP de la mquina de destino como el nmero de puerto de protocolo del destino dentro de
la mquina.
El UDP proporciona el mecanismo primario que utilizan los programas de aplicacin
para enviar datagramas a otros programas de aplicacin. El UDP proporciona puertos de
protocolo utilizados para distinguir entre muchos programas que se ejecutan en la misma
mquina. Esto es, adems de los datos, cada mensaje UDP contiene tanto en nmero de
puerto de destino como el nmero de puerto origen, haciendo posible que el software
UDP en el destino entregue el mensaje al receptor correcto y que ste enve una
respuesta.
El UDP utiliza el Protocolo Internet subyacente para transportar un mensaje de una
mquina a otra y proporciona la misma semntica de entrega de datagramas, sin
conexin y no confiable que el IP. No emplea acuses de recibo para asegurarse de que
llegan mensajes, no ordena los mensajes entrantes, ni proporciona retroalimentacin para
controlar la velocidad del flujo de informacin entre las mquinas. Por tanto, los
mensajes UDP se pueden perder, duplicar o llegar sin orden. Adems, los paquetes
pueden llegar ms rpido de lo que el receptor los puede procesar. En resumen:
El UDP proporciona un servicio de entrega sin conexin y no confiable,
utilizando el IP para transportar mensajes entre mquinas. Emplea el IP
para llevar mensajes, pero agrega la capacidad para distinguir entre varios
destinos dentro de la computadora anfitrin.
Formato de los mensajes UDP:
Cada mensaje UDP se conoce como datagrama de usuario. Conceptualmente, un
datagrama de usuario consiste en dos partes: un encabezado UDP y un rea de datos
UDP. El encabezado se divide en cuatro campos de 16 bits, que especifican el puerto
desde el que se envi el mensaje, el puerto para el que se destina el mensaje, la longitud
el mensaje y una suma de verificacin UDP.
Figura 2. Estructura
simplificada de UDP
21
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
22
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
En las secciones anteriores hemos visto el servicio de entrega de paquetes sin conexin y no
confiable, que forma la base para toda comunicacin en InterNet, as como el protocolo IP
que lo defina.
Ahora veremos el segundo servicio ms importante y mejor conocido a nivel de red, la
entrega de flujo confiable (Reliable Stream Transport), as como el Protocolo de Control de
Transmisin (TCP) que lo define.
En el nivel ms bajo, las redes de comunicacin proporcionan una entrega de paquetes no
confiable. Los paquetes se pueden perder o destruir debido a errores (falla el hardware,
sobrecarga de la red,...). Las redes que rutean dinmicamente los paquetes pueden
entregarlos en desorden, con retraso o duplicados. En el nivel ms alto, los programas de
aplicacin a menudo necesitan enviar grandes volmenes de datos de una computadora a
otra. Utilizar un sistema de entrega de conexin y no confiable para transferencias de
grandes volmenes de informacin resulta ser la peor opcin. Debido a esto, el TCP se ha
vuelto un protocolo de propsito general para estos casos.
La interfaz entre los programas de aplicacin y la entrega confiable (es, decir, las
caractersticas del TCP) se caracterizan por cinco funciones :
Servicio Orientado a Conexin : El servicio de entrega de flujo en la mquina
destino pasa al receptor exactamente la misma secuencia de bytes que le pasa el
transmisor en la mquina origen.
Conexin de Circuito Virtual : Durante la transferencia, el software de protocolo
en las dos mquinas contina comunicndose para verificar que los datos se reciban
correctamente. Si la comunicacin no se logra por cualquier motivo (v.q. falla el
hardware de red), ambas mquinas detectarn la falla y la reportarn a los programas
apropiados de aplicacin. Se utiliza el trmino circuito virtual para describir dichas
conexiones porque aunque los programas de aplicacin visualizan la conexin como
un circuito dedicado de hardware, la confiabilidad que se proporciona depende del
servicio de entrega de flujo.
Transferencia con Memoria Intermedia : Los programas de aplicacin envan un
flujo de datos a travs del circuito virtual pasando repetidamente bytes de datos al
software de protocolo. Cuando se transfieren datos, cada aplicacin utiliza piezas del
tamao que encuentre adecuado, que pueden ser tan pequeas como un byte. En el
extremo receptor, el software de protocolo entrega bytes del flujo de datos en el
mismo orden en que se enviaron, ponindolos a disposicin del programa de
aplicacin receptor tan pronto como se reciben y se verifican. El software de
protocolo puede dividir el flujo en paquetes, independientemente de las piezas que
transfiera el programa de aplicacin. Para hacer eficiente la transferencia y
minimizar el trfico de red, las implantaciones por lo general recolectan datos
suficientes de un flujo para llenar un datagrama razonablemente largo antes de
enviarlo. Por lo tanto, inclusive si el programa de aplicacin genera el flujo un byte a
la vez, la transferencia a travs de la red puede ser sumamente eficiente. De forma
similar, si el programa de aplicacin genera bloques de datos muy largos, el software
23
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
24
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
el envo de un nuevo paquete hasta que reciba un ACK del paquete anterior.
La solucin est en otra tcnica conocida como ventana deslizante, que es una forma ms
compleja de acuse de recibo positivo y retransmisin. Los protocolos de ventana deslizante
utilizan el ancho de banda de red de mejor forma al permitir que el transmisor enve varios
paquetes sin esperar el ACK (remitirse a captulos anteriores para una descripcin de ste
mtodo).
Puerto/protocolo Descripcin
25
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
37/tcp time
43/tcp nicname
37/tcp time
70/tcp Gopher
79/tcp Finger
26
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
111/tcp sunrpc
135/tcp epmap
162/tcp SNMP-trap
162/udp SNMP-trap
27
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
512/tcp exec
513/tcp login
520/udp RIP
1433/tcp Microsoft-SQL-Server
1434/tcp Microsoft-SQL-Monitor
1434/udp Microsoft-SQL-Monitor
1512/tcp WINS
28
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
3030/tcp NetPanzer
3030/upd NetPanzer
3128/tcp HTTP usado por web caches y por defecto en Squid cache
3128/tcp NDL-AAS
29
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
6112/udp Blizzard
6347/udp Gnutella
6348/udp Gnutella
6349/udp Gnutella
6350/udp Gnutella
6355/udp Gnutella
8080/tcp HTTP HTTP-ALT ver puerto 80. Tomcat lo usa como puerto por defecto.
8118/tcp privoxy
30
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
LA INTERFACE SOCKET
31
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Introduccin
Los sockets son interfaces lgicos de entrada/salida que permiten la comunicacin entre
procesos que pueden residir en mquinas distintas pero que estn conectadas mediante
una red. Es el mecanismo utilizado por las aplicaciones en red basadas en tecnologa
Internet, de ah su importancia dada la difusin de sta en la actualidad.
Las aplicaciones en red suelen responder a un modelo conocido como cliente-servidor.
En este modelo, el servidor es un proceso encargado de la gestin de un determinado
recurso de una mquina. El cliente, que, en general, se ejecuta en una mquina diferente,
interacciona con el recurso remoto estableciendo una comunicacin con el servidor,
siguiendo las reglas impuestas por el protocolo de nivel de aplicacin que corresponda.
Tras esta introduccin a las comunicaciones en redes tipo Internet, pasamos a describir
los interfaces de programacin que permiten el acceso a los sockets en distintos
lenguajes y sistemas operativos.
SOCKETS
Los sockets son interfaces lgicos que permiten la comunicacin bidireccional entre
procesos que se ejecutan en una misma mquina o en mquinas distintas conectadas en
red. Por ejemplo, los navegadores web se comunican con los servidores web mediante
sockets. Es frecuente encontrar en la bibliografa analogas entre sockets y telfonos o
buzones de correo. En cierto modo, estos ltimos permiten la comunicacin entre
personas de forma similar a como los sockets hacen posible la interaccin entre procesos.
La comunicacin mediante sockets es el mecanismo usado por la aplicaciones en red que
se basan en tecnologa Internet, es decir, en la familia de protocolos TCP/IP. De hecho,
un socket no es ms que la implementacin del acceso a los servicios del nivel de
transporte de la familia TCP/IP. En las aplicaciones en red es importante distinguir los
recursos locales de los recusos remotos. Siguiendo con el ejemplo anterior, el navegador
web prepara un socket local (es decir, en su mquina) para comunicarse con el socket
remoto dispuesto por el servidor web. Por extensin, suele hablarse tambin de proceso
local/remoto o incluso de mquina local/remota.
Identificacin de un socket
Desde el punto de vista de un proceso, un socket no es ms que un recurso muy parecido
a un fichero que se solicita localmente al sistema operativo y que, de alguna forma, abre
una puerta hacia el exterior. Es fundamental que este socket est identificado
convenientemente para que pueda ser referenciado desde el exterior. La forma de
identificar el socket est ntimamente relacionada con el mecanismo de direccionamiento
de la familia de protocolos subyacente, es decir, la familia TCP/IP (Internet), y se
describe a continuacin.
32
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
33
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Tipos de sockets
Como hemos visto, los sockets estn relacionados ntimamente con el protocolo de
transporte. En la familia TCP/IP tenemos dos posibles protocolos de transporte, TCP y
UDP, por lo que, en consecuencia, existen dos tipos de sockets2:
Sockets TCP, stream u orientados a la conexin.
La comunicacin entre sockets TCP es fiable (sin prdida de paquetes), ordenada
(TCP nos proporciona los paquetes en la secuencia correcta) y sin duplicacin de
paquetes. TCP, y consecuentemente, este tipo de sockets, es orientado a la conexin.
Esto quiere decir que los sockets de los extremos a comunicar deben establecer un
circuito virtual a travs del cual se producir el intercambio de informacin. El
establecimiento del circuito virtual se suele denominar conexin, y es el paso previo al
intercambio de datos. Una vez finalizado ste, se procede
1
Esta asignacin de puertos puede encontrarse en el documento RFC1700. Las RFCs (Request for
Comment) son
documentos oficiales del IETF (Internet Engineering Task Force), que recogen los estndares, borradores
de estndar y recomendaciones sobre todos los aspectos de Internet.
2
A veces es posible usar, adems de los tipos de sockets descritos, un tipo especial denominado "raw", a
travs del cual se tiene acceso directamente al protocolo IP, dejando vaco el nivel de transporte.
34
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
35
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
3
El socket que se ha creado en la mquina servidora para llevar a cabo la comunicacin con el cliente
tiene caractersticas similares al socket cliente, esto es, no est en estado de escucha, sino preparado para
enviar y recibir informacin.
4
Esto es, que tienen varios procesos ejecutndose concurrentemente en la mquina.
36
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
37
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Modelo de programacin
El proceso de conexin descrito en el apartado anterior, desde el punto de vista del
programador de procesos servidores o clientes, se corresponde con el diagrama mostrado
en la figura 3.
38
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Byte order
El flujo de datos entre sockets TCP est orientado al intercambio de bytes (char en
lenguaje C). Supongamos que queremos una secuencia de words (short en C) o double
words (long en C), compuestos por 2 y 4 bytes respectivamente. En qu orden debemos
enviar los bytes individuales que componen cada uno de estos datos? Sistemas basados
en microprocesadores distintos usan diferentes convenciones a la hora de almacenar
internamente estos tipos de datos, como es el caso de los Intel x86 (primero el byte
menos significativo, convencin little endian) y Motorola 680xx (primero el byte ms
significativo, convencin big endian).
Para solucionar el problema, se distinguen dos tipos de ordenamiento: el host order (el
39
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
orden con el que se almacena en el equipo, que ser little o big endian dependiendo del
sistema) y el network order (el orden establecido por convencin para las redes tipo
Internet, concretamente big endian), y se establecen las siguientes reglas:
todos los datos que se enven hacia la red deben convertirse al network order.
todos los datos que se reciban de la red deben convertirse al host order.
De esta forma, si el extremo A quiere transmitir un dato (de longitud mayor a un byte) al
extremo B, lo primero que hace es convertir el dato desde el host order de A al network
order. El dato, una vez recibido en B en network order, se transforma al host order de B.
De esta forma, independientemente de cules sean los host order de A y B, la
comunicacin se realiza correctamente. La clave est en que se ha definido un network
order universal, que siempre se respeta.
Insistimos en que el problema de orden de envo es relevante slo cuando la unidad de
informacin tiene una longitud superior a un byte.
Las funciones short htons(short) y long htonl(long) realizan la conversin de
host order a network order de un entero tipo short o long, respectivamente, mientras que
short ntohs(short) y long ntohl(long) realizan las conversiones opuestas, es decir, de
network order a host order. Estas funciones estn definidas en el fichero de cabecera
<netinet/in.h>.
40
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
El resto de funciones que manejan sockets (que devuelven int) indican una
situacin de error mediante la constante SOCKET_ERROR (en lugar de devolver
-1). Es el caso, por ejemplo, de send() y recv().
La funcin close() en winsock2 se denomina closesocket(), aunque manteniendo
la misma signatura.
En winsock2, la variable errno no es actualizada con el error producido. En su
lugar, hay que invocar a WSAGetLastError() para obtener el cdigo de error.
Antes de realizar cualquier llamada a winsock2 es necesario invocar la funcin
WSAStartup(), que se encarga de iniciar esta librera. Anlogamente, cuando ya
no sea necesario seguir usando winsock2, debe llamarse a WSACleanup().
Tpicamente, el cdigo necesario para llamar a WSAStartup() es de la forma:
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
if(WSAStartup(wVersionRequested, &wsaData) != 0) {
printf("Error: WSAStartup\n");
exit(1);
}
Mientras que para WSACleanup():
if(WSACleanup() == SOCKET_ERROR) {
printf("Error: WSACleanup\n");
exit(1);
}
Para ms informacin sobre la programacin de sockets en Windows, puede consultarse
la MSDN Library Visual Studio, en Platform SDK > Networking and Distributed
Services > Windows Sockets Version 2 API.
41
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
42
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
43
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
El MSWinsockControl incluido con Visual C++ es una herramienta muy poderosa para
la creacin de aplicaciones basadas en sockets.
Con MSWinsockControl se pueden implementar los diferentes protocolos utilizados en
Internet e inclusive protocolos propios.
Las aplicaciones que se han desarrollado pueden utilizar tantos sockets como sean
necesarios para realizar la tarea encomendada de la manera ms eficiente pero siempre
teniendo en cuenta que cada socket trabaja sobre un nico puerto.
El control WinSock permite conectarse a un equipo remoto e intercambiar datos con el
Protocolo de datagramas de usuario (UDP) o con el Protocolo de control de transmisin
(TCP). Ambos protocolos se pueden usar para crear aplicaciones cliente-servidor. Al
igual que el control Timer, el control WinSock no tiene una interfaz visible en tiempo de
ejecucin.
Aplicaciones posibles
- Crear una aplicacin cliente que recopile informacin del usuario antes de
enviarla a un servidor central.
- Crear una aplicacin servidora que funcione como un punto central de
recopilacin de datos procedentes de varios usuarios.
- Crear una aplicacin de "conversacin".
Seleccionar un protocolo
Cuando se utiliza el control WinSock, primero debe tener en cuenta es si se va a usar el
protocolo TCP o el protocolo UDP. La principal diferencia entre los dos radica en su
estado de conexin:
TCP es un protocolo basado en la conexin y es anlogo a un telfono: el usuario
debe establecer una conexin antes de continuar.
UDP es un protocolo sin conexin y la transaccin entre los dos equipos es como
44
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
pasar una nota: se enva un mensaje desde un equipo a otro, pero no existe una
conexin explcita entre ambos. Adems, el tamao mximo de los datos en
envos individuales est determinado por la red.
La naturaleza de la aplicacin que se est creando determinar generalmente qu
protocolo se debe seleccionar. He aqu varias cuestiones que pueden ayudar a
seleccionar el protocolo adecuado:
1- Necesita la aplicacin la confirmacin por parte del cliente o el servidor
cuando se enven o reciban datos? Si es as, el protocolo TCP requiere
una conexin explcita antes de enviar o recibir datos.
2- Ser muy grande el tamao de los datos (como en el caso de los archivos
de imgenes o sonidos)? Una vez establecida la conexin, el protocolo
TCP mantiene la conexin y asegura la integridad de los datos. No
obstante, esta conexin utiliza ms recursos del sistema, por lo que
resulta ms "cara".
3- Se envian los datos de forma intermitente o en una sesin? Por ejemplo,
si se est creando una aplicacin que avisa a equipos especficos cuando
se han completado ciertas tareas, el protocolo UDP puede ser el ms
apropiado. Este protocolo es tambin el ms adecuado para enviar
pequeas cantidades de datos.
Establecer el protocolo
Para establecer el protocolo que la aplicacin va a usar: en tiempo de diseo, en la
ventana Propiedades, Se entra en Protocolo y se selecciona sckTCPProtocol o
sckUDPProtocol. Tambin se puede establecer la propiedad Protocol en el cdigo, como
se muestra a continuacin:
Cdigo:
Winsock1.Protocol = sckTCPProtocol
45
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
En cambio, el protocolo UDP no requiere una conexin explcita. Para enviar datos entre
los dos controles, se deben completar tres pasos (en ambos lados de la conexin):
46
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Winsock (Control)
El control Winsock, invisible para el usuario, proporciona un acceso sencillo a los
servicios de red TCP y UDP. Pueden usarlo los programadores de Microsoft Access,
Visual Basic, Visual C++ o Visual FoxPro. Para escribir aplicaciones de servidor o de
cliente no necesita comprender los detalles de TCP ni llamar a las API de Winsock de
nivel inferior. Si establece las propiedades y llama a los mtodos del control, podr
conectar fcilmente con un equipo remoto e intercambiar datos en las dos direcciones.
47
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
equipo servidor slo necesita establecer RemoteHost a la direccin de Internet del equipo
cliente y la propiedad RemotePort al mismo puerto que la propiedad LocalPort del
equipo cliente, y llamar al mtodo SendData para comenzar a enviar mensajes. Despus,
el equipo cliente utiliza el mtodo GetData del evento DataArrival para recuperar los
mensajes enviados.
Propiedades Winsock(control)
BytesReceived (Propiedad)
Devuelve la cantidad de datos recibidos (que estn actualmente en el bfer de recepcin).
Utilice el mtodo GetData para recuperar los datos.
Es de slo lectura y no est disponible en tiempo de diseo.
- Sintaxis: objeto.BytesReceived
- Valor devuelto: Long
LocalHostName (Propiedad)
Devuelve el nombre de la mquina local. Es de slo lectura y no est disponible en
tiempo de diseo.
- Sintaxis: objeto.LocalHostName
- Valor devuelto:String
LocalIP (Propiedad)
Devuelve la direccin IP de la mquina local en el formato de cadena con puntos de
direccin IP (xxx.xxx.xxx.xxx). Es de slo lectura y no est disponible en tiempo de
diseo.
- Sintaxis: objeto.LocalIP
Tipo de datos: String
LocalPort (Propiedad)
Devuelve o establece el puerto local que desea usar. Es de lectura y escritura, y est
disponible en tiempo de diseo.
En el cliente, designa el puerto local desde el que desea enviar los datos.
Especifique el puerto 0 si la aplicacin no necesita un puerto especfico. En este
caso, el control seleccionar un puerto de forma aleatoria. Una vez establecida la
conexin, ste es el puerto local utilizado para la conexin TCP.
En el servidor, es el puerto local en el que se escuchar. Si especifica el puerto 0,
48
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Comentarios
Para establecer dinmicamente conexiones entre dos equipos, se suele usar el puerto
0. Por ejemplo, un cliente que desea que un servidor le "devuelva la llamada" puede
usar el puerto 0 para obtener un nuevo nmero de puerto (aleatorio), que pueda
proporcionar al equipo remoto para ese propsito.
RemoteHostIP (Propiedad)
Devuelve la direccin IP del equipo remoto.
En las aplicaciones de cliente, despus de establecer la conexin con el mtodo
Connect, esta propiedad contiene la cadena IP del equipo remoto.
En las aplicaciones de servidor, despus de la llegada de una solicitud de llamada
(evento ConnectionRequest), esta propiedad contiene la cadena IP del equipo
remoto que inici la conexin.
Cuando utiliza el protocolo UDP, despus de producirse el evento DataArrival, esta
propiedad contiene la direccin IP del equipo que enva los datos UDP.
- Sintaxis: objeto.RemoteHostIP
- Tipo de datos: String
49
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
SocketHandle (Propiedad)
Devuelve un valor que corresponde al controlador de socket que utiliza el control para
comunicarse con la capa Winsock. Es de slo lectura y no est disponible en tiempo de
diseo.
- Sintaxis: objeto.SocketHandle
- Tipo de datos: Long
Comentarios
Esta propiedad se dise para pasarla a las API de Winsock.
50
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Name (Propiedad)
Devuelve el nombre utilizado en el cdigo para identificar un formulario, un
control o un objeto de acceso a datos. Es de slo lectura en tiempo de ejecucin.
Devuelve o establece el nombre de un objeto fuente.
- Sintaxis: objeto.Name
objeto Una expresin de objeto que da como resultado un objeto de la lista Se aplica a.
propiedad Propiedad compatible con el objeto.
mtodo Mtodo compatible con el objeto.
Comentarios
Utilizar esta propiedad para especificar un objeto que desea usar en una tarea de
Automatizacin.
Para usar en una tarea de Automatizacin el objeto devuelto por la propiedad Object,
utilizar las propiedades y los mtodos de dicho objeto. Para obtener informacin acerca
de las propiedades y los mtodos compatibles con un objeto, ver la documentacin de la
aplicacin que cre el objeto.
Parent (Propiedad)
Devuelve el formulario, objeto o coleccin que contiene un control u otro objeto o
coleccin.
- Sintaxis: objeto.Parent
Comentarios
Utilizar la propiedad Parent para tener acceso a las propiedades, los mtodos o los
controles del primario de un objeto.
La propiedad Parent es til en una aplicacin en la que se pasan objetos como
argumentos. Por ejemplo, se podra pasar una variable de control a un procedimiento
general en un mdulo y usar la propiedad Parent para tener acceso a su formulario
primario.
51
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Devuelve o establece el equipo remoto al que un control enva datos, o aqul del que los
recibe. Puede indicar el nombre de host, como "FTP://ftp.microsoft.com" o como una
cadena de direccin IP en el formato con puntos, como "100.0.1.1".
- Sintaxis: objeto.RemoteHost = cadena
La sintaxis de la propiedad RemoteHost consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Una expresin de objeto que da como resultado un objeto de la lista Se aplica a.
cadena El nombre o la direccin del equipo remoto.
Comentarios
Cuando se especifica esta propiedad, la propiedad URL se actualiza para mostrar el
nuevo valor. Adems, si se actualiza la parte de host de la direccin URL, esta propiedad
tambin se modifica para reflejar el nuevo valor.
La propiedad RemoteHost tambin puede modificarse al invocar los mtodos OpenURL
o Execute. En tiempo de ejecucin, el cambio de este valor no tiene ningn efecto hasta
la conexin siguiente.
RemotePort (Propiedad, controles ActiveX)
Devuelve o establece el nmero del puerto remoto con el que conectar.
- Sintaxis: objeto.RemotePort = puerto
La sintaxis de la propiedad RemotePort consta de la siguientes partes:
Cdigo:
Parte Descripcin
objeto Control Winsock
puerto El puerto con el que conectar. El valor predeterminado de esta propiedad es 80.
52
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Devuelve o establece una expresin que almacena cualquier dato adicional necesario
para su programa.
- Sintaxis: objeto.Tag [= expresin]
La sintaxis de la propiedad Tag consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Casi cualquier objeto
expresin Cualquier texto
Winsock(Metodos)
Accept (Mtodo)
Slo para las aplicaciones de servidor TCP. Este mtodo se utiliza para aceptar una
conexin entrante cuando se est tratando un evento ConnectionRequest.
- Sintaxis: objeto.Accept IdSolicitud
- Tipo de datos: Long
- Valor devuelto: Ninguno
Comentarios
El mtodo Accept se utiliza en el evento ConnectionRequest. El evento
ConnectionRequest tiene un argumento, el parmetro RequestID, que debe pasarse al
mtodo Accept.
Debe usar el mtodo Accept en una nueva instancia del control (distinta de la que est en
estado de escucha.)
Bind (Mtodo)
Especifica el puerto local y la direccin IP local a usar en las conexiones TCP. Utilice
este mtodo si tiene mltiples adaptadores de protocolo.
- Sintaxis: objeto.Bind puertoLocal, IPLocal
La sintaxis del mtodo Bind consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Control Winsock
puertoLocal Puerto utilizado para realizar una conexin.
IPLocal Direccin local de Internet utilizada para realizar una conexin.
Comentarios
Debe llamar al mtodo Bind antes de llamar al mtodo Listen.
Cierra una conexin TCP o un socket en escucha para las aplicaciones de cliente y de
servidor.
- Sintaxis: objeto.Close
- Argumentos: Ninguno
- Valor devuelto: Ninguno
Valores
Los valores de tipo son:
Cdigo:
Descripcin Constante
Byte VbByte
Entero VbInteger
Largo VbLong
Simple VbSingle
Doble vbDouble
Moneda vbCurrency
Fecha vbDate
Booleano vbBoolean
SCODE vbError
Cadena vbString
Matriz de bytes vbArray + vbByte
Comentarios
54
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
El mtodo GetData se suele usar con el evento DataArrival, que incluye el argumento
bytesTotales. Si especifica una longMx menor que el argumento bytesTotales, obtendr
el mensaje de advertencia 10040, que indica que se perdern los bytes restantes.
Listen (Mtodo)
Crea un socket y lo establece a modo de escucha. Este mtodo slo funciona en las
conexiones TCP.
- Sintaxis: objeto.Listen
- Argumentos: Ninguno
- Valor devuelto: Ninguno
Comentarios
El evento ConnectionRequest se produce cuando hay una conexin entrante. Cuando se
est tratando un evento ConnectionRequest, la aplicacin debera usar el mtodo Accept
(en una nueva instancia del control) para aceptar la conexin.
PeekData (Mtodo)
Similar a GetData, excepto que PeekData no elimina los datos de la cola de entrada. Este
mtodo slo funciona en las conexiones TCP.
- Sintaxis: objeto.PeekData datos, [tipo,] [longMx]
La sintaxis del mtodo PeekData consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Control Winsock
datos Almacena los datos recuperados despus de que el mtodo acaba
satisfactoriamente. Si no hay suficientes datos disponibles para el tipo solicitado,
datos se establecer a Vaco.
tipo Opcional. Tipo de los datos a recuperar, como se describe en Valores. Valor
predeterminado: vbArray + vbByte.
longMx Opcional. Longitud que especifica el tamao deseado cuando se recibe una matriz
de bytes o una cadena. Si falta este argumento para las matrices de bytes o
cadenas, se recuperan todos los datos disponibles. Si se proporciona para otros
tipos de datos que no sean matrices de bytes o cadenas, se pasa por alto el
argumento.
Valores
Los valores de tipo son:
Cdigo:
55
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Tipo Constante
Byte VbByte
Entero VbInteger
Largo VbLong
Simple VbSingle
Doble VbDouble
Moneda vbCurrency
Fecha VbDate
Booleano VbBoolean
SCODE VbError
Cadena VbString
Matriz de bytes VbArray + vbByte
SendData (Mtodo)
Enva datos a un equipo remoto.
- Valor devuelto: Ninguno
- Sintaxis: objeto.SendData datos
La sintaxis del mtodo SendData consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Control Winsock
datos Datos que desea enviar. Para los datos binarios, debera usar matrices de datos.
Comentarios
Cuando pasa una cadena UNICODE, se convierte a cadena ANSI antes de enviarla a la
red.
Winsock(eventos)
Close (Evento)
Se produce cuando el equipo remoto cierra la conexin. Las aplicaciones deben usar el
mtodo Close para cerrar correctamente una conexin TCP.
- Sintaxis: objeto_Close( )
- Argumentos: Ninguno
56
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ConnectionRequest (Evento)
Se produce cuando el equipo remoto solicita una conexin.
Slo para aplicaciones de servidor TCP. El evento se activa cuando llega una
solicitud de conexin. Las propiedades RemoteHostIP y RemotePort almacenan
la informacin acerca del cliente despus de que se ha activado el evento.
- Sintaxis: objeto_ConnectionRequest (IdSolicitud As Long)
La sintaxis del evento ConnectionRequest consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Control Winsock
IdSolicitud Identificador de la solicitud de conexin entrante. Este argumento se debera
pasar al mtodo Accept de la segunda instancia del control.
Comentarios
El servidor puede decidir si acepta o no la conexin. Si no se acepta la conexin entrante,
el equipo (cliente) obtendr el evento Close. Utilice el mtodo Accept (en una nueva
instancia del control) para aceptar una conexin entrante.
DataArrival (Evento)
Se produce cuando llegan nuevos datos.
- Sintaxis: objeto_DataArrival (bytesTotales As Long)
La sintaxis del evento DataArrival consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Objeto Winsock
bytesTotales Long. Cantidad total de datos que se puede recuperar.
Comentarios
Este evento no se producir si no recupera todos los datos con una llamada GetData.
Slo se activa cuando hay datos nuevos. Utilice la propiedad BytesReceived para
comprobar la cantidad de datos disponibles en cualquier momento.
57
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Valores
Los valores de nmero son:
Cdigo:
Constante Valor Descripcin
sckOutOfMemory 7 Sin memoria
sckInvalidPropertyValue 380 El valor de la propiedad no es vlido.
sckGetNotSupported 394 No se puede leer la propiedad.
sckSetNotSupported 383 La propiedad es de slo lectura.
sckBadState 40006 Protocolo o estado de conexin incorrecto para la solicitud
o la transaccin requerida.
sckInvalidArg 40014 El argumento que se pas a una funcin no estaba en el
formato correcto o en el intervalo especificado.
sckSuccess 40017 Correcto.
sckUnsupported 40018 Tipo Variant no aceptado.
sckInvalidOp 40020 La operacin no es vlida en el estado actual.
sckOutOfRange 40021 El argumento est fuera del intervalo.
sckWrongProtocol 40026 Protocolo errneo para la solicitud o la transaccin
requerida.
sckOpCanceled 10004 Se cancel la operacin.
sckInvalidArgument 10014 La direccin solicitada es una direccin de multidifusin,
pero el indicador no est activado.
sckWouldBlock 10035 El socket es no bloqueante y la operacin especificada se
58
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
bloquear.
sckInProgress 10036 Se est efectuando una operacin de Winsock bloqueante.
sckAlreadyComplete 10037 Se complet la operacin. No se estn efectuando
operaciones bloqueantes.
sckNotSocket 10038 El descriptor no es un socket.
sckMsgTooBig 10040 El datagrama es demasiado grande para el bfer y se
truncar.
sckPortNotSupported 10043 El puerto especificado no es compatible.
sckAddressInUse 10048 Direccin en uso.
sckAddressNotAvailable 10049 La direccin no est disponible en la mquina 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 conexin antes de
establecer SO_KEEPALIVE.
sckConnectAborted 10053 La conexin se ha cancelado al sobrepasar el tiempo de
espera o por otro error.
sckConnectionReset 10054 La conexin se ha restablecido desde el lado remoto.
sckNoBufferSpace 10055 No hay espacio disponible en el bfer.
sckAlreadyConnected 10056 El socket ya est conectado.
SendComplete (Evento)
Se produce cuando termina una operacin de envo.
- Sintaxis: objeto_SendComplete
- Argumentos: Ninguno
SendProgress (Evento)
Se produce mientras se estn enviando datos.
- Sintaxis: objeto_SendProgress (bytesEnv As Long, bytesRest As Long)
La sintaxis del evento SendProgress consta de las siguientes partes:
Cdigo:
Parte Descripcin
objeto Expresin de objeto que da como resultado un objeto de la lista Se aplica a.
59
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
bytesEnv Nmero de bytes enviados desde la ltima vez que se activ el evento.
bytesRest Nmero de bytes que esperan en el bfer de envo a ser enviados.
60
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Diagramas de flujo
61
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Introduccin
A continuacin se muestran los diagramas de flujo de cada una de las aplicaciones donde
se puede observar el funcionamiento del programa.
Cada diagrama muestra el tratamiento de cada una de las excepciones que pueden ser
invocadas en el programa, existen excepciones tratadas internamente desde el cdigo y
otras que son producidas por acontecimientos externos como la pulsacin de un botn o
el cambio producido en una ventana de texto del programa.
El primer diagrama de cada aplicacin muestra el tratamiento a eventos producidos
desde el men de la aplicacin, mientras que, los siguientes diagramas muestran el
tratamiento realizado a todos los dems eventos.
62
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Aplicacin scada
63
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CLIENTE LECTURA ON
EVENTO
OnConnectWinsock1() OnDestroy()
OnInitDialog()
OnTimer(UINT nIDEvent)
OnConnectWinsock2() OnDataArrivalWinsock2(long bytesTotal)
OnDataArrivalWinsock1(long bytesTotal)
Remote? Si mensaje es
Flag PASS y Envo mensaje aceptado: Muestra consigna Inicia parmetros
Remote activados obtener al Flag Remote recibida del Cierra socket si se y variables del
Aviso por pantalla Servidor. SI NO activado, flag Servidor por destruye la
sistema
de introducir Flag Remote PASS pantalla. ventana y envia
contrasea activado desactivado y Flag obtener una peticin de
Anula Indica error en el desactivado borrado de la
reinicio socket 1
temporizador. sistema. conexin del
Flag Remote Flag obtener cliente
desactivado desactivado
64
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CLIENTE ESCRITURA ON
EVENTO
CLIENTE ESCRITURA ON
EVENTO
OnConnectWinsock1()
OnChangeConsigna() OnDestroy() OnInitDialog()
OnTimer(UINT nIDEvent)
65
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Aplicacin servidor
66
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
67
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Conclusiones
68
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Conclusiones
69
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Gran parte del xito de este proyecto radica en el estudio anterior sobre programacin en
c, aportado en asignaturas realizadas en el transcurso de la carrera y de la informacin
obtenida en la bibliografa documentada en el apartado referencias de este documento.
Tambin ha sido de gran utilidad la informacin obtenida va internet de los diferentes
aspectos de comunicacin entre sockets que han ayudado a corregir algunos errores
aparecidos en el transcurso de la elaboracin de este proyecto.
En el anexo aadimos el cdigo de todos los archivos que se incluyen en el proyecto de
Microsoft Visual C++.
70
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Referencias
71
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
72
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
MANUAL USUARIO
73
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
INDICE
Aplicacin servidor________________________71
Aplicacin cliente_________________________78
Instalacin________________________________________________ 79
Servidor 79
Cliente 80
Funcionamiento de la aplicacin______________________________ 81
Servidor 82
Cliente 82
74
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
75
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Aplicacin servidor
Para poder utilizar correctamente la aplicacin servidor se debern tener en cuenta los
siguientes factores:
Despus de realizar estas preguntas se puede observar que la configuracin del sistema
puede ser variable y que cada configuracin tendr sus diferentes pasos a seguir.
Algunas configuracines nos permitirn trabajar con un sistema ms estable, evitando
perdidas de conexin por parte del servidor e evitar errores con los datos del proceso.
La configuracin ms adecuada para el correcto funcionamiento del servidor ser la
siguiente:
Con esta configuracin la aplicacin podr funcionar perfectamente sin ningn tipo de
configuracin adicional, simplemente se deber tener en cuenta que los cortafuegos y
antivirus del sistema operativo instalado nos permitan el acceso a las aplicaciones.
Si no disponemos de tal configuracin tambin se puede ejecutar la aplicacin con
cualquier sistema operativo Windows conectado a una red local o a Internet. El gran
inconveniente de no disponer una direccin IP esttica es que con la IP dinmica la
3
Proxy hace referencia a un programa o dispositivo que realiza una accin en representacin de otro. Su finalidad ms
habitual es la de servidor proxy, que sirve para permitir el acceso a Internet a todos los equipos de una organizacin
cuando slo se puede disponer de un nico equipo conectado, esto es, una nica direccin IP.
76
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
La solucin planteada aqu es usar un servicio de nombrado dinmico, es decir que sea
capaz de trabajar con una IP dinmica. Para que esto funcione, necesitamos que nuestro
servidor informe al servicio de nombrado cada vez que nuestro ISP nos cambie la IP, de
este modo el servicio de nombres estar actualizado.
Hay varios proveedores de servicios de nombrado dinmico (estos son slo algunos de
ellos):
No-IP
ZoneEdit
DynDNS
77
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Ahora tendremos que darnos de alta en No-IP, y crear una cuenta gratuita, una vez
hecho esto, tendremos que dar de alta el (o los) nombre de dominio que queremos, en el
caso de No-IP nos dan a elegir entre subdominios. Una vez iniciada sesin en la cuenta
de No-IP, se introducen los valores de YOUR NO-IP, Hosts/Redirects, Add .
1) Abrimos una nueva ventana del explorador y escribimos 192.168.1.1 (por defecto).
2) Aparecer una ventana pidiendo usuario y contrasea. Por defecto es 1234 en ambas
casillas, si no pueden ingresar con estos datos, van a tener que conseguirlos ya que no
78
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
79
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Seleccionamos la opcin SUA Only y clickeamos en Edit Details de esa misma opcin.
80
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Ahora viene la parte ms sencilla. En la columna Start Port No. vamos a escribir el
nmero del puerto en donde se comenzar a abrir. En la columna End Port No.
escribiremos el nmero del puerto en donde se terminar de abrir. Por ejemplo, si quiero
abrir todos los puertos desde el 70 al 80, escribo 70 en Start Port No. y 80 en End Port
No.. Si quiero abrir un slo puerto, escribo el mismo nmero en ambas casillas.
En la columna IP Adress debemos escribir la direccin IP interna de nuestra PC, es
decir, la direccin IP de nuestra PC en la red (no es la IP pblica). Para descubrir la IP
actual de nuestro sistema seguir los pasos detallados en la configuracin anterior.
6) Para terminar realizamos un clic en el botn Save y listo, las conexiones que entren,
en este caso, por los puertos 4662 y 4672 se re direccionarn a nuestro sistema y
podremos recibir las notificaciones sin problemas.
81
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Aplicacin Cliente
La configuracin del sistema para el correcto funcionamiento de la aplicacin cliente es
cualquiera que posea una conexin a internet y un sistema operativo Windows. Tener en
cuenta tambin que las aplicaciones de antivirus y cortafuegos nos permitan el acceso al
exterior de la aplicacin.
82
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Instalacin
Servidor
Para instalar la aplicacin Servidor bastara con ejecutar la aplicacin
PFC-EGP-Servidor.exe
Cliente
Para la instalacin de la aplicacin cliente se realizarn los mismos pasos que en la
instalacin de la aplicacin servidor.
83
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Funcionamiento de la aplicacin
El software realizado (Cliente.exe, Servidor.Exe) se debe instalar en un ordenador PC
compatible con el sistema operativo Windows.
Dependiendo de cul sea la ubicacin se instalara una aplicacin o otra:
En el ordenador donde est conectado el proceso industrial instalaremos la aplicacin
Cliente (Scada), esta aplicacin se encargara de captar los datos del sensor y enviar la
consigna deseada.
En el ordenador donde reside el ordenador Servidor con conexin al exterior
instalaremos la aplicacin Servidor.exe, esta aplicacin se encargara de guardar los datos
del proceso y enviarlos debidamente a los destinatarios, tambin enviara la consigna
deseada al ordenador del proceso cuando tenga activada esta opcin.
En todos los dems ordenadores pertenecientes a la red LAN o WAN se podr instalar la
aplicacin cliente y trabajar como lectura o escritura, la diferencia entre estas dos
aplicaciones reside en el hecho de que lectura slo puede leer los datos del sensor
mientras que escritura puede leer y enviar la consigna deseada cuando el ordenador del
proceso tenga activada esta opcin.
La aplicacin escritura slo funcionar desde una nica ubicacin, aunque esta se puede
variar dependiendo de las necesidades de la planta, el motivo de esta configuracin es la
de evitar posibles datos errneos en la consigna del proceso.
A continuacin se mostraran todas la pantallas detalladas de los mens pertenecientes a
cada aplicacin.
84
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Servidor
Cliente
85
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Aplicacin Scada:
Cliente lectura:
86
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Cliente escritura:
87
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ANEXOS
88
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
MSWinsockControl.cpp
// NOTE: Do not modify the contents of this file. If this class is regenerated by
// Microsoft Visual C++, your modifications will be overwritten.
#include "stdafx.h"
#include "mswinsockcontrol.h"
/////////////////////////////////////////////////////////////////////////////
// CMSWinsockControl
IMPLEMENT_DYNCREATE(CMSWinsockControl, CWnd)
/////////////////////////////////////////////////////////////////////////////
// CMSWinsockControl properties
/////////////////////////////////////////////////////////////////////////////
// CMSWinsockControl operations
long CMSWinsockControl::GetProtocol()
{
long result;
InvokeHelper(0x3, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
return result;
}
CString CMSWinsockControl::GetRemoteHostIP()
{
CString result;
InvokeHelper(0x4, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
return result;
}
CString CMSWinsockControl::GetLocalHostName()
{
CString result;
InvokeHelper(0x5, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
return result;
}
CString CMSWinsockControl::GetLocalIP()
{
CString result;
InvokeHelper(0x6, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
return result;
}
long CMSWinsockControl::GetSocketHandle()
{
long result;
InvokeHelper(0x7, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
return result;
}
long CMSWinsockControl::GetRemotePort()
{
long result;
InvokeHelper(0x1, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
return result;
}
89
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
long CMSWinsockControl::GetLocalPort()
{
long result;
InvokeHelper(0x2, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
return result;
}
short CMSWinsockControl::GetState()
{
short result;
InvokeHelper(0x8, DISPATCH_PROPERTYGET, VT_I2, (void*)&result, NULL);
return result;
}
long CMSWinsockControl::GetBytesReceived()
{
long result;
InvokeHelper(0x9, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL);
return result;
}
void CMSWinsockControl::Listen()
{
InvokeHelper(0x41, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}
90
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
void CMSWinsockControl::Close()
{
InvokeHelper(0x46, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}
CString CMSWinsockControl::GetRemoteHost()
{
CString result;
InvokeHelper(0xa, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
return result;
}
91
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
MSWinsockControl.h
#if !defined(AFX_MSWINSOCKCONTROL_H__5F5F6292_64DE_48DD_A382_A558E468340A__INCLUDED_)
#define AFX_MSWINSOCKCONTROL_H__5F5F6292_64DE_48DD_A382_A558E468340A__INCLUDED_
// NOTE: Do not modify the contents of this file. If this class is regenerated by
// Microsoft Visual C++, your modifications will be overwritten.
/////////////////////////////////////////////////////////////////////////////
// CMSWinsockControl wrapper class
// Attributes
public:
// Operations
public:
long GetProtocol();
void SetProtocol(long nNewValue);
CString GetRemoteHostIP();
CString GetLocalHostName();
CString GetLocalIP();
long GetSocketHandle();
long GetRemotePort();
void SetRemotePort(long nNewValue);
long GetLocalPort();
void SetLocalPort(long nNewValue);
short GetState();
long GetBytesReceived();
void Connect(const VARIANT& RemoteHost, const VARIANT& RemotePort);
void Listen();
void Accept(long requestID);
void SendData(const VARIANT& data);
void GetData(VARIANT* data, const VARIANT& type, const VARIANT& maxLen);
void PeekData(VARIANT* data, const VARIANT& type, const VARIANT& maxLen);
void Close();
void Bind(const VARIANT& LocalPort, const VARIANT& LocalIP);
CString GetRemoteHost();
void SetRemoteHost(LPCTSTR lpszNewValue);
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
92
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
#endif //
!defined(AFX_MSWINSOCKCONTROL_H__5F5F6292_64DE_48DD_A382_A558E468340A__INCLUDED_)
93
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
server.rc
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by server.rc
//
#define IDOK2 2
#define IDOK3 3
#define IDOK4 4
#define IDOK5 5
#define IDOK6 6
#define IDOK7 7
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_SERVER_DIALOG 102
#define IDP_SOCKETS_INIT_FAILED 103
#define IDR_MAINFRAME 128
#define IDC_EDIT1 1001
#define IDC_EDIT2 1002
#define IDC_WINSOCK1 1003
#define IDC_EDIT3 1005
#define IDC_EDIT4 1006
#define IDC_ANIMATE1 1007
#define IDC_EDIT5 1007
#define IDC_WINSOCK2 1008
#define IDC_EDIT6 1009
#define IDC_EDIT7 1010
#define IDC_WINSOCK3 1011
#define IDC_WINSOCK4 1012
#define IDC_EDIT8 1013
#define IDC_EDIT9 1014
#define IDC_EDIT10 1015
#define IDC_BUTTON2 1016
#define IDC_EDIT11 1017
#define IDC_EDIT12 1018
#define IDC_EDIT16 1019
#define IDC_EDIT17 1020
#define IDC_EDIT18 1021
#define IDC_EDIT13 1022
#define IDC_EDIT14 1023
#define IDC_EDIT15 1024
#define IDC_EDIT19 1025
#define IDC_EDIT20 1026
#define IDC_EDIT21 1027
#define IDC_EDIT22 1028
#define IDC_EDIT23 1029
#define IDC_EDIT24 1030
#define IDC_BUTTON1 1031
#define IDC_WINSOCK5 1032
94
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Server.cpp
#include "stdafx.h"
#include "server.h"
#include "serverDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CServerApp
BEGIN_MESSAGE_MAP(CServerApp, CWinApp)
//{{AFX_MSG_MAP(CServerApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerApp construction
CServerApp::CServerApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CServerApp object
CServerApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CServerApp initialization
BOOL CServerApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CServerDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
95
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
96
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Server.h
#if !defined(AFX_SERVER_H__ABA7404C_5318_41FF_A149_C9085DF1C3AB__INCLUDED_)
#define AFX_SERVER_H__ABA7404C_5318_41FF_A149_C9085DF1C3AB__INCLUDED_
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
/////////////////////////////////////////////////////////////////////////////
// CServerApp:
// See server.cpp for the implementation of this class
//
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CServerApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
#endif // !defined(AFX_SERVER_H__ABA7404C_5318_41FF_A149_C9085DF1C3AB__INCLUDED_)
97
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ServerDlg.cpp
#include "stdafx.h"
#include "server.h"
#include "serverDlg.h"
#include "usuarios.h"
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
CMSWinsockControl proba;
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDlg dialog
98
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
//{{AFX_DATA_INIT(CServerDlg)
m_edit1 = _T("");
m_edit2 = _T("OFF");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
//proba.SetRemoteHost(m_host);
//proba.SetRemotePort(atoi(m_port));
BEGIN_MESSAGE_MAP(CServerDlg, CDialog)
//{{AFX_MSG_MAP(CServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_EN_CHANGE(IDC_EDIT1, OnTactual)
ON_BN_CLICKED(IDOK, OnEnviarres)
ON_EN_CHANGE(IDC_EDIT2, OnChangeConsigna)
ON_BN_CLICKED(IDC_BUTTON2, OnValidarPSWRW)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BUTTON1, OnCambiarPSW)
ON_BN_CLICKED(IDOK7, OnEnableClient0)
ON_BN_CLICKED(IDOK3, OnEnableClient1)
ON_BN_CLICKED(IDOK4, OnEnableClient2)
ON_BN_CLICKED(IDOK6, OnEnableClient4)
ON_BN_CLICKED(IDOK5, OnEnableClient3)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDlg message handlers
BOOL CServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
99
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
PasswordRW="master";
ServerOK=TRUE;
LocalIP = m_socket1.GetLocalIP();
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit3->SetWindowText(LocalIP); //Captamos la direccin actual del
servidor
EnableClient0=TRUE;
EnableClient1=TRUE;
EnableClient2=TRUE;
EnableClient3=TRUE;
EnableClient4=TRUE;
EnableALL=TRUE; //Habilitamos Todos los clientes
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CServerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
100
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CServerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
BEGIN_EVENTSINK_MAP(CServerDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CServerDlg)
ON_EVENT(CServerDlg, IDC_WINSOCK1, 1 /* Connect */, OnConnectWinsock1, VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK1, 2 /* ConnectionRequest */,
OnConnectionRequestWinsock1, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK1, 0 /* DataArrival */, OnDataArrivalWinsock1,
VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK1, 5 /* Close */, OnCloseWinsock1, VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK2, 2 /* ConnectionRequest */,
OnConnectionRequestWinsock2, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK2, 0 /* DataArrival */, OnDataArrivalWinsock2,
VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK2, 5 /* Close */, OnCloseWinsock2, VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK4, 2 /* ConnectionRequest */,
OnConnectionRequestWinsockClienteR, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK4, 0 /* DataArrival */,
OnDataArrivalWinsockClienteR, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK4, 5 /* Close */, OnCloseWinsockClienteR,
VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK3, 5 /* Close */, OnCloseWinsock3, VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK3, 2 /* ConnectionRequest */,
OnConnectionRequestWinsockClienteRDatos, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK3, 0 /* DataArrival */,
OnDataArrivalWinsockClienteRDatos, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK3, 4 /* SendComplete */,
OnSendCompleteWinsockClienteRDatos, VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK5, 2 /* ConnectionRequest */,
OnConnectionRequestWinsockClienteRExit, VTS_I4)
ON_EVENT(CServerDlg, IDC_WINSOCK2, 4 /* SendComplete */, OnSendCompleteWinsock2,
VTS_NONE)
ON_EVENT(CServerDlg, IDC_WINSOCK5, 5 /* Close */, OnCloseWinsock5, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CServerDlg::OnConnectWinsock1()
{
// TODO: Add your control notification handler code here
void CServerDlg::OnEnviarres()
{
if(EnableALL)
{
EnableClient0=FALSE;
EnableClient1=FALSE;
EnableClient2=FALSE;
EnableClient3=FALSE;
EnableClient4=FALSE;
EnableALL=FALSE;
AfxMessageBox ("Clientes deshabilitados");
}
else
{
EnableClient0=TRUE;
EnableClient1=TRUE;
EnableClient2=TRUE;
EnableClient3=TRUE;
EnableClient4=TRUE;
EnableALL=TRUE;
AfxMessageBox ("Clientes habilitados");
}
101
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CString strport;
VARIANT vtData;
VARIANT vtType;
VARIANT vtMaxlen;
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket1.GetData(&vtData,vtType,vtMaxlen);
if(mensaje=="Desconectar")
{
m_socket1.Close();
m_socket1.Listen();
m_socket2.Close();
m_socket2.Listen();
Socket1=FALSE;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT5); //captamos contenido edit
pEdit->SetWindowText("Desconectado");
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT1);
pEdit1->SetWindowText("OFF");
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit2->SetWindowText("OFF"); //Si el mensaje es desonectar cerramos la
conexin con scada y cliente escritura
}
else
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT1);
pEdit->SetWindowText(mensaje); //Actualizamos temperatura actual
}
void CServerDlg::OnCloseWinsock1()
{
OnCloseWinsock2();
Socket1=FALSE; //Desactivamos el flag de conexin con scada
m_socket1.Close();
m_socket1.Listen(); //Reiniciamos socket 1
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT5);
pEdit->SetWindowText("Desconectado");
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT1);
pEdit1->SetWindowText("OFF");
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit2->SetWindowText("OFF"); //Informamos por pantalla
102
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
void CServerDlg::InitSocket()
{
//////CONFIGURACIN PUERTOS/////////////////////
m_host = LocalIP;
m_port = "888";
m_port2 = "889";
m_port3 = "891";
m_port4 = "890";
m_port5 = "892";
////////////////////////////////////////////////
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
m_socket1.SetLocalPort(atoi(m_port)); //El proceso servidor crea ("abre") el
socket servidor(socket)
//m_socket1.Bind(vtPort,vtHost); //le asigna un puerto (bind) en la mquina
servidora
m_socket1.Listen(); //prepara para la escucha
vtPort.bstrVal=m_port2.AllocSysString();
m_socket2.SetLocalPort(atoi(m_port2));
//m_socket2.Bind(vtPort,vtHost);
m_socket2.Listen();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port4.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
vtPort.bstrVal=m_port4.AllocSysString();
m_socket4.SetLocalPort(atoi(m_port4));
//m_socket4.Bind(vtPort,vtHost);
m_socket4.Listen();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port3.AllocSysString();
m_socket3.SetLocalPort(atoi(m_port3));
//m_socket3.Bind(vtPort,vtHost);
m_socket3.Listen();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port5.AllocSysString();
m_socket5.SetLocalPort(atoi(m_port5));
//m_socket5.Bind(vtPort,vtHost);
m_socket5.Listen();
103
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
//////////////////////////////////////////////////////////////
//Evento temporizador
if(mensaje!="OFF")
{
//OnEnviarres();
}
void CServerDlg::OnTactual()
{
CString Data;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT1); //captamos contenido edit
pEdit->GetWindowText(Data);
104
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
long Port;
CString IP;
BOOL encontrado=FALSE;
if(Socket1==TRUE)
{
m_socket2.Close();
IP = m_socket2.GetRemoteHostIP();
Port = m_socket2.GetRemotePort();
vtHost.vt=VT_BSTR;
vtHost.bstrVal=IP.AllocSysString();
m_socket2.Accept(requestID);
}
else
{
m_socket2.Close();
IP = m_socket2.GetRemoteHostIP();
Port = m_socket2.GetRemotePort();
vtHost.vt=VT_BSTR;
vtHost.bstrVal=IP.AllocSysString();
m_socket2.Accept(requestID);
VARIANT vtDato;
CString Dato;
Dato = "SCADA OFF";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket2.SendData(vtDato);
}
CString strport;
VARIANT vtData;
VARIANT vtType;
VARIANT vtMaxlen;
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket2.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
if(mensaje!="Obtener"&&mensaje!="PASS"&&mensaje!="master"&&Socket1==TRUE&&Passwor
d==TRUE)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit->SetWindowText(mensaje);
}
if(mensaje=="PASS")
{
VARIANT vtDato;
105
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CString Dato;
Dato = "PASS";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket2.SendData(vtDato);
}
if(mensaje==PasswordRW)
{
CString IP;
Password=TRUE;
VARIANT vtDato;
CString Dato;
Dato = "Conectado";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket2.SendData(vtDato);
IP = m_socket2.GetRemoteHostIP();
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT6); //captamos contenido edit
pEdit->SetWindowText(IP);
}
if(Socket1==TRUE&&Password==TRUE)
{
if(mensaje=="Obtener")
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT1); //captamos
contenido edit
pEdit->GetWindowText(mensaje);
vtData.vt=VT_BSTR;
vtData.bstrVal=mensaje.AllocSysString();
m_socket2.SendData(vtData);
}
else
{
}
}
if(Socket1==FALSE)
{
VARIANT vtDato;
CString Dato;
Dato = "SCADA OFF";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket2.SendData(vtDato);
}
void CServerDlg::OnCloseWinsock2()
{
//AfxMessageBox ("Close2");
Password=FALSE;
m_socket2.Close();
m_socket2.Listen();
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT6); //captamos contenido edit
pEdit->SetWindowText("");
void CServerDlg::OnChangeConsigna()
{
106
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
if(Socket1==TRUE)
{
VARIANT vtmensaje;
CString mensaje;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT2); //captamos contenido edit
pEdit->GetWindowText(mensaje);
vtmensaje.vt=VT_BSTR;
vtmensaje.bstrVal=mensaje.AllocSysString();
m_socket1.SendData(vtmensaje);
}
if(ServerOK==TRUE)
{
ServerOK=FALSE;
m_socket4.Close();
IP = m_socket4.GetRemoteHostIP();
Port = m_socket4.GetRemotePort();
vtHost.vt=VT_BSTR;
vtHost.bstrVal=IP.AllocSysString();
m_socket4.Accept(requestID);
VARIANT vtDato;
CString Dato;
Dato = "Pass";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket4.SendData(vtDato);
ServerOK=TRUE;
}
else
{
m_socket4.Close();
IP = m_socket4.GetRemoteHostIP();
Port = m_socket4.GetRemotePort();
vtHost.vt=VT_BSTR;
vtHost.bstrVal=IP.AllocSysString();
m_socket4.Accept(requestID);
VARIANT vtDato;
CString Dato;
Dato = "Servidor ocupado";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket4.SendData(vtDato);
}
BOOL encontrado=FALSE;
CString strport;
VARIANT vtData;
VARIANT vtType;
VARIANT vtMaxlen;
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
107
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket4.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
vtHost.vt=VT_BSTR;
108
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port4.AllocSysString();
m_socket4.SetLocalPort(atoi(m_port4));
m_socket4.Listen(); //prepara para la escucha
}
if(!encontrado)
{
mensaje="PassWord Incorrecto";
VARIANT vtDato;
vtDato.vt=VT_BSTR;
vtDato.bstrVal=mensaje.AllocSysString();
m_socket4.SendData(vtDato); //Enviamos la cliente la informacin
}
void CServerDlg::OnCloseWinsockClienteR()
{
m_socket4.Close();
m_socket4.Listen();
void CServerDlg::OnCloseWinsock3()
{
m_socket3.Close();
m_socket3.Listen();
}
void CServerDlg::OnValidarPSWRW()
{
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT3); //captamos contenido edit
pEdit2->GetWindowText(PasswordRW);
AfxMessageBox ("Contrasea cliente escritura modificada");
}
void CServerDlg::OnDestroy()
{
m_socket1.Close();
m_socket2.Close();
m_socket3.Close();
m_socket4.Close();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
m_socket1.SetLocalPort(atoi(m_port)); //El proceso servidor crea ("abre") el
socket servidor(socket)
vtPort.bstrVal=m_port2.AllocSysString();
m_socket2.SetLocalPort(atoi(m_port2)); //El proceso servidor crea ("abre") el
socket servidor(socket)
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
vtPort.bstrVal=m_port4.AllocSysString();
m_socket4.SetLocalPort(atoi(m_port4));
CDialog::OnDestroy();
109
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
if(ServerOK==TRUE)
{
ServerOK=FALSE;
long Port;
CString IP;
CString Dato;
m_socket3.Close();
IP = m_socket3.GetRemoteHostIP();
Port = m_socket3.GetRemotePort();
vtHost.vt=VT_BSTR;
vtHost.bstrVal=IP.AllocSysString();
m_socket3.Accept(requestID);
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT1); //captamos contenido edit
pEdit2->GetWindowText(Dato);
VARIANT vtDato;
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket3.SendData(vtDato);
}
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket3.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
void CServerDlg::OnCambiarPSW()
{
CString PSW;
110
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
pEdit2->GetWindowText(PSW);
strcpy(m_ListaUsuarios[2]->m_strPass , PSW);
void CServerDlg::OnSendCompleteWinsockClienteRDatos()
{
m_socket3.Close();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port3.AllocSysString();
m_socket3.SetLocalPort(atoi(m_port3));
m_socket3.Listen(); //prepara para la escucha
ServerOK=TRUE;
void CServerDlg::OnEnableClient0()
{
if(EnableClient0)
{
EnableClient0=FALSE;
AfxMessageBox ("Cliente deshabilitado 0");
}
else
{
EnableClient0=TRUE;
AfxMessageBox ("Cliente habilitado 0");
}
void CServerDlg::OnEnableClient1()
{
if(EnableClient1)
{
EnableClient1=FALSE;
AfxMessageBox ("Cliente deshabilitado 1");
}
else
{
EnableClient1=TRUE;
AfxMessageBox ("Cliente habilitado 1");
}
void CServerDlg::OnEnableClient2()
{
if(EnableClient2)
{
EnableClient2=FALSE;
AfxMessageBox ("Cliente deshabilitado 2");
}
else
{
EnableClient2=TRUE;
AfxMessageBox ("Cliente habilitado 2");
111
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
void CServerDlg::OnEnableClient3()
{
if(EnableClient3)
{
EnableClient3=FALSE;
AfxMessageBox ("Cliente deshabilitado 3");
}
else
{
EnableClient3=TRUE;
AfxMessageBox ("Cliente habilitado 3");
}
}
void CServerDlg::OnEnableClient4()
{
if(EnableClient4)
{
EnableClient4=FALSE;
AfxMessageBox ("Cliente deshabilitado 3");
}
else
{
EnableClient4=TRUE;
AfxMessageBox ("Cliente habilitado 3");
}
112
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
}
if(i==2)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT17); //captamos
contenido edit
pEdit->SetWindowText("");
}
if(i==3)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT20); //captamos
contenido edit
pEdit->SetWindowText("");
}
if(i==4)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT23); //captamos
contenido edit
pEdit->SetWindowText("");
}
m_socket5.Close();
m_socket5.Listen(); //Reiniciamos socket5
void CServerDlg::OnSendCompleteWinsock2()
{
if(Socket1!=TRUE)
{
m_socket2.Close();
vtPort.bstrVal=m_port2.AllocSysString();
m_socket2.SetLocalPort(atoi(m_port2)); //El proceso servidor crea (abre) el
socket servidor(socket)
//m_socket2.Bind(vtPort,vtHost); //le asigna un puerto (bind) en la mquina
servidora
m_socket2.Listen(); //prepara para la escucha
}
}
void CServerDlg::OnCloseWinsock5()
{
m_socket5.Close();
m_socket5.Listen();
113
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ServerDlg.h
#if !defined(AFX_SERVERDLG_H__19163570_82D7_4BBA_B402_87FB2A55328F__INCLUDED_)
#define AFX_SERVERDLG_H__19163570_82D7_4BBA_B402_87FB2A55328F__INCLUDED_
#include <stdlib.h>
#include <stdio.h>
#include "Usuarios.h"
#define MAX_USUARIOS 5
/////////////////////////////////////////////////////////////////////////////
// CServerDlg dialog
void InitSocket();
CServerDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CServerDlg)
enum { IDD = IDD_SERVER_DIALOG };
CButton m_ok;
BOOL Socket1;
BOOL Password;
BOOL EnableClient0;
BOOL EnableClient1;
BOOL EnableClient2;
BOOL EnableClient3;
BOOL EnableClient4;
BOOL EnableALL;
CString PasswordRW;
CString LocalIP;
CString m_edit1;
CString m_edit2;
CString m_host;
CString m_port;
CString m_port2;
CString m_port3;
CString m_port4;
CString m_port5;
VARIANT vtHost;
VARIANT vtPort;
BOOL DataSocket2;
CMSWinsockControl m_socket2;
CMSWinsockControl m_socket1;
CMSWinsockControl m_socket3;
CMSWinsockControl m_socket4;
BOOL ServerOK; //Flag indicador del estado actual para recibir peticiones
cliente
CMSWinsockControl m_socket5;
//}}AFX_DATA
// Implementation
protected:
HICON m_hIcon;
114
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CUsuarios* m_ListaUsuarios[MAX_USUARIOS];
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
#endif // !defined(AFX_SERVERDLG_H__19163570_82D7_4BBA_B402_87FB2A55328F__INCLUDED_)
115
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Usuarios.cpp
#include "stdafx.h"
//#include "serverDlg.h"
#include "Usuarios.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CUsuarios::CUsuarios()
{
CUsuarios::~CUsuarios()
{
116
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Usuarios.h
#if !defined(AFX_USUARIOS_H__82CF0162_1C36_434C_A754_83889ED833F4__INCLUDED_)
#define AFX_USUARIOS_H__82CF0162_1C36_434C_A754_83889ED833F4__INCLUDED_
class CUsuarios
{
public:
char m_strPass[20];
char m_strIP[20];
CUsuarios();
CUsuarios(char* strPass, char* strIP);
virtual ~CUsuarios();
};
#endif // !defined(AFX_USUARIOS_H__82CF0162_1C36_434C_A754_83889ED833F4__INCLUDED_)
117
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
PFC.rc
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PFC.rc
//
#define IDOK2 3
#define IDOK3 4
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_PFC_DIALOG 102
#define IDP_SOCKETS_INIT_FAILED 103
#define IDD_SCADA 129
#define IDD_CLIENTE_LECTURA 133
#define IDD_CLIENTE_ESCRITURA 134
#define IDI_ICON 148
#define IDC_WINSOCK1 1000
#define IDC_EDIT1 1001
#define IDC_BUTTON1 1002
#define IDC_EDIT2 1003
#define IDC_EDIT3 1004
#define IDC_EDIT4 1005
#define IDC_BUTTON2 1006
#define IDC_EDIT5 1007
#define IDC_EDIT6 1008
#define IDC_EDIT7 1009
#define IDC_EDIT8 1010
#define IDC_EDIT14 1011
#define IDC_BUTTON5 1011
#define IDC_EDIT9 1012
#define IDC_EDIT10 1013
#define IDC_BUTTON4 1014
#define IDC_BUTTON3 1015
#define IDC_EDIT11 1016
#define IDC_EDIT12 1017
#define IDC_EDIT13 1018
#define IDC_BUTTON6 1019
#define IDC_WINSOCK2 1020
#define IDC_WINSOCK3 1021
118
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
PFC.cpp
#include "stdafx.h"
#include "PFC.h"
#include "PFCDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPFCApp
BEGIN_MESSAGE_MAP(CPFCApp, CWinApp)
//{{AFX_MSG_MAP(CPFCApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPFCApp construction
CPFCApp::CPFCApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CPFCApp object
CPFCApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CPFCApp initialization
BOOL CPFCApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CPFCDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
119
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
120
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
PFC.h
#if !defined(AFX_PFC_H__56431A0E_2054_44D7_B064_8031C28BF07D__INCLUDED_)
#define AFX_PFC_H__56431A0E_2054_44D7_B064_8031C28BF07D__INCLUDED_
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
/////////////////////////////////////////////////////////////////////////////
// CPFCApp:
// See PFC.cpp for the implementation of this class
//
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPFCApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CPFCApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
#endif // !defined(AFX_PFC_H__56431A0E_2054_44D7_B064_8031C28BF07D__INCLUDED_)
121
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Scada.cpp
#include "stdafx.h"
#include "PFC.h"
#include "Scada.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScada dialog
BEGIN_MESSAGE_MAP(CScada, CDialog)
//{{AFX_MSG_MAP(CScada)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON1, OnEnviarConsignaScada)
ON_EN_CHANGE(IDC_EDIT1, OnChangeConsignaScada)
ON_BN_CLICKED(IDC_BUTTON2, OnConectar)
ON_BN_CLICKED(IDC_BUTTON4, OnActualizar)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScada message handlers
BOOL CScada::OnInitDialog()
{
CDialog::OnInitDialog();
m_host = "127.0.0.1";
m_port = "888";
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
122
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Consigna=23;
Remote=FALSE;
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit3->SetWindowText("23");
LocalIP = m_socket1.GetLocalIP();
CEdit* pEdit4 = (CEdit*) GetDlgItem(IDC_EDIT8);
pEdit4->SetWindowText(LocalIP);
SetTimer(1, 500, NULL);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
BEGIN_EVENTSINK_MAP(CScada, CDialog)
//{{AFX_EVENTSINK_MAP(CScada)
ON_EVENT(CScada, IDC_WINSOCK1, 1 /* Connect */, OnConnectWinsock1, VTS_NONE)
ON_EVENT(CScada, IDC_WINSOCK1, 0 /* DataArrival */, OnDataArrivalWinsock1,
VTS_I4)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CScada::OnConnectWinsock1()
{
Remote=TRUE;
}
else
{
Remote=FALSE;
}
int TA;
CString Tact;
CString Data;
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit2->GetWindowText(Tact);
TA = atoi( Tact );
if (TA!=Consigna||TA!=23)
123
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
{
if (TA>Consigna)
{
TA=TA-1;
}
if (TA<Consigna)
{
TA=TA+1;
}
}
char buffer[20];
_itoa( TA, buffer, 10 );
Data=buffer;
/////////////////////////////////////
CDialog::OnTimer(nIDEvent);
}
void CScada::OnEnviarConsignaScada()
{
if(Remote==FALSE)
{
if(ConsignaSCADA<23||ConsignaSCADA>281)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT3);
pEdit->SetWindowText("Valor de consigna no valido");
}
else
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT3);
pEdit->SetWindowText("Valor de consigna valido");
Consigna = ConsignaSCADA;
}
}
else
{
AfxMessageBox ("El control Remoto esta activado");
}
void CScada::OnChangeConsignaScada()
{
CString ConsignaScada;
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT1);
pEdit1->GetWindowText(ConsignaScada);
ConsignaSCADA = atoi( ConsignaScada );
if(Remote==FALSE)
{
if(ConsignaSCADA<23||ConsignaSCADA>281)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT3);
pEdit->SetWindowText("Valor de consigna no valido");
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit1->GetWindowText(ConsignaScada);
ConsignaSCADA = atoi ( ConsignaScada );
}
else
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT3);
124
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
}
}
else
{
}
}
void CScada::OnConectar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado);
if (estado == "Conectado")
{
VARIANT vtDato;
CString Dato;
Dato = "Desconectar";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket1.SendData(vtDato);
AfxMessageBox ("sistema desconectado");
}
else if (estado =! "Conectado")
{
m_socket1.Close();
m_socket1.Connect(vtHost,vtPort);
void CScada::OnActualizar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado);
CString Host;
CString Host1;
CString Host2;
CString Host3;
CString Port;
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT9);
pEdit1->GetWindowText(Host);
Host=Host+".";
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT10);
pEdit2->GetWindowText(Host1);
Host1=Host+Host1+".";
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT11);
pEdit3->GetWindowText(Host2);
Host2=Host1+Host2+".";
CEdit* pEdit4 = (CEdit*) GetDlgItem(IDC_EDIT12);
pEdit4->GetWindowText(Host3);
Host3=Host2+Host3;
m_host = Host3;
m_port = Port;
125
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
}
}
void CScada::OnDestroy()
{
m_socket1.Close();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
CDialog::OnDestroy();
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket1.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
void CScada::OnEnviar()
{
VARIANT vtDato;
CString Dato;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT2); //captamos contenido edit
126
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
pEdit->GetWindowText(Dato);
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket1.SendData(vtDato);
127
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Scada.h
//{{AFX_INCLUDES()
#include "mswinsockcontrol.h"
//}}AFX_INCLUDES
#if !defined(AFX_SCADA_H__683A305E_4720_4EBE_BE59_D291D9905FB7__INCLUDED_)
#define AFX_SCADA_H__683A305E_4720_4EBE_BE59_D291D9905FB7__INCLUDED_
#include "mswinsockcontrol.h"
#include "ConvertirEstado.h"
// Dialog Data
//{{AFX_DATA(CScada)
enum { IDD = IDD_SCADA };
CMSWinsockControl m_socket1;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CScada)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
#endif // !defined(AFX_SCADA_H__683A305E_4720_4EBE_BE59_D291D9905FB7__INCLUDED_)
128
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ConvertirEstado.cpp
#include "stdafx.h"
#include "PFC.h"
#include "ConvertirEstado.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////
// CConvertirEstado
CConvertirEstado::CConvertirEstado()
{
}
CConvertirEstado::~CConvertirEstado()
{
}
CString CConvertirEstado::ConvertirEstado(int Estado)
{
switch (Estado)
{
case 0:
return "Cerrado";
break;
case 1:
return "Abierto";
break;
case 2:
return "Escuchando";
break;
case 3:
return "Conexin pendiente de abrir";
break;
case 4:
return "Resolviendo Host";
break;
case 5:
return "Host Resuelto";
break;
case 6:
return "Conectando";
break;
case 7:
return "Conectado";
break;
case 8:
return "Peer esta cerrando la conexin";
break;
case 9:
return "Error";
break;
case 10:
return "Invalido";
break;
default:
return "";
break;
}
BEGIN_MESSAGE_MAP(CConvertirEstado, CWnd)
//{{AFX_MSG_MAP(CConvertirEstado)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
129
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
ConvertirEstado.h
#if !defined(AFX_CONVERTIRESTADO_H__6D8B783D_F4FA_4EB0_B6B0_21636F95514C__INCLUDED_)
#define AFX_CONVERTIRESTADO_H__6D8B783D_F4FA_4EB0_B6B0_21636F95514C__INCLUDED_
/////////////////////////////////////////////////////////////////////////////
// CConvertirEstado window
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CConvertirEstado)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CConvertirEstado();
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
#endif //
!defined(AFX_CONVERTIRESTADO_H__6D8B783D_F4FA_4EB0_B6B0_21636F95514C__INCLUDED_)
130
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CEscritura.cpp
#include "stdafx.h"
#include "PFC.h"
#include "CEscritura.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCEscritura dialog
BEGIN_MESSAGE_MAP(CCEscritura, CDialog)
//{{AFX_MSG_MAP(CCEscritura)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON2, OnConectar)
ON_BN_CLICKED(IDC_BUTTON4, OnActualizar)
ON_BN_CLICKED(IDC_BUTTON3, OnConfirmarPassword)
ON_BN_CLICKED(IDC_BUTTON5, OnObtener)
ON_BN_CLICKED(IDC_BUTTON1, OnEnviar)
ON_EN_CHANGE(IDC_EDIT1, OnChangeConsigna)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCEscritura message handlers
BOOL CCEscritura::OnInitDialog()
{
CDialog::OnInitDialog();
short estado;
m_host = "127.0.0.1";
m_port = "889";
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
131
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
Consigna=0;
Remote=FALSE;
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit3->SetWindowText("OFF");
LocalIP = m_socket1.GetLocalIP();
CEdit* pEdit4 = (CEdit*) GetDlgItem(IDC_EDIT8);
pEdit4->SetWindowText(LocalIP);
estado=m_socket1.GetState();
CConvertirEstado m_convertirEstado;
CEdit* pEdit5 = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit5->SetWindowText(m_convertirEstado.ConvertirEstado(estado)); //Mostramos
estado de conexin por pantalla
SetTimer(1, 500, NULL); //Activacin sel temporizador
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
BEGIN_EVENTSINK_MAP(CCEscritura, CDialog)
//{{AFX_EVENTSINK_MAP(CCEscritura)
ON_EVENT(CCEscritura, IDC_WINSOCK1, 1 /* Connect */, OnConnectWinsock1, VTS_NONE)
ON_EVENT(CCEscritura, IDC_WINSOCK1, 0 /* DataArrival */, OnDataArrivalWinsock1,
VTS_I4)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CCEscritura::OnConnectWinsock1()
{
VARIANT vtDato;
CString Dato;
Dato = "PASS";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket1.SendData(vtDato); //Solicitamos permiso de introduccin de
contrasea al servidor
void CCEscritura::OnConectar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado); //Captamos el estado de la conexin con el servidor
if (estado == "Conectado")
{
AfxMessageBox ("El sistema ya esta conectado");
}
else if (estado =! "Conectado")
132
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
{
PASS=TRUE;
m_socket1.Close();
m_socket1.Connect(vtHost,vtPort); //Si el sistema esta desconectado,
conectamos con el servidor
}
}
void CCEscritura::OnActualizar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado); //Captamos el estado de la conexin con el servidor
CString Host;
CString Host1;
CString Host2;
CString Host3;
CString Port;
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT9);
pEdit1->GetWindowText(Host);
Host=Host+".";
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT10);
pEdit2->GetWindowText(Host1);
Host1=Host+Host1+".";
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT11);
pEdit3->GetWindowText(Host2);
Host2=Host1+Host2+".";
CEdit* pEdit4 = (CEdit*) GetDlgItem(IDC_EDIT12);
pEdit4->GetWindowText(Host3);
Host3=Host2+Host3;
m_host = Host3;
m_port = Port;
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
}
133
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket1.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
if(mensaje!="SCADA
OFF"&&mensaje!="PASS"&&mensaje!="Pass"&&mensaje!="Conectado"&&mensaje!="PASSSCADA
OFF"&&mensaje!="SCADA OFFPASSSCADA OFF")
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->SetWindowText("Conectado");
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit1->SetWindowText(mensaje);
if(mensaje=="PASS")
{
PASS=TRUE;
AfxMessageBox ("Confirmar Password");
}
if(mensaje=="Conectado")
{
AfxMessageBox ("Password correcto");
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit1->SetWindowText("Conectado");
PASS=FALSE;
}
if(mensaje=="SCADA OFF")
{
PASS=TRUE;
AfxMessageBox ("Control Remoto SCADA desactivado");
m_socket1.Close();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit1->SetWindowText("Desconectado");
}
void CCEscritura::OnConfirmarPassword()
{
if(PASS==TRUE)
{
VARIANT vtDato;
134
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CString Dato;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT5);
pEdit->GetWindowText(Dato);
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket1.SendData(vtDato);
}
}
void CCEscritura::OnObtener()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado);
if (estado == "Conectado")
{
VARIANT vtDato;
CString Dato;
Dato = "Obtener";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket1.SendData(vtDato);
}
else if (estado =! "Conectado")
{
AfxMessageBox ("El sistema no esta conectado");
}
void CCEscritura::OnEnviar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado);
if (estado == "Conectado")
{
VARIANT vtDato;
CString Dato;
char buffer[20];
_itoa( Consigna, buffer, 10 );
Dato=buffer;
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
if(Dato!="0")
{
m_socket1.SendData(vtDato);
}
}
else if (estado =! "Conectado")
{
AfxMessageBox ("El sistema no esta conectado");
}
}
void CCEscritura::OnChangeConsigna()
{
int PreConsigna;
CString Dato;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT1);
pEdit->GetWindowText(Dato);
PreConsigna = atoi( Dato );
if(PreConsigna<23||PreConsigna>180)
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT3);
pEdit->SetWindowText("Valor de consigna no valido");
}
else
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT3);
135
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
void CCEscritura::OnDestroy()
{
m_socket1.Close();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
CDialog::OnDestroy();
136
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CEscritura.h
//{{AFX_INCLUDES()
#include "mswinsockcontrol1.h"
//}}AFX_INCLUDES
#if !defined(AFX_CESCRITURA_H__D8EBDECD_F8A6_4AD4_B241_E0B58BE3F967__INCLUDED_)
#define AFX_CESCRITURA_H__D8EBDECD_F8A6_4AD4_B241_E0B58BE3F967__INCLUDED_
#include "mswinsockcontrol.h"
#include "ConvertirEstado.h"
// Dialog Data
//{{AFX_DATA(CCEscritura)
enum { IDD = IDD_CLIENTE_ESCRITURA };
CMSWinsockControl1 m_socket1;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCEscritura)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
#endif // !defined(AFX_CESCRITURA_H__D8EBDECD_F8A6_4AD4_B241_E0B58BE3F967__INCLUDED_)
137
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
CLectura.cpp
#include "stdafx.h"
#include "PFC.h"
#include "CLectura.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CCLectura dialog
BEGIN_MESSAGE_MAP(CCLectura, CDialog)
//{{AFX_MSG_MAP(CCLectura)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON4, OnActualizar)
ON_BN_CLICKED(IDC_BUTTON2, OnConectar)
ON_BN_CLICKED(IDC_BUTTON3, OnConfirmarPassword)
ON_BN_CLICKED(IDC_BUTTON6, OnObtener)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCLectura message handlers
BOOL CCLectura::OnInitDialog()
{
CDialog::OnInitDialog();
short estado;
m_host = "127.0.0.1";
m_port = "890";
m_portR = "891";
m_portExit = "892";
PASS = FALSE;
Remote = FALSE;
Obtener = FALSE;
138
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
vtHostR.vt=VT_BSTR;
vtPortR.vt=VT_BSTR;
vtHostR.bstrVal=m_host.AllocSysString();
vtPortR.bstrVal=m_portR.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket2.SetRemotePort(atoi(m_portR));
m_socket2.SetRemoteHost(m_host);
vtHostExit.vt=VT_BSTR;
vtPortExit.vt=VT_BSTR;
vtHostExit.bstrVal=m_host.AllocSysString();
vtPortExit.bstrVal=m_portExit.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket3.SetRemotePort(atoi(m_portExit));
m_socket3.SetRemoteHost(m_host);
Consigna=23;
Remote=FALSE;
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT2);
pEdit3->SetWindowText("OFF");
LocalIP = m_socket1.GetLocalIP();
CEdit* pEdit4 = (CEdit*) GetDlgItem(IDC_EDIT8);
pEdit4->SetWindowText(LocalIP);
estado=m_socket1.GetState();
CConvertirEstado m_convertirEstado;
CEdit* pEdit5 = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit5->SetWindowText(m_convertirEstado.ConvertirEstado(estado));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CCLectura::OnActualizar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado);
139
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
if (estado != "Desconectado")
{
AfxMessageBox ("El sistema ya esta conectado con la IP establecida. Para
establecer una nueva direccin debe reiniciar el programa");
}
else if (estado == "Desconectado")
{
CString Host;
CString Host1;
CString Host2;
CString Host3;
CString Port;
CEdit* pEdit1 = (CEdit*) GetDlgItem(IDC_EDIT9);
pEdit1->GetWindowText(Host);
Host=Host+".";
CEdit* pEdit2 = (CEdit*) GetDlgItem(IDC_EDIT10);
pEdit2->GetWindowText(Host1);
Host1=Host+Host1+".";
CEdit* pEdit3 = (CEdit*) GetDlgItem(IDC_EDIT11);
pEdit3->GetWindowText(Host2);
Host2=Host1+Host2+".";
CEdit* pEdit4 = (CEdit*) GetDlgItem(IDC_EDIT12);
pEdit4->GetWindowText(Host3);
Host3=Host2+Host3;
m_host = Host3;
m_port = Port;
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_portR.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket2.SetRemotePort(atoi(m_portR));
m_socket2.SetRemoteHost(m_host);
}
void CCLectura::OnConectar()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado); //Captamos el estado de la conexin con el servidor
if (estado == "Conectado")
{
AfxMessageBox ("El sistema ya esta conectado");
}
else if (estado =! "Conectado")
{
140
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
m_socket1.Close();
m_socket1.Connect(vtHost,vtPort); //Si el sistema esta desconectado,
conectamos con el servidor
SetTimer(1, 10000, NULL); //Activamos temporizador
BEGIN_EVENTSINK_MAP(CCLectura, CDialog)
//{{AFX_EVENTSINK_MAP(CCLectura)
ON_EVENT(CCLectura, IDC_WINSOCK1, 1 /* Connect */, OnConnectWinsock1, VTS_NONE)
ON_EVENT(CCLectura, IDC_WINSOCK1, 0 /* DataArrival */, OnDataArrivalWinsock1,
VTS_I4)
ON_EVENT(CCLectura, IDC_WINSOCK2, 1 /* Connect */, OnConnectWinsock2, VTS_NONE)
ON_EVENT(CCLectura, IDC_WINSOCK2, 0 /* DataArrival */, OnDataArrivalWinsock2,
VTS_I4)
ON_EVENT(CCLectura, IDC_WINSOCK2, 5 /* Close */, OnCloseWinsock2, VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
void CCLectura::OnConnectWinsock1()
{
Remote = TRUE;
PASS = TRUE;
AfxMessageBox ("Introducir Password");
void CCLectura::OnConfirmarPassword()
{
if (PASS)
{
VARIANT vtDato;
CString Dato;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT5);
pEdit->GetWindowText(Dato);
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket1.SendData(vtDato);
}
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket1.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
//AfxMessageBox (mensaje);
if(mensaje=="Aceptado")
{
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->SetWindowText("Conectado");
PASS = FALSE;
141
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
m_socket1.Close();
vtHost .vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_portR));
m_socket1.SetRemoteHost(m_host); //Una vez conectado se deja libre
socket1 para que otro cliente pueda conectarse con el servidor
void CCLectura::OnObtener()
{
CString estado;
CEdit* pEdit = (CEdit*) GetDlgItem(IDC_EDIT4);
pEdit->GetWindowText(estado);
if(estado=="Conectado")
{
//Si flag obtener desactivado, conectamos con servidor
if(Obtener==FALSE)
{
Obtener=TRUE;
SetTimer(1, 10000, NULL);
m_socket2.Close();
m_socket2.Connect(vtHostR,vtPortR);
}
}
}
void CCLectura::OnConnectWinsock2()
{
Remote = TRUE;
VARIANT vtDato;
CString Dato;
Dato = "Obtener";
vtDato.vt=VT_BSTR;
vtDato.bstrVal=Dato.AllocSysString();
m_socket2.SendData(vtDato);
//AfxMessageBox ("Obtener");
strport="4000";
vtData.vt=VT_BSTR;
vtType.vt=VT_ERROR;
vtMaxlen.vt=VT_I2;
vtMaxlen.iVal=(short)bytesTotal;
CString mensaje;
vtData.bstrVal=strport.AllocSysString();
vtType.bstrVal=strport.AllocSysString();
m_socket2.GetData(&vtData,vtType,vtMaxlen);
mensaje=vtData.bstrVal;
142
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
void CCLectura::OnDestroy()
{
m_socket1.Close();
vtHost.vt=VT_BSTR;
vtPort.vt=VT_BSTR;
vtHost.bstrVal=m_host.AllocSysString();
vtPort.bstrVal=m_port.AllocSysString();
//m_socket1.SetLocalPort(atoi(m_port));
//m_socket1.SetProtocol(0);
m_socket1.SetRemotePort(atoi(m_port));
m_socket1.SetRemoteHost(m_host);
m_socket3.Close();
m_socket3.Connect(vtHostExit,vtPortExit); //Conectamos con servidor para informar
de la desconexin del cliente
AfxMessageBox ("Si el sistema esta conectado con el servidor va a ser
desconectado");
CDialog::OnDestroy();
143
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
Clectura.h
//{{AFX_INCLUDES()
#include "mswinsockcontrol1.h"
//}}AFX_INCLUDES
#if !defined(AFX_CLECTURA_H__B61C1F2C_1840_4BA6_B788_E22CDD012BFA__INCLUDED_)
#define AFX_CLECTURA_H__B61C1F2C_1840_4BA6_B788_E22CDD012BFA__INCLUDED_
#include "mswinsockcontrol.h"
#include "ConvertirEstado.h"
/////////////////////////////////////////////////////////////////////////////
// CCLectura dialog
// Dialog Data
//{{AFX_DATA(CCLectura)
enum { IDD = IDD_CLIENTE_LECTURA };
CMSWinsockControl1 m_socket1;
CMSWinsockControl1 m_socket2;
CMSWinsockControl1 m_socket3;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCLectura)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
144
APLICACIN SCADA BASADA EN COMUNICACIN TCP/IP ESTEVEGRAUPINA
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the
previous line.
#endif // !defined(AFX_CLECTURA_H__B61C1F2C_1840_4BA6_B788_E22CDD012BFA__INCLUDED_)
145