?
Solved

How to get Computer Name and IP Address in BCB?

Posted on 2003-03-16
16
Medium Priority
?
11,746 Views
Last Modified: 2007-12-19
In Delphi, someone use the following functions to get the local computer informations.
Such as:
 Function GetLocalIp(var LocalIp:string): Boolean; //to get local IP
 Function GetNameByIPAddr(IPAddr: string; var MacName: string): Boolean ;

How could we also use these functions to get local IP & MachineName in BCB, and what include files we must use?
0
Comment
Question by:abdate
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
  • 2
16 Comments
 
LVL 12

Expert Comment

by:Salte
ID: 8146193
To get the IP address and name in C++ the best way is probably the standard:

char hostname[64];

gethostname(hostname);

This gets the hostname of your machine and stuff it in the buffer hostname[].

Next you use gethostbyname to get the host entry for that machine:

struct hostent * he = gethostbyname(hostname);

Now, the IP address is found at he -> h_addr.

Note that the ip number stored there is in binary form, if you want it to be in ascii form (dotted numbers) you can use inet_ntoa() function to convert the ip address to a form such as "10.230.18.92".

Alf
0
 

Author Comment

by:abdate
ID: 8148013
Thanks for your reply!
But what include files for gethostbyname() & inet_ntoa(),
I get undefined functions for both during compiling.
Thank you very much!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8150397
under windows they should both be available if you include the file #include <winsock2.h> - at least that's what I believe the include file is called.

If not you can try #include <winsock.h> or perhaps even #include <windows.h>

Alf
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:Salte
ID: 8150401
In either case you can press F1 key while having cursor on the function names and you get explanation on both arguments, which include file to include and other info.

Alf
0
 

Author Comment

by:abdate
ID: 8151870
After I add on  #include <winsock2.h>
I got some problems:
1. s1 = false  for
   bool s1=gethostbyname(hostname);

   
2  he = NULL for
 struct hostent * he = gethostbyname(hostname);

3. Can not convert 'chr*' to 'in_addr'
  for inet_ntoa(he -> h_addr)

Could you give me more details to solve these problems?
0
 
LVL 12

Expert Comment

by:Salte
ID: 8152021
1. and 2.

Err... gethostbyname does not return bool value.

gethostbyname return a hostent structure.

If you get NULL for hostname then you specify a hostname which it cannot find an IP address for.

What is the value of the hostname string given to gethostbyname? If this is the proper name of your local host it should return the hostent structure for your local host.

The name should be something like this:

a) "foobar"  if your machine's name is foobar.
b) "foobar.baz.com" if you're machine is defined in the domain baz.com and is named foobar.


The name given from gethostname() is your local machine's name as it thinks the name is.

gethostbyname() looks up in a database and ask if there's machine named "...name arg here...." anywhere in the world and what is that machine's IP address if it is.

It returns NULL if the name isn't found anywhere.

Does your local machine at all have a name? If you didn't name it, it is possible that gethostname() only return an empty string or something.

Perhaps you mean gethostname() return false. Well, this isn't proper return type of the function. The function return 0 on success and non-zero on failiure so having it return bool means you get 'false' for success and 'true' for failiure - kinda opposite of what you want. Don't store the return in a bool variable.

Probably also a good idea to print out the string you get from gethostname() first time you try it.

Then call gethostbyname(). Gethostbyname() shouldn't go out on the net to find the hostname for your local host - if you have setup your machine's name and IP address properly. For other machines - i.e. if the name cannot be found locally gethostbyname() will send an IP request to a DNS server and ask it for the name. This DNS server may then in turn ask other DNS servers for the name if it doesn't have it in its own tables. When a machine is found some place in the world with the given name that DNS server will then send the info back to the DNS server you contacted and it will then send you the info. So it is possible that gethostbyname() will lead to a world wide search for a host of the given name. For this reason it is probably smart to be connected to the network when you try out these functions.

3. inet_ntoa() convert a binary 32 bit IP address to a string so you can display it on screen or write to file etc.

The return value is char * so you should do:

const char * s = inet_ntoa(he -> h_addr);

This will return something like "10.237.20.43" a so-called dotted decimal representation of the IP address.

Alf
0
 

Author Comment

by:abdate
ID: 8154435
Thanks for your help!
The following is my codeing:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
char hostname[14];
bool s1=gethostbyname(hostname);
struct hostent * he = gethostbyname(hostname);
const char * s = inet_ntoa(he -> h_addr);
}
I got error message during compileing like this:
E2034 cannot convert 'char *' to 'in_addr'
E2342 Type mismatch in parameter 'in'(wanted'in_addr',got'char *')

After I took away this line
 const char * s =inet_ntoa(he->h_addr);

the result is
s1=false
he =NULL

My computer name is "IBM"
I can got the local name "IBM" when I try someone's Delphi Application.

Please inspected my codeing and tell me how to modify them.
0
 
LVL 9

Expert Comment

by:Joeisanerd
ID: 8156817

//Character string for the address to check
char address[255];

or

AnsiString address

then use address.c_str() as the parameter for the gethostbyname.
   
// Look up an IP address for the given host name
struct hostent* phe;
if ((phe = gethostbyname(address)) == 0) {
     //Couldn't resolve the name
}

address most have a null terminated string with the hostname specified

To get the hostname of the machine to get the ip you need to use GetComputerName which you can get like this

AnsiString ComputerName()
{
    DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
    char szBuf[MAX_COMPUTERNAME_LENGTH + 1];
    szBuf[0] = '\0';

    GetComputerName(szBuf, &dwSize);

    return AnsiString(szBuf);
}

I hope this helps but if not I can explain further. I use BCB 5 alot!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8157533
gethostbyname takes an input argument for hostname.

gethostname takes a buffer and fill it in with the hostname.

so the first function should be gethostname and not gethostbyname.

also, I am not sure if bool is proper return value for it. It should be 'int' and 0 means success and non-zero means failure, so:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char hostname[14];
  struct hostent * he;

  if (gethostname(hostname)) {
     // something went wrong, display error message.
  } else if ((he = gethostbyname(hostname)) == 0) {
     // something went wrong with gethostbyname
     // display error message.
  } else {
     struct in_addr addr;
     memcpy(&addr,he -> h_addr,sizeof(addr));
     const char * s = inet_ntoa(addr);
     // s should now have the IP number in readable form.
     // addr and h_addr hold it in binary form.
     // hostname should hold the name "IBM".
  }
}

Hope this helps.

Alf
0
 

Author Comment

by:abdate
ID: 8160149
Thank You very much!
I try
 
 if (gethostname(hostname,20)){
   // something went wrong, display error message.
 }

and get NULL for hostname and cannot try more.

but try

  GetComputerName(szBuf, &dwSize);
It works,I get my local compter name "IBM".

I also try and get phe null for
 
if ((phe = gethostbyname(address)) == 0) {
    //Couldn't resolve the name
}


Now, I get CompterName, how to get my machine IP

Thanks for your patient!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8160641
If GetComputerName does it then that's the function you can use. It is a Win32 function. The 'gethostname' is supposed to call GetComputerName()' and return that value but it is possible you have some problems with that implementation.

In any case if you have the computer name then it is a simple matter to do:

struct hostent * he = gethostbyname("IBM");

If this returns NULL then it means that gethostbyname() cannot find your computer name. I thought it should be able to do that but it is possible you have something wrong.

set up a file named 'hosts' on your computer - it's supposed to be there already so search for the file in a windows directory (For example C:\Windows\something\hosts, not sure what that 'something' is but that is why you need to search for it. In unix the file is located in /etc/hosts.

This file was originally used to hold a list of all computer names that your computer knew about so it had entries such as:

IP-addr: foo.bar.com
Another-IP-addr:   baz.gazonk baz

etc...

if a line had more than one machine name it meant that the machine had several aliases and all of them mapped to the specified IP address.

Now, in modern times this file isn't used as much as it used to. The internet has a zillion computers and you cannot possibly go and edit that file each time someone in singapore install a new computer to the internet, so there's a new method in town.

When gethostbyname() get a name it searches first the file named hosts and if the entry isn't found there it will typically make a connection to your DNS server and ask about the hostname there. Since "IBM" is your own local computer you must not allow it to go to DNS, it probably wouldn't know where to find the machine by DNS either since DNS typically expect names like "ibm.someone.com" or some such. So, make sure your hosts file contain a line such as:

Your-IP-address: ibm

some place early in the file migh solve it. However, this require that you have a fixed IP address for your computer. If you run DHCP that won't work.

If you run DHCP you get a new IP number from time to time and you don't want to go and edit that hosts file each time you do it, so systems that support DHCP does it a little bit differently:

They simply save the IP number some place and your name and then when gethostbyname is called it check that place either before or after it has checked the hosts file.

Which place it checks and which place this info is stored vary from system to system. I believe you run Windows and there the system should take care of it for you. So gethostbyname() if you run a fairly modern version of winsock would take care of it.

It is possible that your version of winsock is too old and doesn't know about DHCP and that is why gethostbyname() can't find "IBM"?

If so you need to upgrade to a newer version of DHCP aware winsock.

In any case, try:

struct hostent * he = gethostbyname("IBM");

and tell me what you get.

Alf
0
 

Author Comment

by:abdate
ID: 8160797
Yes, I use BCB Ent. 5.0 UpdatePack 1 running on XP.
winsock2.h issued at 1/31/2000
Now I still get he NULL
for trying
struct hostent * he = gethostbyname("IBM");

How to get IP for this situation?

Thank you very much!!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8160935
If you get NULL from gethostbyname("IBM") I suspect the winsock2.h file of yours appear very outdated... january 31st, 2000...doesn't SOUND very old but you never know...

I really don't know of any other way to get the IP address. Of course, you could use the Winsock's native function to do it but that function is virtually the same and will probably also return NULL if gethostbyname() returns NULL.

This means that you need to look for another winsock2 function. Of course, the IP address is set in a setting in the registry but that isn't a portable nor a very good place to look for it.

Also, I somehow think that the winsock2.dll probably is modern enough - the problem is that somehow it doesn't know your machine's local name.

You can also get your local IP address by query the IP layer but that too isn't portable and is generally relying on undocumented features which you shouldn't use.

You could ask this question to some borland specific board or to some microsoft board and ask them about this winsock2.dll version you have that appear unable to get your hostname.

How is the hostname defined for your computer btw? Is it defined in the 'network identication' section under 'my computer\properties'? (right click on "My computer" and check properties etc...).

Is it possible it isn't defined some place where gethostbyname() is looking for it and when it doesn't find it there it doesn't look for it where you defined it?

Alf
0
 
LVL 9

Accepted Solution

by:
Joeisanerd earned 200 total points
ID: 8161585
Ok abdate here is some simple code that requires a simple button and a memo field for this demo. Just #include <winsock.h>

OnButton1 Click Event Below
{
   DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
   char szBuf[MAX_COMPUTERNAME_LENGTH + 1];
   szBuf[0] = '\0';

   //Retrieves the computer name
   GetComputerName(szBuf, &dwSize);

   //Adds the computer name to the memo
   Memo1->Lines->Add(AnsiString(szBuf));

   //Windows Socket initialization stuff
   //Why the gethostbyname returned null
   WSAData wsaData;
   if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
        ShowMessage("Error!");
    }

   //Gethostbyname
   //Better to use this funtion because you could use a dns name or a computer name
   struct hostent *phe;
   phe = gethostbyname(szBuf);

   //Converts the struct address to an AnsiString format
   AnsiString ipaddr;
   ipaddr = AnsiString(int(LOBYTE(LOWORD(*((DWORD*)phe->h_addr_list[0]))))) + ".";
   ipaddr+= AnsiString(int(HIBYTE(LOWORD(*((DWORD*)phe->h_addr_list[0]))))) + ".";
   ipaddr+= AnsiString(int(LOBYTE(HIWORD(*((DWORD*)phe->h_addr_list[0]))))) + ".";
   ipaddr+= AnsiString(int(HIBYTE(HIWORD(*((DWORD*)phe->h_addr_list[0])))));

   //Add the ip address to the memo
   Memo1->Lines->Add(ipaddr);

   //Windows socket clean up
   WSACleanup();
}


I know this works because I just did it with BCB 5 Professional and it returned my hostname and ip address. If you need to ping addresses I can help you with that as well.
0
 

Author Comment

by:abdate
ID: 8162605
Thank you Joeisanerd!! It works.
and I also thanks to Salte, he give me many help!!

-->If you need to ping addresses I can help you with that as well.

Sure,I like to know it. Please show me how to do it!!
0
 
LVL 12

Expert Comment

by:Salte
ID: 8165340
You still need to call WSAstartup????? I thought those days were over...

why can't they just have the winsock code act like regular socket code from other systems?

Oh well, I do suggest that you use inet_ntoa instead of the 'grabbing bytes myself and translating'. If you some day want to switch to IPv6 or something it is easier to do if you treat the addresses as opaque data that you do not inspect bit by bit and only accesses through standard functions.

winsock do provide inet_ntoa so if the problem was WSAstartup, then simply put WSAstartup call in the code I provided.

Alf

0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question