Mostrando entradas con la etiqueta source code. Mostrar todas las entradas
Mostrando entradas con la etiqueta source code. Mostrar todas las entradas
5/06/2014
Cómo hacer screenshot captura pantalla pantallazo en C Sharp NET
Etiquetas:
c sharp,
c#,
captura,
código fuente,
csharp,
desarrollo,
lenguaje,
open source,
pantalla,
pantallazo,
programación,
screenshot,
source code,
videotutorial
5/03/2014
Cómo generar códigos de barras EAN8 y EAN13 con Delphi 6 Proyecto AjpdSoft
Tutorial donde mostramos cómo generar códigos de barras EAN8 y EAN13 desarrollando una aplicación con el lenguaje de programación Delphi 6. Incluimos una aplicación con código fuente gratuito: AjpdSoft Generador de códigos de barras, que servirá como ejemplo. Publicamos esta aplicación gratuita y open source (con código fuente en Delphi 6) que permite generar códigos de
barras EAN8 y EAN13. La aplicación permite imprimir el código generado o
guardarlo en fichero de imagen y calcular el dígito de control.
Etiquetas:
barcode,
barras,
código,
código barras,
código fuente,
delphi,
desarrollo,
ean13,
ean8,
lenguaje,
open source,
programación,
source code
Estructura del código de barras EAN 13 y ejemplo en Delphi de obtención de datos Proyecto AjpdSoft
Mostramos en este tutorial cuál es la estructura del código de barras EAN13 y cómo obtenerla con una aplicación en Delphi 6 AjpdSoft Obtener datos EAN13 en Delphi 6. Mostramos también cómo calcular el dígito de control de un código de barras EAN.
Etiquetas:
barcode,
barras,
código,
código barras,
código fuente,
delphi,
desarrollo,
ean13,
ean8,
lenguaje,
open source,
programación,
source code
AjpdSoft Generador de códigos de barras | Open Source Delphi 6
Etiquetas:
barcode,
barras,
código,
código barras,
código fuente,
delphi,
desarrollo,
hash,
lenguaje,
open source,
programación,
source code,
videotutorial
5/01/2014
AjpdSoft Generador y lector códigos QR | Gratuito | Código fuente open s...
Etiquetas:
.net,
barcode,
c sharp,
c#,
código barras,
código fuente,
csharp,
desarrollo,
lenguaje,
open source,
programación,
qr,
source code,
videotutorial,
visual studio .net
4/21/2014
AjpdSoft Gestión VMware ESXi y vCenter
Descarga gratuita (freeware) del código fuente (source code) 100% open source, desarrollado con Visual Studio .Net 2013 (C# C Sharp .NET) de la aplicación AjpdSoft Gestión VMware ESXi y vCenter:
accede a un servidor VMware ESXi o a un clúster de servidores VMware
vCenter Server y obtiene todas las máquinas virtuales y sus datos
básicos (nombre máquina virtual, estado (PowerState), tiempo de
inicio, estado conexión, vRAM, vCPU, cores por socket, estado VMware
Tools, hostname, IP, sistema operativo , ruta ficheros MV, ID Guest,
Uuid, WWN, anotaciones, número de discos, tamaño, ficheros que
componen la MV, alarmas, etc.). Además, esta aplicación también permite
ejecutar acciones sobre las máquinas virtuales como: iniciar máquina
virtual, apagar, pausar, resetear, reiniciar sistema operativo, apagar
sistema operativo, actualizar VMware Tools, instalar VMware Tools,
desmontar CD VMware Tools, cambiar nombre a máquina virtual, crear
snapshot, etc..
accede a un servidor VMware ESXi o a un clúster de servidores VMware
vCenter Server y obtiene todas las máquinas virtuales y sus datos
básicos (nombre máquina virtual, estado (PowerState), tiempo de
inicio, estado conexión, vRAM, vCPU, cores por socket, estado VMware
Tools, hostname, IP, sistema operativo , ruta ficheros MV, ID Guest,
Uuid, WWN, anotaciones, número de discos, tamaño, ficheros que
componen la MV, alarmas, etc.). Además, esta aplicación también permite
ejecutar acciones sobre las máquinas virtuales como: iniciar máquina
virtual, apagar, pausar, resetear, reiniciar sistema operativo, apagar
sistema operativo, actualizar VMware Tools, instalar VMware Tools,
desmontar CD VMware Tools, cambiar nombre a máquina virtual, crear
snapshot, etc..
7/22/2013
AjpdSoft Acceso PostgreSQL con Lazarus x64 código fuente Lazarus
Descarga gratuita (freeware) del código fuente (source code) 100% open source, desarrollado con Lazarus x64 de la aplicación de ejemplo AjpdSoft Acceso PostgreSQL Lazarus:
10/12/2012
AjpdSoft Gestión Integral código fuente
AjpdSoft Gestión Integral código fuente
Descarga gratuita (freeware) del código fuente (source code) 100% open source, desarrollado con Borland Delphi 6 de la aplicación: AjpdSoft Gestión Integral. Aplicación en fase beta y de depuración desarrollada para empresas que necesiten gestionar los partes de trabajo de sus técnicos y facturar a clientes. Permite gestionar incidencias (tareas, solicitudes), partes de trabajo, albaranes de proveedores, facturación (facturar a clientes y facturas de proveedores), cobros, pagos, cheques/pagarés, contactos, notas, caja, material (control de stock).
Descarga gratuita (freeware) del código fuente (source code) 100% open source, desarrollado con Borland Delphi 6 de la aplicación: AjpdSoft Gestión Integral. Aplicación en fase beta y de depuración desarrollada para empresas que necesiten gestionar los partes de trabajo de sus técnicos y facturar a clientes. Permite gestionar incidencias (tareas, solicitudes), partes de trabajo, albaranes de proveedores, facturación (facturar a clientes y facturas de proveedores), cobros, pagos, cheques/pagarés, contactos, notas, caja, material (control de stock).
1/06/2012
Descarga gratuita (freeware) del código fuente (source code) 100% open source, desarrollado con Visual Basic .Net 2010 de la aplicación: AjpdSoft Generador y Lector códigos QR.
Este código fuente en VB.Net muestra cómo generar códigos QR (Quick
Response Barcode), permite guardar el código QR en fichero de imagen
(PNG, BMP, GIF ó JPEG) o imprimirlo. AjpdSoft Generador y Lector códigos QR también lee o decodifica códigos QR ya generados y guardados en imagen.
10/24/2011
Socket Visual Basic .Net, conexión mediante socket VB.Net y System.Net.Sockets
Explicamos cómo conectar
dos PCs a través de Internet usando Socket, realizamos un ejemplo de
chat entre un PC servidor y sus clientes usando Microsoft Visual Basic .Net (VB.Net) y el Namespace System.Net.Sockets. Mostramos también como comparativa cómo se realizaba una conexión por Socket usando el antiguo lenguaje de programación Visual Basic 6, mediante Winsock.
- Socket de Internet.
- Conexión por socket en Visual Basic 6.0 y anteriores.
- Conexión por socket en Visual Basic .Net de Visual Studio 2010.
- AjpdSoft Socket VB.Net en funcionamiento.
- Artículos relacionados.
- Créditos.
Socket de Internet
Con Socket se designa un concepto abstracto por el
cual dos programas situados en computadoras distintas (o en la misma)
pueden intercambiar cualquier flujo de datos, generalmente de manera
fiable y ordenada.
El término socket es también usado como el nombre de una interfaz de programación de aplicaciones (API) para el stack de protocolos de Internet TCP/IP, provista usualmente por el sistema operativo.
Los sockets de Internet constituyen el mecanismo para
la entrega de paquetes de datos provenientes de la tarjeta de red a los
procesos o hilos apropiados. Un socket queda definido por un par de
direcciones IP local y remota, un protocolo de transporte y un par de números de puerto local y remoto.
Para que dos programas puedan comunicarse entre sí es necesario que se cumplan ciertos requisitos:
- Que un programa sea capaz de localizar al otro.
- Que ambos programas sean capaces de intercambiarse cualquier secuencia de octetos, es decir, datos relevantes a su finalidad.
Para ello son necesarios los tres recursos que originan el concepto de socket:
- Un protocolo de comunicaciones, que permite el intercambio de octetos.
- Un par de direcciones del protocolo de red (dirección IP, si se utiliza el protocolo TCP/IP), que identifican la computadora de origen y la remota.
- Un par de números de puerto, que identifican a un programa dentro de cada computadora.
Los sockets permiten implementar una
arquitectura cliente-servidor. La comunicación debe ser iniciada por
uno de los programas que se denomina programa "cliente". El segundo
programa espera a que otro inicie la comunicación, por este motivo se
denomina programa "servidor".
Un socket es un proceso o hilo existente en
la máquina cliente y en la máquina servidora, que sirve en última
instancia para que el programa servidor y el cliente lean y escriban
la información. Esta información será la transmitida por las
diferentes capas de red.
Conexión por socket en Visual Basic 6.0 y anteriores
Para las versiones de Visual Basic 6 y anteriores, si
queríamos desarrollar una aplicación con conexión por socket debíamos
usar el componente WinSock. Dicho componente se agregaba a Visual Basic 6 desde el menú "Proyecto" - "Componentes":
En la pestaña "Controles" buscamos "Microsoft Winsock Control 6.0":
C:/Windows/system32/MSWINSCK.OCK
lo marcamos y pulsamos "Aceptar":
Nos agregará un nuevo elemento a la paleta de componentes:
Aplicación servidor para conexión por socket con Visual Basic 6
Mostramos a continuación un ejemplo de aplicación en
Visual Basic 6 para conexión con Socket mediante Winsock, por un lado la
aplicación servidor, que tendrá este aspecto:
Una vez agregado el componente Winsock al formulario
de nuestra aplicación servidor VB6 podremos programarlo, por ejemplo,
para establecer el modo escucha de la que sería la aplicacion servidor,
agregando un botón llamado "btEscuchar" con el siguiente código:
Private Sub btEscuchar_Click()
on error goto cError
'Cerrar conexiones actuales
Winsock1.Close
'Puerto por el que escucharemos
Winsock1.LocalPort = txtPuerto.Text
'Activamos el modo escucha
Winsock1.Listen
'desplegamos un mensaje en la ventana
txtLog.Text = txtLog.Text & _
"Iniciado servidor, escuchando..." & vbCrLf
btDesactivarEscucha.Enabled = True
btEscuchar.Enabled = False
txtMensaje.Enabled = True
btEnviarMensaje.Enabled = True
:cSalir
exit sub
:cError
MsgBox "Error al activar servidor: " + err.number + vbcrlf + _
" Descripción del error: " + err.description
End Sub
El evento "ConnectionRequest" del componente WinSock se ejecutará cada vez que un cliente intente establecer una conexión con el servidor, podremos colocar el siguiente código:
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
'Mostrar mensaje cuando un cliente se conecte
txtLog.Text = txtLog.Text & _
"Petición de conexión cliente " & requestID & vbCrLf
'Cerrar el socket
Winsock1.Close
'Aceptar la conexión
Winsock1.Accept requestID
'desplegamos un mensaje en la ventana
txtLog.Text = txtLog.Text & "Cliente conectado: " & _
requestID & vbCrLf
End Sub
Para desactivar el modo escucha y cerrar todas las conexiones actuales en el servidor agregaremos el botón "btDesactivarEscucha" con el siguiente código:
Private Sub btDesactivarEscucha_Click() 'Cerrar conexión Socket Winsock1.Close End Sub
Cuando el usuario pulse en el botón "Desactivar escucha", se ejecutará el evento "Close" del WinSock, desde este evento podremos controlar cuando el servidor deja de escuchar clientes:
Private Sub Winsock1_Close()
txtLog.Text = txtLog.Text & _
"Desactivado modo escucha, no se aceptarán conexiones" & vbCrLf
btDesactivarEscucha.Enabled = False
btEscuchar.Enabled = True
txtMensaje.Enabled = False
btEnviarMensaje.Enabled = False
End Sub
Para agregar un botón al formulario del servidor que envíe un mensaje al cliente conectado (btEnviarMensaje) usaremos el siguiente código:
Private Sub btEnviarMensaje_Click() Winsock1.SendData txtMensaje.Text & vbCrLf End Sub
Para mostrar los mensajes enviados por los clientes
al servidor, usaremos el evento "DataArrival" del componente WinSock,
este evento se ejecuta cada vez que se reciben datos de algún cliente
conectado:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim datosRecibidos As String
'Obtener los datos enviados por el cliente
Winsock1.GetData datosRecibidos
txtMensajesClientes.Text = txtMensajesClientes.Text & _
"Mensaje: " & datosRecibidos
End Sub
Si se produce algún error podemos "controlarlo" con
el evento "Error" del componente "WinSock", por ejemplo podríamos
mostrar el error cuando se produzca y cerrar las conexiones:
Private Sub Winsock1_Error( _
ByVal Number As Integer, Description As String, _
ByVal Scode As Long, ByVal Source As String, _
ByVal HelpFile As String, ByVal HelpContext As Long, _
CancelDisplay As Boolean)
'Si se produce un error cerramos la conexión
Winsock1.Close
'Mostramos el error
MsgBox "Error con WinSock: " & Number & ": " & _
Description, vbCritical
End Sub
Aplicación cliente para conexión por socket con Visual Basic 6
Para el caso de la aplicación cliente con VB6 y Winsock tendrá este aspecto:
Para realizar una conexión del equipo cliente con el
equipo servidor especificado en txtServidor y el puerto especifidaco en
txtPuerto agregaremos el siguiente código para el botón"btConectar":
Private Sub btConectar_Click() 'Asignamos la IP o hostname a Winsock Winsock1.RemoteHost = txtServidor.Text 'Asignamos el puerto a Winsock Winsock1.RemotePort = txtPuerto.Text 'Desconectamos por si acaso estaba conectado ya Winsock1.Close 'Realizamos la conexión mediante Socket al servidor y puerto Winsock1.Connect End Sub
Si la conexión se ha establecido con el equipo servidor de socket, se ejecutará el evento "Connect" de Winsock, en dicho evento podremos añadir el siguiente código:
Private Sub Winsock1_Connect()
'desplegamos un mensaje en la ventana
txtLog.Text = txtLog.Text & _
"Conexión establecida con servidor " & _
txtServidor.Text & ":" & txtPuerto.Text & vbCrLf
End Sub
Otro evento que programaremos, cuando se pierde la conexión del cliente con el servidor, será el "Close" de Winsock, por ejemplo podremos añadir el siguiente código a este evento:
Private Sub Winsock1_Close()
txtLog.Text = txtLog.Text & _
"Desconectado de servidor" & vbCrLf
End Sub
En el botón "btDesconectar" colocaremos el siguiente código, con este botón el usuario podrá desconectarse del servidor cuando lo estime pertinente:
Private Sub btDesconectar_Click() 'Cerramos la conexión con el servidor Winsock1.Close End Sub
El botón para enviar un mensaje de texto al servidor "btEnviarMensaje" tendrá el siguiente código:
Private Sub btEnviar_Click() 'Enviar txtMensaje a servidor Winsock1.SendData txtMensaje.Text & vbCrLf End Sub
Si el servidor nos envía algún mensaje, lo podremos mostrar programando el evento DataArrival del componente Winsock, con el siguiente código VB6:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim datosRecibidos As String
'Se obtienen los datos enviados por el servidor
Winsock1.GetData datosRecibidos
txtMensajesServidor = txtMensajesServidor.Text & _
"Servidor: " & datosRecibidos
End Sub
Si se produce algún error podemos "controlarlo" con
el evento "Error" del componente "WinSock", por ejemplo podríamos
mostrar el error cuando se produzca y cerrar las conexiones:
Private Sub Winsock1_Error( _
ByVal Number As Integer, Description As String, _
ByVal Scode As Long, ByVal Source As String,
ByVal HelpFile As String, ByVal HelpContext As Long, _
CancelDisplay As Boolean)
'Si se produce un error cerramos la conexión
Winsock1.Close
'Mostramos el error
MsgBox "Error con WinSock: " & Number & ": " & _
Description, vbCritical
End Sub
Con los ejemplos anteriores mostramos cómo se
programaba con Visual Basic 6 y anteriores una aplicación
cliente-servidor mediante conexión por Socket. Como se puede observar
este ejemplo, con algunos retoques, puede servir para desarrollar una
aplicación de Chat. Por supuesto este tipo de conexiones entre
aplicaciones, que puede ser usada en una red LAN
o incluso a través de internet abriendo los puertos correspondientes en
los routers o cortafuegos, permite ser usada para múltiples propósitos
como por ejemplo controlar una aplicación desde otra, incluso controlar
un PC desde otro.
Tal y como lo hemos programado sólo se aceptará una
conexión por cada servidor, para permitir múltiples conexiones habría
que usar una matriz de componentes Winsock e ir creando uno nuevo por
cada conexión que se establezca. No entraremos más en detalle sobre
socket con VB6 por estar este lenguaje de programación obsoleto. A
continuación pasaremos a explicar los socket con VB.Net.
Conexión por socket en Visual Basic .Net de Visual Studio 2010
A partir de Microsoft Visual Studio .Net, Microsoft incorporó un Namespace para trabajar con Socket: System.Net.Sockets,
será este Namespace el que usemos para realizar una aplicación de
ejemplo que utilice Socket para conectar dos PCs a través de Internet o
de la red LAN y enviar mensajes de texto (o incluso enviar ficheros) entre uno y otro.
Sin duda el namespace System.Net.Sockets es
mucho más "potente" que el antiguo Winsock, proporciona más funciones,
propiedades, eventos y métodos y más eficientes. Aunque echamos de menos
que todo esto no esté implementando en un componente, lo cual
facilitaría bastante las cosas, como ocurre con la antigua versión de
Borland Delphi 6, que incluía un componente para Socket con todas las
opciones para una sencilla programación. Por ejemplo la aplicación de AjpdSoft Chat, bastante profesional, ha sido desarrollada con Delphi 6 y estos componentes (ClientSocket y ServerSocket):
También AjpdSoft Aviso cambio IP pública usa socket para conexión entre el usuario y el servidor donde se guardan las IPs. O la aplicación AjpdSoft Transferencia de ficheros que envía ficheros entre PCs mediante socket.
Volviendo a Microsoft Visual Studio .Net,
utilizaremos Visual Basic .Net VB.Net para conectar dos equipos
mediante Socket. A continuación explicaremos cómo desarrollar la
aplicación servidor y la aplicación cliente. Veremos que es un poco
"arduo" debido a que no incorpora un componente para este menester.
Aplicación servidor para conexión por socket con Visual Basic .Net
En la aplicación servidor agregaremos los siguientes componentes:
Agregaremos una clase a nuestro proyecto
AjpdSoftSocketServidor, en esta clase que llamaremos
"ClaseServidorSocket" agregaremos el código necesario para interactuar
con el Namespace System.Net.Sockets:
Imports System.Threading
Imports System.Net.Sockets
Imports System.Text
Public Class ClaseServidorSocket
'Esta estructura permite guardar la información sobre un cliente
Private Structure datosClienteConectado
Public socketConexion As Socket 'Socket para mantener la conexión con cliente
Public Thread As Thread 'Hilo para mantener escucha con el cliente
Public UltimosDatosRecibidos As String 'Últimos datos enviados por el cliente
End Structure
Private tcpLsn As TcpListener 'Para realizar la escuchas de conexiones de clientes
Private Clientes As New Hashtable() 'Datos de los clientes conectados
Private tcpThd As Thread
Private IDClienteActual As Net.IPEndPoint 'Último cliente conectado
Private m_PuertoDeEscucha As String
Public Event NuevaConexion(ByVal IDTerminal As Net.IPEndPoint)
Public Event DatosRecibidos(ByVal IDTerminal As Net.IPEndPoint)
Public Event ConexionTerminada(ByVal IDTerminal As Net.IPEndPoint)
'Propiedad para establecer el puerto por el que se realizará la escucha
Property Puerto() As Integer
Get
Puerto = m_PuertoDeEscucha
End Get
Set(ByVal Value As Integer)
m_PuertoDeEscucha = Value
End Set
End Property
'Procedimiento para establecer el servidor en modo escucha
Public Sub IniciarEscucha()
tcpLsn = New TcpListener(Puerto)
'Iniciar escucha
tcpLsn.Start()
'Crear hilo para dejar escuchando la conexión de clientes
tcpThd = New Thread(AddressOf EsperarConexionCliente)
tcpThd.Start()
End Sub
'Procedimiento para detener la escucha del servidor
Public Sub DetenerEscucha()
CerrarTodosClientes()
tcpThd.Abort()
tcpLsn.Stop()
End Sub
Public Function ObtenerDatos(ByVal IDCliente As Net.IPEndPoint) As String
Dim InfoClienteSolicitado As datosClienteConectado
'Obtengo la informacion del cliente solicitado
InfoClienteSolicitado = Clientes(IDCliente)
ObtenerDatos = InfoClienteSolicitado.UltimosDatosRecibidos
End Function
'Cierra la conexión de un cliente conectado
Public Sub cerrarConexionCliente(ByVal IDCliente As Net.IPEndPoint)
Dim InfoClienteActual As datosClienteConectado
'Obtener información del cliente indicado
InfoClienteActual = Clientes(IDCliente)
'Cerrar conexión con cliente
InfoClienteActual.socketConexion.Close()
End Sub
'Cerrar todas la conexión de todos los clientes conectados
Public Sub CerrarTodosClientes()
Dim InfoClienteActual As datosClienteConectado
'Cerrar conexión de todos los clientes
For Each InfoClienteActual In Clientes.Values
Call cerrarConexionCliente(InfoClienteActual.socketConexion.RemoteEndPoint)
Next
End Sub
'Enviar mensaje a cliente indicado
Public Sub enviarMensajeCliente(ByVal IDCliente As Net.IPEndPoint, _
ByVal Datos As String)
Dim Cliente As datosClienteConectado
'Obtener información del cliente al que se enviará el mensaje
Cliente = Clientes(IDCliente)
'Enviar mensaje a cliente
Cliente.socketConexion.Send(Encoding.ASCII.GetBytes(Datos))
End Sub
'Enviar mensaje a todos los clientes conectados al servidor
Public Sub enviarMensajeTodosClientes(ByVal Datos As String)
Dim Cliente As datosClienteConectado
For Each Cliente In Clientes.Values
enviarMensajeCliente(Cliente.socketConexion.RemoteEndPoint, Datos)
Next
End Sub
'Procedimiento que inicia la espera de la conexión de un cliente
'para ello inicia un hilo (thread)
Private Sub EsperarConexionCliente()
Dim datosClienteActual As datosClienteConectado
While True
'Se guarda la información del cliente cuando se recibe la conexión
'Quedará esperando la conexión de un nuevo cliente
datosClienteActual.socketConexion = tcpLsn.AcceptSocket()
'Con el IDClienteActual se identificará al cliente conectado
IDClienteActual = datosClienteActual.socketConexion.RemoteEndPoint
'Crear un hilo para que quede escuchando los mensajes del cliente
datosClienteActual.Thread = New Thread(AddressOf LeerSocket)
'Agregar la información del cliente conectado al array
SyncLock Me
Clientes.Add(IDClienteActual, datosClienteActual)
End SyncLock
'Generar evento NuevaConexion
RaiseEvent NuevaConexion(IDClienteActual)
'Iniciar el hilo que escuchará los mensajes del cliente
datosClienteActual.Thread.Start()
End While
End Sub
'Procedimiento para leer datos enviados por el cliente
Private Sub LeerSocket()
Dim IDReal As Net.IPEndPoint 'ID del cliente que se va a escuchar
Dim Recibir() As Byte 'Array donde se guardarán los datos que lleguen
Dim InfoClienteActual As datosClienteConectado 'Datos del cliente conectado
Dim Ret As Integer = 0
IDReal = IDClienteActual
InfoClienteActual = Clientes(IDReal)
While True
If InfoClienteActual.socketConexion.Connected Then
Recibir = New Byte(100) {}
Try
'Esperar a que lleguen un mensaje desde el cliente
Ret = InfoClienteActual.socketConexion.Receive(Recibir,
Recibir.Length, SocketFlags.None)
If Ret > 0 Then
'Guardar mensaje recibido
InfoClienteActual.UltimosDatosRecibidos =
Encoding.ASCII.GetString(Recibir)
Clientes(IDReal) = InfoClienteActual
'Generar el evento DatosRecibidos
'para los datos recibidos
RaiseEvent DatosRecibidos(IDReal)
Else
'Generar el evento ConexionTerminada
'de finalización de la conexión
RaiseEvent ConexionTerminada(IDReal)
Exit While
End If
Catch e As Exception
If Not InfoClienteActual.socketConexion.Connected Then
'Generar el evento ConexionTerminada
'de finalización de la conexión
RaiseEvent ConexionTerminada(IDReal)
Exit While
End If
End Try
End If
End While
Call CerrarThread(IDReal)
End Sub
'Procedimiento para cerrar el hilo (thread)
Private Sub CerrarThread(ByVal IDCliente As Net.IPEndPoint)
Dim InfoClienteActual As datosClienteConectado
'Finalizar el hilo (thread) iniciado
' encargado de escuchar al cliente
InfoClienteActual = Clientes(IDCliente)
Try
InfoClienteActual.Thread.Abort()
Catch e As Exception
SyncLock Me
'Eliminar el cliente del array
Clientes.Remove(IDCliente)
End SyncLock
End Try
End Sub
End Class
A continuación mostramos el código completo para el
formulario de la aplicación AjpdSoft Socket VB.Net Servidor, en el
código incluimos los eventos necesarios, el botón "Escuchar", el botón
"Detener escucha" y el botón "Enviar datos":
Public Class formSocketServidor
Dim WithEvents socketServidor As New ClaseServidorSocket()
'Iniciar el servidor, establecer el modo escucha
'para recibir conexión de clientes
Private Sub btEscuchar_Click(sender As System.Object,
e As System.EventArgs) Handles btEscuchar.Click
If txtPuerto.Text <> "" Then
Try
socketServidor.Puerto = txtPuerto.Text
socketServidor.IniciarEscucha()
btEscuchar.Enabled = False
txtPuerto.Enabled = False
txtMensaje.Enabled = True
btEnviarMensaje.Enabled = True
btDetenerEscucha.Enabled = True
txtMensaje.Focus()
Catch err As Exception
MsgBox("Se ha producido un error al intentar " & _
"establecer escucha por el puerto " & _
txtPuerto.Text & vbCrLf & vbCrLf & err.Message,
MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
End Try
Else
MsgBox("Debe indicar el puerto por el que establecer la escucha.",
MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
txtPuerto.Focus()
End If
End Sub
'Evento que se ejecutará cuando un nuevo cliente se conecte
Private Sub socketServidor_NuevaConexion(ByVal IDTerminal As _
System.Net.IPEndPoint) Handles socketServidor.NuevaConexion
txtLog.Text = txtLog.Text & vbCrLf & "Conectado cliente: " &
IDTerminal.Address.ToString & ", Puerto: " & IDTerminal.Port
End Sub
'Evento que se ejecutará cuando finalice la conexión de un cliente
Private Sub socketServidor_ConexionTerminada(ByVal IDTerminal As _
System.Net.IPEndPoint) Handles socketServidor.ConexionTerminada
txtLog.Text = txtLog.Text & vbCrLf & "Desconectado cliente: " &
IDTerminal.Address.ToString & ", Puerto: " & IDTerminal.Port
btEscuchar.Enabled = True
txtPuerto.Enabled = True
End Sub
'Evento que se ejecutará cuando se reciban datos de los clientes conectados
Private Sub socketServidor_DatosRecibidos(ByVal IDTerminal As _
System.Net.IPEndPoint) Handles socketServidor.DatosRecibidos
'Datos del cliente que se conecta
txtLog.Text = txtLog.Text & vbCrLf &
"Cliente: " & IDTerminal.Address.ToString &
", Puerto: " & IDTerminal.Port
'Mensaje recibido del cliente
txtMensajeRecibido.Text = IDTerminal.Address.ToString & " " & Now & " " &
txtMensajeRecibido.Text & " " & socketServidor.ObtenerDatos(IDTerminal)
End Sub
'Enviar mensaje a todos los clientes conectados
Private Sub btEnviarMensaje_Click(sender As System.Object,
e As System.EventArgs) Handles btEnviarMensaje.Click
socketServidor.enviarMensajeTodosClientes(txtMensaje.Text)
End Sub
'Detener modo escucha, no se recibirán conexiones de clientes
Private Sub btDetenerEscucha_Click(sender As System.Object,
e As System.EventArgs) Handles btDetenerEscucha.Click
btEscuchar.Enabled = True
txtPuerto.Enabled = True
txtMensaje.Enabled = False
btEnviarMensaje.Enabled = False
btDetenerEscucha.Enabled = False
Try
socketServidor.DetenerEscucha()
Catch err As Exception
MsgBox("Error al detener la escucha:" + vbCrLf +
vbCrLf + err.Message,
MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
End Try
End Sub
'Finalizamos con End para cerrar el hilo (thread) abierto
Private Sub formSocketServidor_FormClosed(sender As System.Object,
e As System.Windows.Forms.FormClosedEventArgs) _
Handles MyBase.FormClosed
End
End Sub
End Class
Aplicación cliente para conexión por socket con Visual Basic .Net
En la aplicación cliente agregaremos los siguientes componentes:
Agregaremos una clase a nuestro proyecto
AjpdSoftSocketCliente, en esta clase que llamaremos "ClaseClienteSocket"
agregaremos el código necesario para interactuar con el Namespace
System.Net.Sockets:
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.IO
Public Class ClaseClienteSocket
Private mensajesEnviarRecibir As Stream 'Para enviar y recibir datos del servidor
Private ipServidor As String 'Dirección IP
Private puertoServidor As String 'Puerto de escucha
Private clienteTCP As TcpClient
Private hiloMensajeServidor As Thread 'Escuchar mensajes enviados desde el servidor
Public Event ConexionTerminada()
Public Event DatosRecibidos(ByVal datos As String)
'Dirección IP del servidor al que nos conectaremos
Public Property IP() As String
Get
IP = ipServidor
End Get
Set(ByVal Value As String)
ipServidor = Value
End Set
End Property
'Puerto por el que realizar la conexión al servidor
Public Property Puerto() As Integer
Get
Puerto = puertoServidor
End Get
Set(ByVal Value As Integer)
puertoServidor = Value
End Set
End Property
'Procedimiento para realizar la conexión con el servidor
Public Sub Conectar()
clienteTCP = New TcpClient()
'Conectar con el servidor
clienteTCP.Connect(IP, Puerto)
mensajesEnviarRecibir = clienteTCP.GetStream()
'Crear hilo para establecer escucha de posibles mensajes
'enviados por el servidor al cliente
hiloMensajeServidor = New Thread(AddressOf LeerSocket)
hiloMensajeServidor.Start()
End Sub
'Procedimiento para cerrar la conexión con el servidor
Public Sub Desconectar()
'desconectamos del servidor
clienteTCP.Close()
'abortamos el hilo (thread)
hiloMensajeServidor.Abort()
End Sub
'Enviar mensaje al servidor
Public Sub EnviarDatos(ByVal Datos As String)
Dim BufferDeEscritura() As Byte
BufferDeEscritura = Encoding.ASCII.GetBytes(Datos)
If Not (mensajesEnviarRecibir Is Nothing) Then
mensajesEnviarRecibir.Write(BufferDeEscritura,
0, BufferDeEscritura.Length)
End If
End Sub
Private Sub LeerSocket()
Dim BufferDeLectura() As Byte
While True
Try
BufferDeLectura = New Byte(100) {}
'Esperar a que llegue algún mensaje
mensajesEnviarRecibir.Read(BufferDeLectura,
0, BufferDeLectura.Length)
'Generar evento DatosRecibidos cuando se recibien datos desde el servidor
RaiseEvent DatosRecibidos(Encoding.ASCII.GetString(BufferDeLectura))
Catch e As Exception
Exit While
End Try
End While
'Finalizar conexión y generar evento ConexionTerminada
RaiseEvent ConexionTerminada()
End Sub
End Class
A continuación mostramos el código completo para el formulario de la
aplicación AjpdSoft Socket VB.Net Servidor, en el código incluimos los
eventos necesarios, el botón "Escuchar", el botón "Detener escucha" y el
botón "Enviar datos":
Public Class formSocketCliente
Dim WithEvents socketCliente As New ClaseClienteSocket
Private Sub btEnviar_Click(sender As System.Object,
e As System.EventArgs) Handles btEnviar.Click
Try
'Enviar mensaje al servidor
socketCliente.EnviarDatos(txtMensaje.Text)
Catch err As Exception
MsgBox("Error al enviar mensaje al servidor." &
vbCrLf & vbCrLf & err.Message)
End Try
End Sub
'Evento que se ejecuta cuando se reciben datos
Private Sub socketCliente_DatosRecibidos( _
ByVal datos As String) Handles socketCliente.DatosRecibidos
bePanel2.Text = "Recibidos datos del servidor"
txtMensajeRecibido.Text = Now + " Servidor: " & datos
End Sub
Private Sub socketCliente_ConexionTerminada() Handles _
socketCliente.ConexionTerminada
bePanel2.Text = "Conexión finalizada"
txtServidor.Enabled = True
txtPuerto.Enabled = True
btConectar.Enabled = True
btDesconectar.Enabled = False
btEnviar.Enabled = False
txtListaMensajes.Enabled = False
bePanel1.Text = "No conectado"
txtServidor.Focus()
End Sub
Private Sub btConectar_Click(sender As System.Object,
e As System.EventArgs) Handles btConectar.Click
'Conexión del cliente con el servidor (IP ó hostname y puerto)
If txtServidor.Text = "" Or txtPuerto.Text = "" Then
MsgBox("Debe indicar el servidor (IP o hostname) y " _
& "el puerto al que realizar la conexión.",
MsgBoxStyle.Information + MsgBoxStyle.OkOnly)
txtServidor.Focus()
Else
Try
socketCliente.IP = txtServidor.Text
socketCliente.Puerto = CInt(txtPuerto.Text)
socketCliente.Conectar()
txtServidor.Enabled = False
txtPuerto.Enabled = False
btConectar.Enabled = False
btEnviar.Enabled = True
txtMensaje.Enabled = True
btDesconectar.Enabled = True
bePanel1.Text = "Conectado"
bePanel1.Text = "Conexión establecida a " & _
txtServidor.Text & ":" & txtPuerto.Text
Catch err As Exception
bePanel1.Text = "No conectado"
MsgBox("Error al conectar al servidor " & txtServidor.Text &
vbCrLf & vbCrLf & err.Message,
MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
End Try
End If
End Sub
Private Sub formSocketCliente_FormClosed(sender As System.Object,
e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
End
End Sub
Private Sub btDesconectar_Click(sender As System.Object, _
e As System.EventArgs) Handles btDesconectar.Click
txtServidor.Enabled = True
txtPuerto.Enabled = True
btConectar.Enabled = True
btEnviar.Enabled = False
txtMensaje.Enabled = False
btDesconectar.Enabled = False
Try
socketCliente.Desconectar()
Catch err As Exception
MsgBox("Error al desconectar del servidor " & txtServidor.Text &
vbCrLf & vbCrLf & err.Message,
MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
End Try
End Sub
End Class
AjpdSoft Socket VB.Net en funcionamiento
A continuación mostramos cómo funciona la aplicación a AjpdSoft Socket VB.Net,
por un lado iniciaremos la parte Servidor, introduciremos el puerto a
usar para las conexiones (debe estar libre), en nuestro caso usaremos el
1010 y pulsaremos "Escuchar":
La aplicación Servidor quedará en modo escucha,
esperando la conexión de los clientes, si el puerto está usado ya por
otra aplicación mostrará un error, si el puerto está libre activará el
botón "Enviar a todos":
Iniciaremos la aplicación Cliente, en esta aplicación
deberemos indicar la IP o nombre de red (hostname) del equipo que tiene
la aplicación Servidor, incluso podremos establecer la conexión a
través de Internet si hemos redireccionado correctamente el puerto usado
en el router o cortafuegos. En nuestro caso usaremos la IP 127.0.0.1
debido a que la aplicación Servidor y Cliente están en el mismo equipo.
Introduciremos el mismo puerto con el que hemos activado la escucha en
el Server, el 1010 y pulsaremos "Conectar":
Si todo es correcto y el Servidor recibe la conexión, la aplicación Servidor mostrará "Conectado cliente ...":
Para enviar un mensaje al Servidor lo escribiremos en "Mensaje" y pulsaremos "Enviar":
En el Servidor se habrá recibido el mensaje enviado
por el Cliente, si queremos enviar un mensaje del servidor a todos los
clientes conectados lo escribiremos y pulsaremos en "Enviar a todos":
Los clientes conectados recibirán el mensaje enviado desde el Servidor:
Artículos relacionados
- AjpdSoft Socket VB.Net.
- AjpdSoft Envío SMS.
- Definición Socket Enciclopedia AjpdSoft.
- Cómo enviar mensajes entre aplicaciones Delphi mediante el API de Windows.
- Enviar y recibir datos mediante el protocolo UDP con Borland Delphi 6.
- AjpdSoft Inventario PCs - Código fuente Delphi.
- Cómo conectar dos equipos en red por el puerto paralelo con Windows 98 y XP.
- Insertar evento de Google Calendar con Visual Basic .Net y Google Data API.
- Descarga gratuita código fuente VB.Net AjpdSoft Insertar Evento Google Calendar.
- Crear proceso en segundo plano con barra de progreso en Visual Basic .Net VB.Net.
- Instalar Visual Studio 2010 y desarrollar aplicación con acceso a PostgreSQL.
- El control de errores en Visual Basic .Net.
- Acceso a MySQL mediante Visual Basic .Net y ODBC.
- Acceso a Oracle mediante Microsoft Visual Basic, RDO y ODBC.
- Insertar y extraer documentos en una tabla Oracle con Visual Basic 6.
- Cambiar marcadores de Word por valores del formulario de una aplicación.
- Exportar ListView a fichero CSV VB.Net.
- Función para reemplazar una cadena de texto dentro de otra - Visual Basic.
- Funciones para leer y escribir en ficheros INI VB.Net.
- Enviar y recibir faxes desde un equipo con Windows XP y un módem.
- AjpdSoft Envío EMail SSL.
- AjpdSoft Conexión BD Visual Basic .Net.
- AjpdSoft Puerto Paralelo (código fuente en Delphi).
- Artículos, manuales y trucos del Proyecto AjpdSoft sobre Microsoft Visual Studio.
- Todos los programas con código fuente en Visual Basic.
- Foro del Proyecto AjpdSoft sobre Visual Basic, Visual Studio .Net, VB.Net.
- Realizar una conexión a Internet con la placa Arduino y un módulo GPRS GSM.
Créditos
Artículo realizado íntegramente por Alonsojpd miembro fundador del Proyecto AjpdSoft.
10/17/2011
Instalar AjpdSoft Control de Stock
Vídeo tutorial sobre cómo instalar la aplicación gratuita y open source AjpdSoft Control de Stock:
http://youtu.be/5N4YOo-9mFs
http://youtu.be/5N4YOo-9mFs
3/17/2011
Aviso importante para usuarios de AjpdSoft Aviso Cambio IP Pública
Si usas esta aplicación en modo "Si cambia la IP guardar en Base de datos" y usas nuestros servidores para ello (opción por defecto) la aplicación no funcionará. Hemos cambiado de servidor la web y la base de datos de la aplicación. Desde desarrollo estamos trabajando para liberar una nueva versión con algunas mejoras, sobre todo en cuanto a seguridad (encriptación de contraseñas, md5, etc.).
Debido a la gran cantidad de usuarios de la aplicación AjpdSoft Aviso Cambio IP Pública, el número de peticiones a la URL http://www.ajpdsoft.com/ip.php ha llegado a colapsar los servidores (más de 10 millones de peticiones al mes) por lo que nuestros técnicos están cambiando también la URL usada para obtener la IP pública en la nueva versión. En este enlace explicamos cómo funciona la aplicación.
Desde el Proyecto AjpdSoft pedimos perdón por las molestias ocasionadas. Teniendo en cuenta que se trata de un proyecto sin ánimo de lucro no nos podemos permitir el lujo de aumentar las capacidades de los servidores para dar soporte a la aplicación sin cambiar los parámetros de la misma.
De forma provisional la aplicación funcionará si seguís los pasos que indicamos aquí:
Así pues, en breve liberaremos una nueva versión que será de obligatoria actualización pues dejará de funcionar la actual completamente (quitaremos "ip.php" y no funcionará la obtención de la IP pública).
2/21/2011
Descarga gratuita (freeware) del código fuente (source code) 100% open source, desarrollado con Borland (ahora Codegear) Delphi 6 de la utilidad AjpdSoft Formulario inicio sesión aplicación Delphi: ejemplo de formulario para añadir la opción de inicio de sesión en nuestras aplicaciones. Incluye opción de acceso mediante usuario y contraseña guardados en base de datos MySQL y opción de validación contra servidor LDAP (Active Directory de Microsoft, OpenLDAP, ...).
Autor: AjpdSoft (bas [arroba] ajpdsoft.com)
Versión: 1.0.0
Tamaño del archivo: 268.00 Kb
MD5: B5421E21E8B4D484E3555439D6A90A12
Descargas: 1
[ Descargar este archivo ahora | Página de Inicio ]
2/20/2011
Desarrollamos un formulario de inicio de sesión con Borland (ahora Codegear) Delphi 6 (válido para otras versiones) y MySQL como motor de base de datos (válido para otros motores). Explicamos en este manual cómo hacer una ventana de validación de usuario usando algunos métodos de seguridad: guardando la contraseña del usuario en MD5 (hash), encriptando la contraseña de acceso a la base de datos, etc. Además, añadiremos la opción de obtener la IP del servidor de MySQL mediante AjpdSoft Aviso cambio IP pública. También mostramos cómo implementar la validación o inicio de sesión en un servidor LDAP (Microsoft Active Directory, dominio Windows u otros compatibles con LDAP).
- Diseño del formulario Delphi, componentes necesarios para validación de usuario.
- Tabla usuarios en la base de datos MySQL para validación de usuario en aplicación Delphi.
- Formulario de alta de usuario con cálculo de hash (md5) para guardar la contraseña.
- La seguridad para el inicio de sesión o validación de un usuario en nuestra aplicación con Delphi.
- Validar usuario en servidor LDAP con Delphi, implementar inicio de sesión login en LDAP con Delphi.
- Acceso a la tabla de parámetros mediante función Delphi y MySQL.
- Acceso nativo a MySQL Server con Delphi.
- Artículos relacionados.
- Créditos.
Diseño del formulario Delphi, componentes necesarios para validación de usuario
En primer lugar añadiremos un formulario a nuestro proyecto Delphi con los siguientes componentes:
- Puesto que nuestra aplicación permitirá validación de diferentes métodos, añadiremos varios TRadioButton para que el usuario pueda seleccionar el método de validación: aplicación, LDAP, Alfresco, etc. En este ejemplo implementaremos el método LDAP y el método aplicación.
- TEdit: para introducir el usuario y la contraseña.
- TButton: para botón "Iniciar", botón "Cancelar" y botón "Opciones".
- TabSheet: donde coloraremos los datos de acceso a la base de datos y los datos para obtener la dirección IP del servidor de base de datos.
Nota: la opción de "Dirección servidor BD IP" no es necesaria para un formulario de validación. Sirve para obtener la IP pública del servidor de bases de datos cuando ésta es dinámica. Si disponemos de IP estática o fija no será necesario. Esta opción enlaza con la base de datos de la aplicación AjpdSoft Aviso cambio IP pública que deberá estar iniciada en el servidor de MySQL para que obtenga la IP y la guarde en la base de datos.
En la siguiente descarga incluimos el código fuente complento de este formulario:
Tabla usuarios en la base de datos MySQL para validación de usuario en aplicación Delphi
Tabla de usuarios en MySQL para inicio de sesión, formulario de validación Delphi
Para el inicio de sesión en la aplicación desarrollada en Delphi usaremos una tabla donde guardaremos los datos de los usuarios. A continuación mostramos la consulta SQL de creación de esta tabla con todos los campos para MySQL:
CREATE TABLE usuario (
codigo int(10) unsigned NOT NULL AUTO_INCREMENT,
nick varchar(20) NOT NULL,
contrasena varchar(100),
codigocliente int(10) unsigned,
codigotecnico int(10) unsigned,
codusuarioa int(10) unsigned,
codusuariom int(10) unsigned,
fechaa datetime,
fecham datetime,
administrador char(1),
modificacion char(1),
nombre varchar(100),
fecha datetime,
accesoweb varchar(1),
codigodepartamento int(10) unsigned,
email varchar(200),
PRIMARY KEY (codigo),
UNIQUE KEY usuario_nick (nick)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
Por supuesto añadiremos todos los campos que necesitemos para los usuarios (DNI, Departamento, etc.), aunque los más importantes para la validación son nick (nombre de usuario) y contrasena (se guardará aquí el hash de la contraseña del usuario, NO la propia contraseña, por seguridad).
Para crear esta tabla en nuestro servidor de MySQL Server podremos usar cualquier aplicación que permita ejecutar sentencias SQL en MySQL Server, como por ejemplo la aplicación gratuita y con código fuente:
Por supuesto, también podremos usar MySQL Administrator o cualquier otro software para ejecutar consultas SQL en MySQL Server.
Tabla MySQL log inicio y cierre de sesión
En nuestro caso, aunque lógicamente no es necesario, usaremos también una tabla para guardar el inicio y cierre de sesión de cada usuario, para guardar un log de los accesos de los usuarios. Crearemos también la siguiente tabla:
CREATE TABLE sesion (
id int(11) NOT NULL AUTO_INCREMENT,
codigousuario int(11),
fecha date,
hora time,
estado varchar(20),
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
Como se puede observar, en la tabla "sesion" guardaremos el código del usuario que inicia la sesión, la fecha y la hora y el estado (si es inicio de sesión o es cierre de sesión). De esta forma quedará constancia de los accesos de cada usuario a la aplicación.
Tabla MySQL de parámetros de configuración de la aplicación
Crearemos una tercera tabla para guardar los parámetros de configuración de la aplicación:
CREATE TABLE parametro (
codigo int(10) unsigned NOT NULL AUTO_INCREMENT,
nombre varchar(50),
valor varchar(100),
PRIMARY KEY (codigo)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
En dicha tabla guardaremos, por ejemplo, la versión de la aplicación. De forma que si desarrollamos una nueva versión de la aplicación, a los usuarios le aparezca un mensaje de aviso indicando que existe una nueva versión de la aplicación, incluso si es una versión "crítica" podemos obligar a los usuarios a que realicen la actualización. Aquí se puede ver un ejemplo de uso de esta tabla.
Formulario de alta de usuario con cálculo de hash (md5) para guardar la contraseña
Para el formulario de alta de nuevo usuario en nuestra aplicación Delphi, añadiremos los componentes necesarios para los campos de fecha de alta, nick, nombre completo, mail, contraseña, etc. A continuación mostramos un formulario de alta de usuario de ejemplo:
El código fuente en Delphi de dicho formulario puede descargarse gratuitamente aquí.
A continuación explicaremos algunas de las opciones más importantes del formulario de alta de usuario:
1. Cuando el usuario o el administrador de la aplicación introduzca la contraseña en el formulario, en la base de datos guardaremos el hash correspondiente a esta contraseña, nunca la contraseña directamente. De esta forma, si se produce un hackeo de nuestra base de datos, si un usuario malintencionado obtiene acceso a nuestra base de datos, al acceder a la tabla de usuarios no verá la contraseña del usuario. Para obtener el hash de la contraseña (que será el valor que guardemos en la base de datos) usaremos el componente gratuito para Delphi: TurboPower LockBox 2.07. Una vez instalado este componente, usaremos la siguiente función para obtener el Hash de la contraseña del usuario:
function obtenerHash (texto : string) : string; var MD5Digest : TMD5Digest; hashMD5 : TLbMD5; begin hashMD5 := TLbMD5.Create(nil); hashMD5.HashString(texto); hashMD5.GetDigest(MD5Digest); result := BufferToHex(MD5Digest, SizeOf(MD5Digest)); end;
2. Al pulsar el botón "Aceptar", en el formulario de alta o modificación de usuario, comprobaremos si se ha cambiado la contraseña. Si el usuario ha cambiado la contraseña (una modificación) realizaremos la comprobación y guardaremos el hash en el componente enlazado con la base de datos, para guardarlo en la base de datos:
//si se ha cambiado la contraseña
if contrasenaActual <> txtContrasena1.Text then
txtContrasena1.Text := AnsiLowerCase(obtenerHash(txtContrasena1.Text));
La seguridad para el inicio de sesión o validación de un usuario en nuestra aplicación con Delphi
Para realizar un formluario seguro de inicio de sesión en nuestras aplicaciones con Delphi, usaremos los siguientes métodos de seguridad:
- En la tabla de usuario de MySQL no guardaremos directamente la contraseña, sino su hash (md5).
- Encriptar o cifrar la contraseña y usuario con los que accederemos a la base de datos MySQL, para ello usaremos el esquema de cifrado AES.
- Guardar log de inicio de sesión de cada usuario, para auditoría de accesos en caso necesario.
- Usar un usuario y contraseña de MySQL que sólo tenga permisos sobre las tablas de la aplicación, que no sea administrador de MySQL (no usar "root").
La función para encriptar la contraseña y el nombre de usuario de acceso a la base de datos MySQL:
//encriptar datos function encriptar (Str, Clave : String) : String; var Src: TStringStream; Dst: TMemoryStream; Size: Integer; Key: TAESKey; ExpandedKey: TAESExpandedKey; begin Result:= EmptyStr; Src:= TStringStream.Create(Str); try Dst:= TMemoryStream.Create; try // Preparamos la clave, lo ideal es que tenga 32 caracteres FillChar(Key,Sizeof(Key),#0); if Length(Clave) > Sizeof(Key) then move(PChar(Clave)^,Key,Sizeof(key)) else move(PChar(Clave)^,Key,Length(Clave)); AEsExpandKey(ExpandedKey,Key); // Guardamos el tamaño del texto original Size:= Src.Size; Dst.WriteBuffer(Size,Sizeof(Size)); // Ciframos el texto AESEncryptStreamECB(Src,Dst,ExpandedKey); // Lo codificamos a base64 Result:= BinToStr(Dst.Memory,Dst.Size); finally Dst.Free; end; finally Src.Free; end; end;
La función para desencriptar la contraseña y usuario:
//desencriptar datos function desencriptar (Str, Clave : String): String; var Src: TMemoryStream; Dst: TStringStream; Size: Integer; Key: TAESKey; ExpandedKey: TAESExpandedKey; begin Result:= EmptyStr; Src:= TMemoryStream.Create; try Dst:= TStringStream.Create(Str); try StrToStream(Str, Src); Src.Position:= 0; FillChar(Key,Sizeof(Key),#0); if Length(Clave) > Sizeof(Key) then move(PChar(Clave)^,Key,Sizeof(key)) else move(PChar(Clave)^,Key,Length(Clave)); AESExpandKey(ExpandedKey,Key); // Leemos el tamaño del texto try Src.ReadBuffer(Size,Sizeof(Size)); AESDecryptStreamECB(Src,Dst,ExpandedKey); Dst.Size:= Size; Result:= Dst.DataString; except Result := ''; end; finally Dst.Free; end; finally Src.Free; end; end;
En la cláusula "Uses" de la unidad donde coloquemos los procendimientos anteriores necesitaremos añadir:
unit UnidadProcedimientos; interface uses inifiles, sysutils, ShlObj, ActiveX, Windows, ShellCtrls, controls, classes, registry, db, dialogs, forms, variants, IdSMTP, IdMessage, dateutils, shellapi, mapi, LbClass, LbCipher, LbUtils, aes, base64, StrUtils;
Para guardar la contraseña en el fichero INI de configuración de la aplicación usaremos:
esCadINI('Base de datos', 'Tipo BD MySQL - Usuario',
trim(encriptar (txtBDUsuario.Text, claveEncriptacionTexto)));
esCadINI('Base de datos', 'Tipo BD MySQL - Contraseña',
trim(encriptar (txtBDContrasena.Text, claveEncriptacionTexto)));
El procedimiento "esCadINI":
//escribe un valor string en un fichero INI procedure esCadINI (clave, cadena : string; valor : String); begin with tinifile.create (changefileext(paramstr(0),'.INI')) do try WriteString (clave, cadena, valor); finally free; end; end;
El procedimiento "esCadINI" requerirá añadir en el Uses de la unidad inifiles:
unit UnidadProcedimientos; interface uses inifiles, sysutils, ShlObj, ActiveX, Windows, ShellCtrls, controls, classes, registry, db, dialogs, forms, variants, IdSMTP, IdMessage, dateutils, shellapi, mapi, LbClass, LbCipher, LbUtils, aes, base64, StrUtils;
También necesitaremos declarar la constante claveEncriptacionTexto con el valor de la clave de encriptación, necesaria para encriptar y desencriptar, es recomendable que sea una clave con números, letras, mayúsculas, minúsculas y algún carácter especial:
Y, lógicamente, necesitaremos los ficheros AES.pas y base64.pas que se incluyen en la descarga:
//para encriptación de contraseñas en AES claveEncriptacionTexto = 'AnJtP1DdSñO2FwT8'; implementation
Validar usuario en servidor LDAP con Delphi, implementar inicio de sesión login en LDAP con Delphi
Para permitir la validación en un servidor con el protocolo LDAP (dominio de Microsoft Windows con Active Directory, OpenLDAP, etc.) añadiremos los siguientes ficheros a nuestro proyecto Delphi: Cert.pas, Constant.pas, Events.pas, Gss.pas, LDAPClasses.pas, Misc.pas. Todos estos ficheros se incluyen en la descarga:
Por supuesto, en la descarga anterior también incluimos el formulario de inicio de sesión con el código fuente necesario para validar o autenticar un usuario en un servidor LDAP.
El código que usamos en el formulario de inicio de sesión para la autenticación, validación o login de un usuario en LDAP con Delphi:
if opValLDAP.Checked then
begin
if ((txtValLDAPServidor.Text = '') or (txtValLDAPDominio.Text = '')) then
begin
continuar := false;
MessageDlg('Para la validación con LDAP debe indicar el servidor y el dominio.',
mtWarning, [mbok], 0);
tabLDAP.Show;
end
else
begin
if autenticarLDAP (txtUsuario.Text, txtContrasena.Text,
txtValLDAPServidor.Text, txtValLDAPDominio.Text) then
begin
continuar := True;
end
else
begin
continuar := false;
MessageDlg('Error de validación LDAP, compruebe que existe el usuario [' +
txtUsuario.Text + '] en el servidor LDAP: [' +
txtValLDAPServidor.Text + '] del dominio [' +
txtValLDAPDominio.Text + '] o que la contraseña es correcta.',
mtWarning, [mbok], 0);
end;
end;
end;
La función "autenticarLDAP" la podremos encontrar en el fichero "UnidadProcedimientos.pas", es la siguiente:
function autenticarLDAP (usuario : string; contrasena : string; servidor : string; dominio : string) : boolean; var e : array[0..0] of string; //i : integer; begin LDAPSession := TLDAPSession.Create; LDAPEntryList := TLDAPEntryList.create; LDAPSession.Server := servidor; LDAPSession.Base := 'dc=' + servidor + ',dc=' + dominio + ',dc=com'; LDAPSESSION.PagedSearch := TRUE; LDAPSEssion.PageSize := 100; LDAPSession.SSL := false; LDAPSession.DereferenceAliases := 0; LDAPSession.Version := 3; LDAPSEssion.AuthMethod := 0; LDAPSession.User := usuario; LDAPSession.Password := contrasena; LdapSession.ChaseReferrals := true; ldapsession.ReferralHops := 32; LDAPSession.Connect; e[0] := 'cn'; if ldapsession.Connected then Result := true else Result := false; end;
Para validar o autenticar un usuario en un servidor con el protocolo LDAP hemos usado la siguiente aplicación de ejemplo del AjpdSoft Validación LDAP y el siguiente paquete de unidades para acceso a LDAP: ADSI (Active Directory Service Interfaces).
Acceso a la tabla de parámetros mediante función Delphi y MySQL
El acceso a la tabla de parámetros de la aplicación, donde guardaremos los valores de configuración, se realizará con una función como la siguiente, donde leeremos el valor del parámetro que necesitemos en cada momento:
procedure obtenerValorParametro (nombre : string; var valor1 : string; var valor2 : string); begin md.tc.Close; md.tc.SQL.Clear; md.tc.SQL.Add('SELECT valor, valor2'); md.tc.SQL.Add('FROM ' + vtTablaParametro); md.tc.SQL.Add('WHERE nombre = :pNombre'); md.tc.ParamByName('pNombre').DataType := ftinteger; md.tc.ParamByName('pNombre').AsString := nombre; md.tc.Open; valor1 := md.tc.FieldByName('valor').AsString; valor2 := md.tc.FieldByName('valor2').AsString; md.tc.Close; end;
Por ejemplo, para obtener la versión de la aplicación y si es distinta no iniciarla, utilizaremos el siguiente código:
//comprobamos la versión de la aplicación
obtenerValorParametro('version', valorParametro1, valorParametro2);
versionBD := valorParametro1;
accesoSiDistinta := valorParametro2;
if (versionBD <> vtVersionAplicacion) then
begin
MessageDlg('La versión actual de su aplicación [' +
vtVersionAplicacion + '] es diferente a la de la BD [' +
versionBD + ']. ' +
chr(13) + chr(13) + 'Le recomendamos que actualice ' +
'su versión de software para evitar incongruencias ' +
'en los datos.', mtInformation, [mbok], 0);
if accesoSiDistinta = 'N' then
Application.Terminate;
end;
De esta forma podremos acceder a cualquier parámetro de la aplicación y éste quedará guardado en la base de datos, por lo que serán parámetros compartidos para todos los usuarios de la aplicación.
Acceso nativo a MySQL Server con Delphi
Para el acceso al servidor de bases de datos MySQL Server con el lenguaje de programación Borland (ahora Codegear) Delphi 6 hemos usado el componente gratuito Zeosdbo 6.5.1. En el siguiente enlace explicamos cómo instalarlo en Delphi 6:
Este componente tiene la ventaja de que accede de forma nativa (sin usar intermediarios como ODBC) al servidor de MySQL Server indicado. Es bastante sencillo de programar, es suficiente con añadir un componente de tipo ZConnection:
Estableceremos las propiedades del componente ZConnection por código, obteniendo los datos del servidor de MySQL Server al que nos conectaremos desde el formulario de login:
if continuar then begin md.bd.Disconnect; md.bd.Database := txtBDBD.Text; md.bd.User := txtBDUsuario.Text; md.bd.Password := txtBDContrasena.Text; md.bd.HostName := txtBDServidor.Text; md.bd.Port := strtoint(txtBDPuerto.Text); md.bd.Protocol := txtBDProtocolo.Text; try md.bd.Connect; ......
Añadiremos el resto de componentes Zeosdbo, todos ellos enlazados con el ZConnection anterior mediante la propiedad Connection. Por ejemplo, para ejecutar consultas SQL en nuestro MySQL Server y obtener el resultado usaremos un ZQuery:
Un ejemplo de uso del ZQuery:
vtUsuario := txtBDUsuario.Text;
md.tc.Close;
md.tc.SQL.Clear;
md.tc.SQL.Add('SELECT codigo, contrasena, nombre, modificacion, ');
md.tc.SQL.Add(' administrador, tipo');
md.tc.SQL.Add('FROM usuario');
md.tc.SQL.Add('WHERE upper(nick) = :pNick and activo = "S"');
md.tc.ParamByName('pNick').DataType := ftString;
md.tc.ParamByName('pNick').Value := ansiuppercase(txtUsuario.Text);
md.tc.Open;
if md.tc.RecordCount > 0 then
begin
vtcontrasenaUsuario := md.tc.FieldByName('contrasena').AsString;
if opValGISAM.Checked then
Podremos consultar y usar el código fuente completo del formulario de inicio de sesión realizando la descarga:
Artículos relacionados
- Encriptar y desencriptar ficheros con CAPICOM y Delphi.
- Cómo se hizo ''Aviso Cambio IP Pública'' mediante Delphi, php y MySQL.
- Uso de CAPICOM y Delphi para acceso a los certificados digitales.
- Cómo enviar mensajes entre aplicaciones Delphi mediante el API de Windows.
- Cómo firmar digitalmente una factura - facturación telemática mediante Delphi.
- Metodología para resolver problemas de ingeniería con Delphi, interpolación.
- Enviar y recibir datos mediante el protocolo UDP con Borland Delphi 6.
- Configurar Linux para que valide en un dominio Microsoft Active Directory.
- Promocionar un equipo con Windows Server 2003 a controlador de dominio.
- Instalar y configurar servicio de Terminal Server en Windows 2003.
- Artículos, manuales y trucos del Proyecto AjpdSoft sobre MySQL.
- Artículos, manuales y trucos del Proyecto AjpdSoft sobre el lenguaje de programación Delphi.
- AjpdSoft Hash - Código Fuente en Delphi.
- AjpdSoft Obtener datos certificados digitales.
- AjpdSoft Encriptar Desencriptar ficheros.
- AjpdSoft Cifrar Texto.
- AjpdSoft Conectar unidad de red Código fuente Delphi.
- AjpdSoft Ping ICMP.
- AjpdSoft Verificar existencia email.
- AjpdSoft Escaneador de puertos.
- AjpdSoft Leer metadatos PNG.
- AjpdSoft Conversor Hexadecimal, Decimal, Texto.
- AjpdSoft Comparar Ficheros bit a bit.
Créditos
Suscribirse a:
Entradas (Atom)













