07 mayo 2010

La librería Synapse (y 5)

Vamos a terminar de ver las propiedades de esta librería, fijándonos en otras funciones que incorpora que pueden facilitarnos la vida a la hora de crear nuestro software orientado a redes o Internet.

COMPROBAR SI UNA DIRECCIÓN DE CORREO ES VÁLIDA

Debemos añadir la unidad mailchck en el formulario donde vamos a realizar la comprobación y llamamos a esta función:

function mailcheck(email: string): integer;

Y estos son los valores que devuelve:

0 - La dirección existe
1 - La dirección puede existir
2 - Tus direcciones DNS no son válidas
3 - Tus direcciones DNS no están definidas
4 - No puede conectar con los servidores MX
5 - El dominio no tiene registro MX
6 - La dirección no existe
7 - La dirección es incorrecta

ESCANEAR DIRECCIONES IP

Vamos a crear un pequeño programa que recorra un rango de direcciones IP y nos diga si existen o no. Es como si hiciésemos un Ping a cada dirección. Para ello creamos un nuevo proyecto con este formulario:

Para introducir la dirección inicial y final he añadido dos componentes TEdit llamados DirIni y DirFin, de modo que cada vez que encuentre una IP activa lo guarde en un componente TListBox llamado Lista.

Para no reinventar la rueda, vamos a copiar las unidades IPUtils.pas y IPThread.pas de la carpeta:

\CodeGear\RAD Studio\5.0\Componentes\Synapse\source\demo\scan

a la carpeta donde tenemos este proyecto y las vinculamos a nuestro formulario:

uses
..., IPUtils, PingThread;

Y este sería el código para recorrer todas las direcciones:

procedure TFEscanear.BEscanearClick(Sender: TObject);
var
i, j: Cardinal;
Ping: Array of TPingResult;
ContadorPing, DirInicial, DirFinal: Cardinal;
Puffer: String;
Hilos: Array of TPingThread;
bHilosCompletados: Boolean;
begin
// Pasamos las direcciones IP de texto a entero
DirInicial := IPToCardinal(StrToIP(DirIni.Text));
DirFinal := IPToCardinal(StrToIP(DirFin.Text));

// Contamos el nº de direcciones a escanear
ContadorPing := (DirFinal - DirInicial) + 1;

// Mostramos el nº de direcciones a escanear
Lista.Items.Add('Escaneando ' + IntToStr(ContadorPing) + ' direcciones...');
Application.ProcessMessages;

// Inicializamos el array dinámico
SetLength(Ping, ContadorPing);
SetLength(Hilos, ContadorPing);

// Recorremos las direcciones y las metemos en el array
j := 0;
for i := DirInicial to DirFinal do
begin
Ping[j].IPAdress := IPToStr(CardinalToIP(i));
Ping[j].Exists := False;
Inc(j);
end;

// Creamos un hilo para cada Ping
for i := 0 to ContadorPing - 1 do
Hilos[i] := TPingThread.Create(Ping[i]);

Lista.Items.Add(' ');

// Esperamos a que los hilos sean ejecutados
repeat
bHilosCompletados := True;
Sleep(1000);
for i := 0 to ContadorPing - 1 do
begin
if not Hilos[i].Ready then
begin
bHilosCompletados := False;
Break;
end;
end;
until bHilosCompletados;

// Volcamos los resultados a la lista
for i := 0 to ContadorPing - 1 do
begin
if Hilos[i].PingResult.Exists then
begin
Puffer := IntToStr(i + 1) + ' ' + Hilos[i].PingResult.IPAdress;
Lista.Items.Add(Puffer);
end;
end;

// Liberamos los hilos de ejecución
for i := 0 to ContadorPing - 1 do
Hilos[i].Free;
end;

Lo que hace es lanzar un hilo de ejecución por cada dirección y cuando terminen todos los muestra por pantalla. Ejecutamos el programa, pulsamos el botón Escanear y esperamos a que termine:

Si en algo destaca esta librería es en su rapidez, ya que se ventila las 250 direcciones en cuestión de segundos.

SINCRONIZAR LA HORA DE VARIOS ORDENADORES

El protocolo NTP (Network Time Procotol) se creó para sincronizar los relojes de cada PC a través de redes, algo ideal para sistemas con bases de datos distribuidas.

Vamos a crear un pequeño programa que lea la hora de un servidor SNTP o NTP:

Contiene un campo TEdit llamado URL donde metemos la dirección del servidor y una etiqueta llamada EMensaje donde volcamos la hora leída o un mensaje de error. Al pulsar el botón Leer hora ejecutamos este código:

procedure TFClienteSNTP.BLeerClick(Sender: TObject);
var
SNTP: TSntpSend;
begin
SNTP := TSntpSend.Create;
try
SNTP.TargetHost := URL.Text;

if SNTP.GetSNTP then
EMensaje.Caption :=
DatetimeToStr(SNTP.NTPTime) + ' UTC'
else
EMensaje.Caption := 'No conectado.';
finally
SNTP.Free;
end;
end;

Para poder utilizar la clase TSntpSend necesitamos añadir la unidad SNTPsend al formulario. Al ejecutar el programa, podemos probarlo con nosotros mismos ya que Windows incorpora un servidor SNTP:

La hora que devuelve es UTC, por lo que debemos incrementar más o menos horas según el país donde estemos. Lo ideal es utilizar un servidor público como este:

De este modo, todos los equipos de nuestra red estarán sincronizados incluso si se encuentran en distintas localizaciones. Aquí podéis encontrar servidores públicos:

http://www.pool.ntp.org/zone/europe


Como funciona sobre UDP, es muy rápido y puede ser de mucha utilidad para que comiencen a la vez las copias de seguridad de distintos centros o para realizar una comunicación directa por TCP a una cierta hora del día.

ENVIAR DATOS POR EL PUERTO SERIE

El ejemplo que trae Synapse sobre las comunicación por el puerto serie no funciona, ya que han cambiado los parámetros de la función Connect y los han desviado a la función Config. Para hacer una prueba hice este formulario:

Contiene los componentes TEdit llamados Puerto, Baudios y Comando que son los parámetros del puerto serie y los mensajes de salida irán a parar a un TMemo llamado Salida. Al pulsar el botón Enviar ejecutamos:

procedure TFPuetoSerie.BEnviarClick(Sender: TObject);
var
Serie: TBlockSerial;
begin
Serie := TBlockSerial.Create;
Serie.RaiseExcept := True;

try
Serie.Config(StrToIntDef(Baudios.Text, 9600), 8, 'N', 0, False, False);
Serie.Connect(Puerto.Text);
Salida.Lines.Text := Serie.ATCommand(Comando.Text);
finally
Serie.Free;
end;
end;

También debemos añadir la unidad SynaSer al mismo. Por más que lo he intentado siempre me salta esta excepción:

Y mira que he probado a enviarlo por COM1 o COM2, incluso me he instalado el emulador de puertos COM llamado com0com que tiene esta pantalla de configuración:

Este emulador se instala perfectamente en Windows simulando todos los puertos que queramos, pero yo con estos temas ya estoy algo obsoleto, ya que desde que pasamos a la ADSL y el resto de dispositivos van por USB (impresoras de tickets, autómatas, etc.), mi experiencia actualmente con el puerto serie es nula. Si alguien tiene ganas de investigar el asunto y tiene MODEM que pruebe a ver que tal.

CONCLUSIONES

A parte de todo lo que hemos visto, esta librería incorpora otros ejemplos como un servidor de ECHO o rutinas para codificar en MIME, algo utilizado para enviar datos por correo a pelo, pero creo que en ese sentido los componentes Indy le superan.

Por lo demás, solo queda decir que aunque no es una librería demasiado extensa, si funciona muy bien, es rápida y permite aprender como se programan algunos protocolos TCP/IP a bajo nivel, algo que puede gustarle a los programadores de troyanos y virus por su bajo consumo de recursos.

Pruebas realizadas en RAD Studio 2007.

Publicidad