Windows NT Systems Programming: Spring 1999

[ Home | Syllabus | Course Notes | Assignments | Search]


Case Study in problem solving VC++ problems

Objective: develop an experimental program for demonstrating the use of symbol machine names in lieu of IP addresses. The main focus was on understanding gethostbyname.

I hoep it will be helpful if I explain the process of getting this simple program to work and of how I figured out the solutions to problems that occurred.

Attempt 1: wrote a simple program which uses gethostbyname after reading on-line documentation and examining windoes socket programming book for examples.


#include <winsock.h>
#include <iostream.h>

void main()
{
   char name[100];
	
   while (true) {
      cout << " type host name: ";
      if(!cin.getline(name,100))
         break; // probably end of file
      if(name[0] == '\0')
         break; // empty string means user done
		
         lpstWSHostent = gethostbyname(name);
         if(! lpstWSHostent) {
            cout << " could not resolve name: \n";
            continue;
         }
         lAddr = *((u_long FAR *) (lpstWSHostent)->h_addr);
         cout << "Primary network IP address is: " << lAddr << endl;
   }
   cout << "done \n";
}

At first this program compiled but would not link. I got the error

main.obj : error LNK2001: unresolved external symbol _gethostbyaddr@12

Again looking at quick infor button in the help for gethostbyname, I saw that gethostbyname is found in the library wsock32.lib. I next went to the Projects menu to Settings, picked the "Link" tab and added this library to the list already being linked.

This program compiled and run but gave an error "could not resolve name".

In order to understand the reason for the failure, I added WSAGetLastError.

Attempt 2:


#include <winsock.h>
#include <iostream.h>

void main()
{
   char name[100];
	
   while (true) {
      cout << " type host name: ";
      if(!cin.getline(name,100))
         break; // probably end of file
      if(name[0] == '\0')
         break; // empty string means user done
		
         lpstWSHostent = gethostbyname(name);
         if(! lpstWSHostent) {
            cout << " could not resolve name: "<< WSAGetLastError() << "\n";
            continue;
         }
         lAddr = *((u_long FAR *) (lpstWSHostent)->h_addr);
         cout << "Primary network IP address is: " << lAddr << endl;
   }
   cout << "done \n";
}

This gave the error number 10093.
What to do? I wanted to know which error this was. so I looked into the hlpe file for gethostbyname and clicked on "quick info". This told me that the header file of interest was winsock2.h.

Next I opened that header file (it was in c:\Program Files\DevStudio\Vc\include\winsock2.h) and searched for "93" and found this.

#define WSANOTINITIALISED (WSABASEERR+93)

This is typically of most errors - they consist of a BaseErr and a specific one - that is why searching on 10093 would not find anything.

Now I knew the problem - I forgot to load the winsock DLL. SO this was my next attempt.

Attempt 3:


#include <winsock.h>
#include <iostream.h>

void main()
{
   char name[100];
   int status;
   WSADATA Data;
   
   status=WSAStartup(MAKEWORD(1, 1), &Data);	// ONLY REQUIRES VERSION 1.1 OF DLL
   if (status != 0) {
      cerr << "ERROR: WSAStartup unsuccessful" << endl;
      ExitProcess(1);
   }
	
   while (true) {
      cout << " type host name: ";
      if(!cin.getline(name,100))
         break; // probably end of file
      if(name[0] == '\0')
         break; // empty string means user done
		
         lpstWSHostent = gethostbyname(name);
         if(! lpstWSHostent) {
            cout << " could not resolve name: "<< WSAGetLastError() << "\n";
            continue;
         }
         lAddr = *((u_long FAR *) (lpstWSHostent)->h_addr);
         cout << "Primary network IP address is: " << lAddr << endl;
   }
   cout << "done \n";
}

 


This program works and returned a large integer. I decided to continue experimenting with related functions I found in the help section. I wanted to confirm the validity of the large integer. SO why not convert in back into a string representing the IP address in human readable forms.

 

 

#include <winsock.h>
#include <iostream.h>

void main()
{
   char name[100];
   struct hostent FAR *lpstWSHostent; // ptr to WinSock DLL hostent
   int status;
   WSADATA Data;
   u_long lAddr;
   struct in_addr hostAddr;


   status=WSAStartup(MAKEWORD(1, 1), &Data);	// ONLY REQUIRES VERSION 1.1 OF DLL
   if (status != 0) {
      cerr << "ERROR: WSAStartup unsuccessful" << endl;
      ExitProcess(1);
   }
	
   while (true) {
      cout << " type host name: ";
      if(!cin.getline(name,100))
         break; // probably end of file
      if(name[0] == '\0')
         break; // empty string means user done
		
         lpstWSHostent = gethostbyname(name);
         if(! lpstWSHostent) {
            cout << " could not resolve name: "<< WSAGetLastError() << "\n";
            continue;
         }
         lAddr = *((u_long FAR *) (lpstWSHostent)->h_addr);
         cout << "Primary network IP address is: " << lAddr << endl;
         lpstWSHostent = gethostbyaddr((char FAR *)&lAddr,4,AF_INET);
         cout << " Host name is: " << lpstWSHostent->h_name << endl;
// above gets symblic address as a string
// below gets numeric PI address as a string
	 hostAddr.s_addr = lAddr;
         cout << "IP address is: " << inet_ntoa(hostAddr) << endl;
   }
   cout << "done \n";
}
		

Copyright chris wild 1999.
For problems or questions regarding this web contact [Dr. Wild].
Last updated: January 26, 1999.