Avatar billede hugopedersen Nybegynder
18. november 2008 - 08:03 Der er 22 kommentarer og
1 løsning

Finde ip på 'ekstern' host

Kan man finde IP nummer på en ekstern host?
Jeg kan kun få WinSock funktionen GetHostByName til at finde den lokale host synes jeg.
Det er måske et eller andet DNS opslag der skal til.
Avatar billede borrisholt Novice
18. november 2008 - 08:10 #1
Prøv med et DNS opslag .. Brug indy

Her har du nogle demoer :
http://pjtsalina.codigolivre.org.br/doc/pascal/Delphi6Demos/Indy/indy_demos.html

Jens B
Avatar billede hugopedersen Nybegynder
18. november 2008 - 09:13 #2
Jeg kan ikke downloade noget der fra!

Jeg har Indy 9 demoer, men jeg kan ikke compile hverken med Delphi 5 eller 2009.
De brokker sig over DNS.QueryRecords
Avatar billede borrisholt Novice
18. november 2008 - 09:20 #3
Måske du så bare skal bruge ren winAPI, hvad med funktionen GetHostByAddr, den burde kunne hjælpe dig
Avatar billede hugopedersen Nybegynder
18. november 2008 - 12:32 #4
GetHostByAddr returnerer den ikke hostnavnet ud fra en IP adresse?
Avatar billede borrisholt Novice
18. november 2008 - 12:49 #5
Nå ja nu var det mig der ikke var vågen ...

Jeg fandt lige noget i mine gemmere :

unit ToolsU;

interface
uses
  Windows, WinSock;
type
  IStringTokenizer = interface
    ['{8C216E9D-984E-4E38-893F-0A222AC547DA}']
    function GetTokenCounts: Integer;
    function HasMoreTokens: Boolean;
    function NextToken: string;
    property countTokens: Integer read getTokenCounts;
  end;

function FirstDelimiter(const Delimiters: string; const Str: string): Integer; overload;
function StringTokenizer(const Str: string; const delim: string): IStringTokenizer;
function IpAdressToDOWRD(const IpAdress: string): DWORD;
function DOWRDToIpadress(const Value: DWORD): string;
function GetIpFromHostname(const Hostname: string): string;
function GetDWORDFromHostname(const Hostname: string): DWORD;

implementation
uses
  SysUtils;

type
  TStringTokenizer = class(TInterfacedObject, IStringTokenizer)
  private
    FString: string;
    FDelim: string;
    FCurPos: Integer;
  public
    constructor Create(const Str: string; delim: string);
    function GetTokenCounts: Integer;
    function HasMoreTokens: Boolean;
    function NextToken: string;
    property CountTokens: Integer read GetTokenCounts;
  end;

function _IndexOf(const ch: Char; const Str: string): Integer; overload;
var
  I: Integer;
begin
  Result := 0;
  I := 1;
  while I <= Length(Str) do
  begin
    if Str[I] = ch then
    begin
      Result := I;
      Exit;
    end;

    Inc(I);
  end;
end;

function FirstDelimiter(const Delimiters: string; const Str: string): Integer;
var
  I: Integer;
begin
  Result := 0;
  I := 1;
  while I <= Length(Str) do
  begin
    if Str[I] in LeadBytes then
      Inc(I)
    else if _IndexOf(Str[I], delimiters) > 0 then
    begin
      Result := I;
      Exit;
    end;
    Inc(I);
  end;
end;

function StringTokenizer(const Str: string; const delim: string): IStringTokenizer;
begin
  Result := TStringTokenizer.Create(Str, delim);
end;

constructor TStringTokenizer.Create(const Str: string; delim: string);
begin
  FString := Str;
  FDelim := delim;
  FCurPos := 1;
  { Point FCurPos to beginning of next Token }
  while (FCurPos <= Length(FString)) and (_IndexOf(FString[FCurPos], FDelim) > 0) do
    Inc(FCurPos);
end;

function TStringTokenizer.GetTokenCounts: Integer;
var
  I: Integer;
  Cnt: Integer;
begin
  Cnt := 0;
  I := 1;
  while I <= Length(FString) do
  begin
    while (I <= Length(FString)) and (_IndexOf(FString[I], FDelim) > 0) do
      Inc(I);
    if I <= Length(FString) then
      Inc(Cnt);
    while (I <= Length(FString)) and (_IndexOf(FString[I], FDelim) = 0) do
      Inc(I);
  end;
  Result := Cnt;
end;

function TStringTokenizer.HasMoreTokens: Boolean;
begin
  Result := FCurPos < Length(FString);
end;

function TStringTokenizer.NextToken: string;
var
  endPos: Integer;
begin
  if FCurPos > Length(FString) then
  begin
    Result := '';
    Exit;
  end;
  endPos := FCurPos;

  while (endPos <= Length(FString)) and (_IndexOf(FString[endPos], FDelim) = 0) do
    Inc(endPos);

  Result := Copy(FString, FCurPos, endPos - FCurPos);
  { Point FCurPos to beginning of next Token }
  FCurPos := endPos;

  while (FCurPos <= Length(FString)) and (_IndexOf(FString[FCurPos], FDelim) > 0) do
    Inc(FCurPos);
end;

function IpAdressToDOWRD(const IpAdress: string): DWORD;
begin
  Result := DWORD(ntohl(inet_addr(Pointer(IpAdress))));
end;

function DOWRDToIpadress(const Value: DWORD): string;
begin
  Result := iNet_ntoa(in_addr(Value));
end;

function GetIpFromHostname(const Hostname: string): string;
var
  MyWSAData: WSADATA;
  RHost: pHostent;
  Ptr: Pointer;
  Remote_Addr: In_Addr;
begin
  WSAStartup($0101, MyWSAData);
  RHost := gethostbyname(pointer(hostname));

  Ptr := RHost^.H_Addr_List^;

  Move(Ptr^, Remote_Addr, 4);
  Result := inet_ntoa(Remote_Addr);
  WSACleanup;
end;

function GetDWORDFromHostname(const Hostname: string): DWORD;
var
  Ip: string;
begin
  Ip := GetIpFromHostname(Hostname);
  Result := IpAdressToDOWRD(Ip);
end;
end.


Jens B
Avatar billede borrisholt Novice
18. november 2008 - 12:53 #6
Du bruger Delphi 2009 vær opmærksom på der er et gammelt hack der skal ænderes:

JEg type caster en streng til en Pchar ved at caste en en pointer, gammelt udokumenteret hack, som altså ikke vorker mere på unicodestrings ...

function IpAdressToDOWRD(const IpAdress: string): DWORD;
begin
  Result := DWORD(ntohl(inet_addr(Pointer(IpAdress))));
end;

function GetIpFromHostname(const Hostname: string): string;
var
  MyWSAData: WSADATA;
  RHost: pHostent;
  Ptr: Pointer;
  Remote_Addr: In_Addr;
begin
  WSAStartup($0101, MyWSAData);
  RHost := gethostbyname(pointer(hostname));

  Ptr := RHost^.H_Addr_List^;

  Move(Ptr^, Remote_Addr, 4);
  Result := inet_ntoa(Remote_Addr);
  WSACleanup;
end;



skal ænderes til

function IpAdressToDOWRD(const IpAdress: string): DWORD;
begin
  Result := DWORD(ntohl(inet_addr(pChar(IpAdress))));
end;

function GetIpFromHostname(const Hostname: string): string;
var
  MyWSAData: WSADATA;
  RHost: pHostent;
  Ptr: Pointer;
  Remote_Addr: In_Addr;
begin
  WSAStartup($0101, MyWSAData);
  RHost := gethostbyname(pChar(hostname));

  Ptr := RHost^.H_Addr_List^;

  Move(Ptr^, Remote_Addr, 4);
  Result := inet_ntoa(Remote_Addr);
  WSACleanup;
end;
Avatar billede hugopedersen Nybegynder
18. november 2008 - 13:10 #7
Det resulterer i at programmet crasher hårdt og brutalt hvis jeg bruger din unit - med de nævnte rettelser.
Avatar billede borrisholt Novice
18. november 2008 - 13:25 #8
Den virker UDEN rettelser i Delphi 2007, har ikke lige mulighed for at teste det i Delphi 2009, rettelserne var en frit fra leveren rettelse.

Her er koden til min delphi 2007 test
    Memo1.Lines.Add( GetIpFromHostname( Edit1.Text  ))
Avatar billede hugopedersen Nybegynder
18. november 2008 - 13:49 #9
Function hp_Host_Validate(strHost : String) : Boolean;

  Var
    strIP                  : String;

Begin
ShowMessage(strHost);
  strIP := GetIpFromHostname(strHost);

Og så crasher den hårdt og brutalt.
Avatar billede borrisholt Novice
18. november 2008 - 13:59 #10
Så brug AnsiString
Avatar billede hugopedersen Nybegynder
18. november 2008 - 14:27 #11
Har prøvet - det gør absolut ingen forskel desværre.
Avatar billede borrisholt Novice
19. november 2008 - 09:51 #12
Kender du Google ? Den her artikel kan du helt sikkert gøre brug af :
http://www.jacobthurman.com/?p=31

I følge den er løsningen :

function IpAdressToDOWRD(const IpAdress: string): DWORD;
begin
  Result := DWORD(ntohl(inet_addr(PAnsiChar(AnsiString(IpAdress)))));
end;

function GetIpFromHostname(const Hostname: string): string;
var
  MyWSAData: WSADATA;
  RHost: pHostent;
  Ptr: Pointer;
  Remote_Addr: In_Addr;
begin
  WSAStartup($0101, MyWSAData);
  RHost := gethostbyname(PAnsiChar(AnsiString(hostname)));

  Ptr := RHost^.H_Addr_List^;

  Move(Ptr^, Remote_Addr, 4);
  Result := inet_ntoa(Remote_Addr);
  WSACleanup;
end;

Jens Borrisholt
Avatar billede hugopedersen Nybegynder
19. november 2008 - 12:32 #13
Det hjalp lidt - nu går det kun ned hvis jeg prøver at finde IP på en host der ikke findes.
Det er linien  Ptr := RHost^.H_Addr_List^; der får det til at crache
RHost er nil men jeg kan ikke få den til at teste på det synes jeg.
Avatar billede mbsnet Nybegynder
20. november 2008 - 06:38 #14
//måske kan denne (ikke testet):

type
str=ansiString;

function GetIpFromHostname(const Hostname: str): str;
var
  MyWSAData: WSADATA;
  RHost: pHostent;
  p:pChar;//ellers: "pAnsiChar"
  Remote_Addr: In_Addr;
begin
  result:='';
  wsaStartup($0101, MyWSAData);
  //det bør være nok at anføre som pChar ovenfor, og så kalde med pointer her.
  p:=pointer(hostname);
  if (p<>nil) and (p^<>#0) then begin
  rHost:=getHostByName(p);
  p:=rHost^.H_Addr_List^;
  if (p<>nil) and (p^<>#0) then move(p^,remote_addr,4);
  end;
  result:=inet_ntoa(remote_addr);
  wsaCleanup;
end;

//mvh mbs
Avatar billede borrisholt Novice
20. november 2008 - 08:22 #15
hmmn eksperten åd min post

function GetIpFromHostname(const Hostname: string): string;
var
  MyWSAData: WSADATA;
  RHost: pHostent;
  Ptr: Pointer;
  Remote_Addr: In_Addr;
begin
  WSAStartup($0101, MyWSAData);
  try
    RHost := gethostbyname(PAnsiChar(AnsiString(hostname)));

    if RHost = nil then
      Exit('');

    if RHost^.H_Addr_List = nil then
      Exit('');

    Ptr := RHost^.H_Addr_List^;

    Move(Ptr^, Remote_Addr, 4);
    Result := inet_ntoa(Remote_Addr);
  finally
    WSACleanup;
  free;
end;
Avatar billede hugopedersen Nybegynder
20. november 2008 - 08:23 #16
Jeg havde testet forkert :-)

Hvis jeg skriver
RHost := gethostbyname(PAnsiChar(AnsiString(hostname)));
If RHost = Nil Then Exit;

Så virker det som ønsket.

Jeg havde skrevet
If Not RHost = Nil Then
  Begin
    ...................
  End;

Og det virker bare ikke.

Borrisholt> et svar for din hjælp.
Avatar billede hugopedersen Nybegynder
20. november 2008 - 08:25 #17
Ja Try kunne måske være smart at putte på også - den tager de værste 'bugs' :-)
Avatar billede hugopedersen Nybegynder
20. november 2008 - 08:31 #18
Bortset fra at jeg ikke kan få den til at æde den sidste Free, så er dit sidste forslag i brug.
Avatar billede borrisholt Novice
20. november 2008 - 10:26 #19
Det free ved jeg ikke lige hvor kommer fra ...

Det er en gave :D Så har du lige et ekstra free på lager hvis du skulle bruge det :D
Avatar billede olebole Juniormester
20. november 2008 - 10:32 #20
<ole>

"Free ... free at last!"
    Martin L. King

;D

/mvh
</bole>
Avatar billede borrisholt Novice
20. november 2008 - 10:39 #21
FreeAndNil(olebole);

;o)
Avatar billede borrisholt Novice
21. november 2008 - 08:51 #22
HUGGO>> Jeg spammer dig lige. To ting hvis du bruger Messenget kan du jo komme på min liste Jens@borrisholt.com

Jeg bemærkede at du er lidt stiv i øvelsen "Porte til Delphi 2009", jeg fandt 3 artikler som du bør læse i gennem:

Delphi in a Unicode World Part I: What is Unicode, Why do you need it, and How do you work with it in Delphi?
http://dn.codegear.com/article/38437

Delphi in a Unicode World Part II: New RTL Features and Classes to Support Unicode
http://dn.codegear.com/article/38498

Delphi in a Unicode World Part III: Unicodifying Your Code
http://dn.codegear.com/article/38693

Jens Borrisholt
Avatar billede hugopedersen Nybegynder
21. november 2008 - 11:14 #23
Ting der indeholder noget fornuftigt er ikke spam :-)

/Hugo
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester