Aplicación de subred local.

Soy de cuba y tengo problemas con una aplicación que intento desarrollar, visito este sitio porque la verdad que estoy lleno de dudas en como emprender el trabajo, la problemática planteada esl a siguiente:
? Construir una aplicación que permita seleccionar, de todas las máquinas disponibles en la subred local, cuáles de ellas poseen un determinado servicio.
? Si dicho servicio no se encuentra, la aplicación debe instalarlo remotamente a partir de las credenciales administrativas especificadas por el usuario. Si el servicio se encuentra detenido, la aplicación debe arrancarlo.
? Hecho esto, la aplicación comienza a enviarle tareas a cada una de las máquinas anteriores, las cuales las ejecutan y devuelven los resultados.
? La aplicación será capaz de mostrar los resultados obtenidos del procesamiento distribuido explicado en los pasos anteriores.
Todo consejo al respecto seria de ayuda...
Saludos nuevamente,
bezeech

1 Respuesta

Respuesta
1
Bueno mira, veo que es una buena aplicación y por supuesto algo extensa, pero mira delphi en sus ejemplos que trae, viene uno como de chat, quizá este ejemplo puedo servirte para empezar a darte una idea de como comunicarte con otro maquina, ahora te van hacer falta algunos tips no se si ya los sepas, como por ejemplo como saber si se esta ejecutando un programa y como ejecutarlo desde tu aplicación en dado caso de que no se este ejecutando!
Con esta función sabes si se esta ejecutando un programa en especifico
procedure TForm1.Button1Click(Sender: TObject);
function EstaEjecutandose (ExeFile:string): boolean;
var H:word;
begin
H := CreateFile(PChar(ExeFile), GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
Result := (H >= 65535);
CloseHandle(H);
end;
begin
If EstaEjecutandose ('c:\windows\notepad.exe')
then Label1.Caption:='SI/YES'
else Label1.Caption:='NO';
end;
Lógicamente si es de otra maquina pues le pasas la ruta de red.
Y con esta función ejecutas una aplicación:
WinExec(PChar('c:\windows\notepad.exe'),SW_SHOWNORMAL);
Bueno espero esto te vaya ayudando más en tu proyecto. Ya cuando tengas algo más especifico que hacer, y si necesitas ayuda házmelo saber ok.
Agradezco tu esfuerzo, ese ejepmlo lo encontré después de postear el problema, ahora lo que me interesa en si no es específicamente saber si es una aplicación lo que corre en la otra maquina, sino un SERVICIO (como el messenger, workstation, etc, etc), ademas otro de mis obstáculos en el desarrollo del código es como conseguir desde delphi una lista de las maquinas encendidas en un dominio (subredlocal), algo así como lo que hace el DAMEWARE. Se de la existencia del servicio de windows Computer Browser, que es el que permite navegar en una subred, pero tampoco se comunicarme con dicho servicio... Puedes hablar de forma técnica si te es más fácil, soy estudiante de cibernética y poseo cierto conocimientos avanzados de programación, claro, todavía no dispongo de la experiencia necesaria en Delphi, de ahí mis dudas...
Bueno a ver vamos por partes ok.
Mira para saber las maquinas que están conectadas aquí te envío este ejemplo a ver si te sirve. Ok y luego veme diciendo lo que vas necesitando pero cosa por cosa ok digamos que más directo...
# Añade una TListBox (ListBox1) en tu form
# Pon este código dentro del OnClick de un TButton:
procedure TForm1.Button1Click(Sender: TObject);
Function GetNetworkDriveMappings(SList:TStrings):Integer;
Var
I:Char;
ThePath:String;
MaxNetPathLen:DWord;
Begin
SList.Clear;
MaxNetPathLen:=MAX_PATH;
SetLength(ThePath,MAX_PATH);
For I := 'A' to 'Z' Do
if WNetGetConnection(PChar(''+I+':'),PChar(ThePath),
MaxNetPathLen)<>ERROR_NOT_CONNECTED then
SList.Add(I+': '+ThePath);
{Devuelve el numero de conexiones}
Result := SList.Count;
End;
begin
GetNetworkDriveMappings(Listbox1.items);
end;
La verdad que me has abierto un mundito nuevo, que cómodo es delphi! ...
Antes de todo te debo unas disculpas por no darle el seguimiento requerido a estas respuestas tuyas, es que soy de cuba y en este país la conexión a veces resulta muy difícil, y si la logras es lenta... en fin problemas y más problemas... bueno al código:
Ese procedure es interesante, solo que parece que no me has interpretado bien, yo no quiero saber cuales ni cuantas conexiones tengo a mi computadora. Me explico: yo trabajo o estudio en un lugar donde las computadoras están en una red LAN, bajo dominio regido por un servidor (DNS, routers, y toda esas cosas). Ahora mi aplicación debe de ser capaz de saber, cada vez que se le pida, cuales son las maquinas o pc encendidas en dicha red LAN, o dominio como prefieras, ¿me entiendes ahora? Por ejemplo, en el pedazo de código que me envías, en el onclick del button1 lo que hace es verificar las conexiones a mi maquina y listarlas en el listbox, y lo que desearía es que verificara las maquinas encendidas en el dominio o red LAN antes mencionadas y las liste en el listbox con sus nombres, ¿me entiendes? ok.. espero que si...
nos vemos ..
Espero poder conectarme de nuevo esta semana...
Saludos
bezeech
Bueno mira así tan fácil no creo que haya un función, lo que tienes que hacer es lo siguiente, del código que te envíe es listarte todas las maquinas, el siguiente paso es saber cual de esas maquinas esta conectada, ¿correcto? Y para esto tienes que hacer un ping por cada maquina que te muestra con la siguiente función:
function Ping(InetAddress : string) : boolean;
var
Handle : THandle;
InAddr : IPAddr;
DW : DWORD;
rep : array[1..128] of byte;
begin
result := false;
Handle := IcmpCreateFile;
if Handle = INVALID_HANDLE_VALUE then
Exit;
TranslateStringToTInAddr(InetAddress, InAddr);
DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0);
Result := (DW <> 0);
IcmpCloseHandle(Handle);
end;
Bueno intentalo y luego dime si funciona y que más te haría falta.
Bueno una vez más estoy en dudas!
Mira la funcion GetNetworkDriveMappings q me mandastes anteriormente me da un listado de las maquinas a cuales he echo conecciones o q estan conectadas a la mia de una u otra forma; ahora me mandas otra function Ping q es la encargada de verificar si esta conectada o dejo de hacerlo, es evidente q no has entendido todavia mi principal duda, de todas maneras me has aclarado muchas cosas q tenia confusas, incluso me has dado ideas buenas para otros proyectos :) ... bien ahora voy a hacer un intento mas para tratar de hubicarte en mi lugar de trabajo y asi llegar a un mutuo entendimiento ok? bien aqui voy:
Yo estudio en la Universidad Central de las Villas (Uclv), Cuba. Aquí, la red de computadoras esta disennada de manera tal que todas las facultades tienen su dominio y a este le asignan un numero ip
172.20.*.* ; como notas la primera parte del ip es constante para todas las maquinas de la universidad, por ejemplo las maquinas comprendidas en el rango de ip 172.20.2.1 - 172.20.2.255 pertenecen a un mismo dominio, o sea:
172.20.1.* -----> dominio1 (ABC, por ej.)
172.20.2.* -----> dominio2
172.20.3.* -----> dominio3
172.20.4.* -----> dominio4
Etc, etc,
El ultimo numero lo sustituí por un asterico, pero aclaro que es el que diferencia los id de un mismo dominio.
Bien, ¿me sigues hasta aquí? Ok. Entonces continuo: la aplicación a desarrollar debe de ser capaz de que, una
vez ejecutada, tenga la opción de listar (en un listbox por ejemplo) las computadoras que están encedidas en su dominio, por ejemplo: estoy sentado en una maquina que se llama Pc-09, con ip 172.20.2.45, ejecuto la aplicación y esta me debe dar una lista con esta idea:
172.20.2.1 server1
172.20.2.2 server2
172.20.2.3 pc-01
172.20.2.4 pc-02
172.20.2.5 pc-03
172.20.2.6 pc-04
. .
. .
. .
172.20.2.255 pc-xx
¿Me hago entender verdad?
La idea es que la aplicación escane un rango de ip dado ...
Creo que ahora debes de interpretar bien que es lo que me tiene en dudas desde que te consulte.
Ah y no recuerdo si te lo comente, la función PING no me corre debido a que el compilador no reconoce los tipos IPAddr, IcmpCreateFile, ni a la función TranslateStringToTInAddr,
¿Qué hago entonces? ¿Alguna UNIT que debo agregar al uses?
Saludos...
Al ejecutar tu código el compilador no encuentra la clase donde se halla el tipo IPAddr, tampoco encuentra IcmpCreateFile ni esta TranslateStringToTInAddr .. en la ayuda si vienen pero no lo logre encontrar la unit para que incluirla en el USES y poder probar el código ...
Saludos..
Bueno a ver espero ahora si haberte entendido.
Tu estas en una maquina que tiene una IP especifica, ahora tu quieres saber todas las maquinas que pertenecen al dominio de esa IP el cual esta basado en los 3 primeros conjuntos de números del IP (172.20.1.*) por ejemplo.
Y si por ejemplo el sistema lo corres en otra maquina que el ip es 172.20.2 entonces te deberá traer todas la maquinas que pertenecer al 172.20.2 y no las del 172.20.1, ¿Si verdad? Dime si ya lo entendí bien. Y empezar a buscar tu solución..
Bueno mira no encuentro una manera directa de hacerlo, pero intentemos esto primero tenemos que localizar la ip local es decir de la maquina donde esta corriendo el sistema, ok y esto la hacemos así:
Utilizamos el componente TCP que tenemos en la paleta de componentes: en código ponemos TCP1. LocalIP; y esto de devolverá la ip.
Ahora de esa ip tu sacaras a lo que llamamos dominio quitando el ultimo conjunto de números. Ok
Ahora aquí viene el problema lo que no encuentro es cuantas maquinas están en ese dominio pero podríamos hacer un ciclo desde 1 hasta al numero que tu crees que haya de maquinas por ejemplo de 1 a 255.
Ahora con la función que te envíe para hacer un ping hazlo por cada iteración del ciclo, si me explico. ¿Bueno intenta esto y dime si esta bien o algo te esta fallando? Ok, tenemos que sacarlo ok saludos...
Exactamente, eso es lo que busco ... :) parece que ahora si nos entendemos! ...
Espero entonces la solución que puedas dar!
saludos ...
bezeech
De echo las cantidad máxima de maquinas que acepta un dominio es 255, si esa idea es buena, estoy trabajando en ella, pero no se como obtener el nombre de la maquina a partir del IP, el nombre lo quiero para poder llenar el listado de las maquinas con su ip y nombre correspondiente...
Yo creo si vamos a sacarlo :) ...
ok, en la pestaña de componentes llamada Internet hay un componente llamado TcpServer1, pones un boton y en el OnClick pones el siguiente codigo ShowMessage(TcpServer1.LookupHostName('43.130.167.112'));
Aquí le pasas como parámetro el IP y te deberá mostrar el nombre de la maquina de ese IP. Ok
Colega tengo un problema ahora con la función PING que tu implementaste, esta:
function Ping(InetAddress : string) : boolean;
var
Handle : THandle;
InAddr : IPAddr;
DW : DWORD;
rep : array[1..128] of byte;
begin
result := false;
Handle := IcmpCreateFile;
if Handle = INVALID_HANDLE_VALUE then
Exit;
TranslateStringToTInAddr(InetAddress, InAddr);
DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0);
Result := (DW <> 0);
IcmpCloseHandle(Handle);
end;
Bueno el problema es que el delphi(6) no me reconoce el tipo de variable "IPAddr", tampoco reconoce las funciones
IcmpCreateFile y TranslateStringToTInAddr, q hago????
saludos ..
bezeech
Si tienes razón, mira aquí te mando toda una unidad y ahí puedes ver lo que te hace falta ok:
unit Ping;
Interface
Uses
Windows, SysUtils, Classes;
type
TSunB = packed record
s_b1, s_b2, s_b3, s_b4: byte;
end;
TSunW = packed record
s_w1, s_w2: word;
end;
PIPAddr = ^TIPAddr;
TIPAddr = record
case integer of
0: (S_un_b: TSunB);
1: (S_un_w: TSunW);
2: (S_addr: longword);
end;
IPAddr = TIPAddr;
function IcmpCreateFile : THandle; stdcall; external 'icmp.dll';
function IcmpCloseHandle (icmpHandle : THandle) : boolean; stdcall; external 'icmp.dll'
function IcmpSendEcho (IcmpHandle : THandle; DestinationAddress : IPAddr;
RequestData : Pointer; RequestSize : Smallint;
RequestOptions : pointer;
ReplyBuffer : Pointer;
ReplySize : DWORD;
Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll';
function Ping(InetAddress : string) : boolean;
implementation
uses
WinSock;
function Fetch(var AInput: string; const ADelim: string = ' '; const ADelete: Boolean = true)
: string;
var
iPos: Integer;
begin
if ADelim = #0 then begin
// AnsiPos does not work with #0
iPos := Pos(ADelim, AInput);
end else begin
iPos := Pos(ADelim, AInput);
end;
if iPos = 0 then begin
Result := AInput;
if ADelete then begin
AInput := '';
end;
end else begin
result := Copy(AInput, 1, iPos - 1);
if ADelete then begin
Delete(AInput, 1, iPos + Length(ADelim) - 1);
end;
end;
end;
procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var
phe: PHostEnt;
pac: PChar;
GInitData: TWSAData;
begin
WSAStartup($101, GInitData);
try
phe := GetHostByName(PChar(AIP));
if Assigned(phe) then
begin
pac := phe^.h_addr_list^;
if Assigned(pac) then
begin
with TIPAddr(AInAddr).S_un_b do begin
s_b1 := Byte(pac[0]);
s_b2 := Byte(pac[1]);
s_b3 := Byte(pac[2]);
s_b4 := Byte(pac[3]);
end;
end
else
begin
raise Exception.Create('Error getting IP from HostName');
end;
end
else
begin
raise Exception.Create('Error getting HostName');
end;
except
FillChar(AInAddr, SizeOf(AInAddr), #0);
end;
WSACleanup;
end;
function Ping(InetAddress : string) : boolean;
var
Handle : THandle;
InAddr : IPAddr;
DW : DWORD;
rep : array[1..128] of byte;
begin
result := false;
Handle := IcmpCreateFile;
if Handle = INVALID_HANDLE_VALUE then
Exit;
TranslateStringToTInAddr(InetAddress, InAddr);
DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0);
Result := (DW <> 0);
IcmpCloseHandle(Handle);
end;
end.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas