Use MFC to write an internet query Program

Source: Internet
Author: User
Tags gopher file transfer protocol name database
In VC ++ 5.0, The WinInet class of MFC encapsulates relevant win32 API functions for programming in internet client programs. In this way, the internet client program can be compiled without understanding the details of winsock or TCP/IP. In this article, we will explore how to use the WinInet class to compile an internet query program named "Pathfinder ". The program can use various protocols to query the network, including the old FINGER and WHOIS.

As the name suggests, Pathfinder is used to find out the situation of an internet server and what services it can provide. For example, if you know someone's e-mail address and assume it's a wang@eop.com, we can use this program to try to build a link to eop.com in a variety of ways, then, WWW queries, FTP queries, GOPHER queries, FINGER queries, and WHOIS queries are used for the specified domain in sequence. Based on the returned results, you can determine which services the domain can provide. In addition, if you want to give your server a domain name, you can also use this program to know whether the domain name has been used.

I. Implementation of the query Program Interface
The User Interface of this program is implemented based on the dialog box. To create an interface, follow these steps:

In developer studio,
1. Select file-new ..., Highlight the MFC appwizard (exe), name the query program in the Project name column, and click OK.
2. In step-1, click dialog based and select English as the resource language. Click next.
3. in step 2, deselect the ActiveX Controls check mark. Do not select windows socket (this program does not directly call the socket function). In the dialog box, type "Explorer" in the title bar ".
4. In step-3, select yes, please, and As a ststically linked library.
5. In step-4, do not change any class name generated by appwiard. After appwizard is completed, we are ready to write the core part of the program.

Appwizard creates an empty dialog box from which we will start to work. The Edit dialog box is as follows:
Select resource view, expand query resources-dialogs, double-click the IDD-QUERY-DIALOG resource, the following edit dialog box:

1. Change the "OK" button to "query host", right-click the button, select properties, and change the ID name of the button to id-query.
2. Change the CANCEL button to "End query ".
3. Delete static text such as to do.
4. Increase the dialog box to 300 pixels in width.
5. Add an edit box at the top of the dialog box, the resource id is named IDC-HOST, stretching the edit box to the widest.
6. Add a tag named "address name" to the edit box.
7. Stretch the dialog box to 150 pixels High.
8. Add another edit box at the bottom of the dialog box, named IDC-OUT, stretching it to as large as possible to fill up the remaining space of the dialog box.
9. Add features such as Multi-line, Horizontal scroll, Vertical scroll, Border, and Read-only to the edit box.

When you click the "query host" button, the program queries the URL in various ways. Therefore, you need to use classwizard to link the code that implements the query function to the query button.

1. Select view-classwizard.
2. Select the CQueryDlg class. The host name will be accepted by this class.
3. Highlight ID-query. Highlight BN-CLICKED in the list on the right.
4. Click Add function to Add a function.
5. The recommended class wizard name is onok. Change it to onquery and click OK.
6. Click the member variable column to prepare the variables for connecting the Edit Control to the dialog box class.
7. Highlight the IDC-HOST and click Add variable. The Edit Control is connected to the cstring member variable of the dialog box class, named m_host.
8. Similar to the above steps, link the IDC-OUT to the cstring variable m_out

Click OK to close classwizard. The rest of the work is to compile the cquerydlg: onquery () function, which will use the m_host value for query and output the result to the m_out variable.

2. write code for HTTP query
When querying an Internet address, you should first try to establish an HTTP link. This is because a large number of addresses contain web pages. The simplest way to establish a link using HTTP is to use the winlnet cinternetsession class and call its member function Openurl (). This function will return a file. We will display the first few lines of text in the file in m_out. First, add the following lines at the beginning of querydlg. cpp:
# Include 'afxinet. H'

This defines the code to access the winlnet class. Because this program will access a large number of URLs, add a function named tryurl in cquerydlg, which contains a cstring class parameter named URL, and the return value is void. Right-click the cquerydlg class and select Add member function .... Add the tryurl () function and define it as the protected type. This new function will be called from cquerydlg: onquery. Add the following code to onquery:

Void cquerydlg: onquery ()
{Const cstring HTTP = "http ://";
Updatedata (true );
M_out = "";
UpdateData (FALSE );
TryURL (http + m_host );
TryURL (http + "www." + m_host );
}

The call to UpdateData (TRUE) will assign the User-Defined value to m_host. The UpdateData (FALSE) Statement clears the content of the m_out variable in the output editing box. Next Call TryURL () twice, for example, when the user inputs microsoft.com, the program will first try the http://microsoft.com and then try the http://www.microsoft.com. The following is the code for TryURL.

Void CQueryDlg: TryURL (CString URL)
{
CInternetSession session;
M_out + = "linking" + URL + "/r/n ";
UpdateData (FALSE );
CInternetFile * file = NULL;
Try
{
File = (CInternetFile *) session. OpenURL (URL );
}
Catch (CInternetException * pEx)
{
File = NULL;
PEx-> Delete ();
}
If (file)
{
M_out + = "established link. /R/n ";
CString line;
For (int I = 0; I <20 & file-> ReadString (line); I ++)
{
M_out + = line + "/r/n ";
}
File-> Close ();
Delete file;
}
Else
{
M_out + = "No http host/r/n found at this address ";
}
M_out + = "------------------------------------------------------/r/n ";
UpdateData (FALSE );
}

Next, we will analyze the above Code one by one. First, create an internet zone, which defines a CInternetSession object. The constructor's prototype is as follows:

Cinternetsession (maid = NULL, DWORD dwcontext = 1, DWORD dwaccesstype = Beijing, lpctstr pstrproxyname = NULL, lpctstr pstrproxybypass = NULL, DWORD dwflags = 0). Many parameters need to be defined, however, this program uses the default value, that is, the value after "=. Cinternetsession constructor parameters are described as follows:

Lpctstr pstragent-Application name. If it is null, it will fill in the program name you have given in Appwizard for you.
DWORD dwcontext-device identifier definition for this operation.

DWORD dwaccesstype-access type, which is one of the following parameters: internet_open_type_preconfig (default), internet_open_type_direct, or internet_open_type_proxy
Lpctstr pstrproxyname-if the access type is internet_open_type_proxy, the protocol name is assigned to this parameter.
Lpctstr pstrproxybypass-if the access type is internet_open_type_proxy, this parameter is a series of addresses that are directly linked without passing through the Protocol server.

DWORD dwflags-the following parameters can be used: internet_flag_dont_cache, internet_flag_async, and internet_flag_offline.
If the dwaccesstype value is missing, the value defined in the system register book will be used. Obviously, it is better to allow the user to define the access type than to define the access type directly within the program. Therefore, to use this program correctly, you must first define the network access type in the Windows system. The steps are as follows:

1. Double-click the "my computer" icon on the desktop.
2. Click "contyol panel ".
3. Click "Internet ".
4. In the pop-up dialog box, select the "connection" column and enter the network connection attributes. If you are using dial-up Internet access, select "dial" and fill in relevant attributes. If you access the Internet through the proxy server, select the "proxy" option and click the "setting" button to set the proxy server address and port number. If you are directly connected to the Internet, all options should be deselected.

This program uses the default value when constructing a cinternetsession object. Therefore, the constructor does not include any parameters. As follows:

Cinternetsession session;
After constructing the object session, we need to write two lines of program for some output, indicating that the program has started to work.
M_out + = "linking" + URL + "/R/N ";
Updatedata (false );

Next, we use the session object member function Openurl () to open a URL resource. This function returns a pointer to a file. The file type is one of the following:

// If you are accessing a local machine, the function returns a pointer to a cstudiofile class object.
FTP: // If an FTP address is accessed, the function returns a pointer to a cinternetfile class object.
Gopher: // If a gopher address is accessed, the function returns a pointer to a cgopherfile class object.
Http: // If an http address is accessed, the function returns a pointer to a CHttpFile class object.

This program is used to access remote machines. Therefore, the function does not return a // type local file. CGopherFile and CHttpFile are derived from CInternetFile, so it is safe to assign the return value of this function to the pointer of the CInternetFile class. When OpenURL () cannot open URL resources normally, this function will throw an exception, resulting in a program running error. Because this program is used to probe an unknown URL, the URL may not provide the corresponding service or does not exist at all, so OpenURL () may not run properly sometimes. To avoid program termination, we need to use the try-catch structure to handle exceptions. The code of this program is as follows:

CInternetFile * file = NULL;
Try
{
File = (CInternetFile *) session. OpenURL (URL );
}
Catch (CInternetException * pEx)
{
File = NULL; // If a runtime error occurs, assign a NULL value to the file, and the program continues to run.
PEx-> Delete ();
}

With the above Code, the program will use the address specified by the user to open the Http URL. If it fails and the returned file is empty, the program will continue to run and try to open the URL using other protocols. Then, no matter whether the website is successfully opened or not, we should make the corresponding output to prompt the user. If the result is successful, we use a for loop to read the first 20 sentences of the returned file and output the results. If the result fails, we also need to give a corresponding prompt. The procedure is as follows:
If (file) // determine whether the link is successful
{
M_out + = "established link. /R/n ";
CString line;
For (int I = 0; I <20 & file-> ReadString (line); I ++)
{
M_out + = line + "/r/n ";
}
File-> Close ();
Delete file;
}
Else
{
M_out + = "No http host/r/n found at this address ";
}
M_out + = "------------------------------------------------------/r/n ";
UpdateData (FALSE );

Now we can compile and run the program, type the address microsof.com and query, the output information shows that the program in the http://microsoft.com and http://www.microsoft.com are found www web page, and output the first 20 lines of HTML files on the home page.

Iii. ftp query implementation

Now we continue programming to check whether the user-entered website provides the ftp service. Ftp is a File Transfer Protocol on the internet, which is mainly used to transfer files between the server and the client. It is impossible to call TryURL () again to achieve the goal, because TryURL () is assumed that the URL points to a file and an ftp URL points to a series of files. You must rewrite a function and add another member function void TryFtp (CString host) to the CQueryDlg class, following the previous steps ). If the website you are exploring provides the ftp service, this function will find the default ftp directory and display it. The Code is as follows:

Void CQueryDlg: TryFTP (CString host)
{
Cinternetsession session;
M_out + = "Connecting FTP address" + host + "/R/N ";
Updatedata (false );
Cftpconnection * connection = NULL;
Try
{
Connection = session. getftpconnection (host );
}
Catch (cinternetexception * PEX)
{
Connection = NULL;
Pex-> Delete ();
}
If (connection)
{
M_out + = "established link. /R/N ";
Cstring line;
Connection-> getcurrentdirectory (line );
M_out + = "the default directory is" + LINE + "/R/N ";
Connection-> close ();
Delete Connection;
}
Else
{
M_out + = "No FTP host is found at this address. /R/N ";

}
M_out + = "------------------------------------------------------/R/N ";
Updatedata (false );
}

This function is similar to tryurl (). However, instead of using Openurl () to open a file, getftpconnection () is used to establish a connection with the FTP server. If the connection is successful, getcurrentdirectory () is used to obtain the default directory of the server.

Most FTP addresses have a prefix of FTP. But some old addresses do not have this prefix. We can add two lines at the end of the onquery () function to call this new function:

Tryftp (m_host );
Tryftp ("ftp." + m_host );

Recompile the program and run it. You can find that FTP service is provided at ftp.microsoft.com. There will be some latency when you start to query the results, because all the results, such as programs, will be displayed again. If we want the results to be displayed in real time, we must use Asynchronous sockets) or multi-threaded programming.

Iv. Gopher query implementation

GOPHER is a text-based protocol that is similar to WWW. You can click the text content to link and browse the network. However, GOPHER organizes links and content through step-by-step text menus. It does not have rich multimedia pages like WWW. To implement the GOPHER query, we should add another member function void TryGopher (CString host) to the CQueryDlg class ). If the query is successful, the function returns the first Gopher location (locator) of the query address ). Location is the concept of the gopher protocol. Any gopher client program must first obtain a gopher location before performing corresponding gopher operations. The TryGopher () function is as follows:

Void CQueryDlg: TryGopher (CString host)
{
CInternetSession session;
M_out + = "linking gopher address" + host + "/r/n ";
UpdateData (FALSE );
CGopherConnection * connection = NULL;
Try
{
Connection = session. GetGopherConnection (host );
}
Catch (CInternetException * pEx)
{
Connection = NULL;
PEx-> Delete ();
}
If (connection)
{
M_out + = "established link. /R/n ";
CString line;
CGopherLocator locator = connection-> CreateLocator (NULL, NULL, GOPHER_TYPE_DIRECTORY );
Line = locator;
M_out + = "the first Gopher location is" + line + "/r/n ";
Connection-> Close ();
Delete connection;
}
Else
{
M_out + = "No gopher host is found at this address. /R/n ";
}
M_out + = "------------------------------------------------------/r/n ";
UpdateData (FALSE );
}

This function is similar to the first two functions. getgopher connection (host); after creating a gopher link, you can use the statement cgopherlocator locator = connection-> createlocator (null, null, gopher_type_directory); To create a gopher location (Locator ), the createlocator () function has multiple versions. Now we use versions with three parameters. The original form is cgopherlocator createlocator (lpctstr pstrdisplaystring, lpctstr pstrselectorstring, DWORD dwgophertype );. The pstrdisplaystring parameter specifies the specific file or directory name on the server to be queried. If it is null, the default directory name of the server is returned. The pstrselectorstring parameter is a character command sent to the server, to retrieve a project. It can be set to null. The dwgophertype parameter specifies the gopher access type. In this example, it is defined as gopher_type_directory, indicating that the target directory is to be accessed. For other optional values, see the VC ++ 5.0 documentation. After the gopher position (Locator) is created, we forcibly convert it to the cstring type and display it. Add the following lines to the end of the onquery () function:

Trygopher (m_host );
Trygopher ("Gopher." + m_host );

Recompile the program and enter the address Harvard.edu. The program will find that it is a gopher address and display the first gopher location.

5. Use gopher to implement Finger query

The Finger protocol is used to provide you with a specific website. It is one of the oldest protocols on the Internet. On a Finger server, you can query the status of a user or the entire website. Of course, this is detrimental to network security. In fact, when experienced hackers attack an Unknown network, the first step is to send Finger and Whois queries to it, this step is also recommended in the hacker tutorial on the hacker website. For security purposes, many network servers do not provide the Finger service. However, when it receives the Finger query request, it still returns some other useful information.

In the MFC and WIN32 APIs, the Finger query function is not provided, but we still have a work und to implement it. All internet links require a host name and port number. All famous services have their specific port numbers. For example, the http service uses port 80 on the remote host machine, the ftp service uses port 21 and the gopher service uses port 70. For the finger service, port 79 is used. Finger is a simple protocol. If you send a string to port 79 of the remote host, the finger server sends a finger response after listening on port 79. If the string you send only contains/r/n, the server will usually return the list of all users on the server and related information (such as the real name of the user) as a response. Therefore, if we do not use the default port 70, but use port 79 to establish a gopher link, we can issue a finger query. Add a member function void TryFinger (CString host) to the CQueryDlg class as follows:

Void CQueryDlg: TryFinger (CString host)
{
CInternetSession session;
M_out + = "Connecting finger address" + host + "/r/n ";
UpdateData (FALSE );
CGopherConnection * connection = NULL;
Try
{
Connection = session. GetGopherConnection (host, NULL, NULL, 79 );
}
Catch (CInternetException * pEx)
{
Connection = NULL;
PEx-> Delete ();
}
If (connection)
{
M_out + = "established link. /R/n ";
CGopherLocator locator = connection-> CreateLocator (NULL, NULL, GOPHER_TYPE_TEXT_FILE );
CGopherFile * file = NULL;
Try
{
File = connection-> OpenFile (locator );
}
Catch (CInternetException * pEx)
{
File = NULL;
PEx-> Delete ();
}
If (file)
{
CString line;
For (int I = 0; I <20 & file-> ReadString (line); I ++)
{
M_out + = line + "/r/n ";
}
File-> Close ();
Delete file;
}
Else
{
M_out + = "finger query failed. /R/n ";
}
Connection-> Close ();
Delete connection;
}
Else
{
M_out + = "no finger host is found at this address. /R/n ";
}
M_out + = "------------------------------------------------------/r/n ";
UpdateData (FALSE );
}
In this function, the statement connection = session. GetGopherConnection (host, NULL, NULL, 79) is used to create a finger link. Then, we created a Gopher location of the text file type to operate on the information returned by the server: CGopherLocator locator = connection-> CreateLocator (NULL, NULL, GOPHER_TYPE_TEXT_FILE );. Use the Gopher location to open the file and use a for loop to read the first 20 lines of the file, and then display it.

Add the following line to the end of the OnQuery () function: TryFinger (m_host );. Compile the program and enter the address whitehouse.gov. The program will return the server's e-mail address. The returned information shows that for security reasons, other finger services on the server have been canceled. If the entered URL does not provide the finger service, the program will have a long delay. A message box pops up to notify the user that the link has timed out. Click OK.

6. Use the gopher protocol to send whois queries
Another protocol can also provide URL-related information. It is also an old protocol. MFC does not directly support it. This is the whois protocol. On the internet, only a few servers provide the whois service. The whois service creates a domain name database on the internet. If a whois query is performed on a domain name, the server returns the actual name, address, phone number, and other information of the organization or individual that owns the domain. An international domain name registrar owns a whois server. For example, all domain names ending with. com are registered in an institution called InterNIC. This institution owns a whois server called rs.internic.net. Like the finger protocol, the whois protocol is a simple protocol that uses Port 43. If a string containing a domain name is sent to Port 43 of the whois server, then the whois server will return the information of the domain owner. Add a member function void TryWhois (CString host) to the CQueryDlg class as follows:

Void cquerydlg: trywhois (cstring host)
{
Cinternetsession session;
M_out + = "connecting to whois address" + host + "/R/N ";
Updatedata (false );
Cgopherconnection * connection = NULL;
Try
{
Connection = session. getgopherconnection ("rs.internic.net", null, null, 43 );
}
Catch (cinternetexception * PEX)
{
Connection = NULL;
Pex-> Delete ();
}
If (connection)
{
M_out + = "established link. /R/N ";
Cgopherlocator locator = connection-> createlocator (null, host, gopher_type_text_file );
Cgopherfile * file = NULL;
Try
{
File = connection-> OpenFile (locator );
}
Catch (CInternetException * pEx)
{
File = NULL;
PEx-> Delete ();
}
If (file)
{
CString line;
For (int I = 0; I <20 & file-> ReadString (line); I ++)
{
M_out + = line + "/r/n ";
}
File-> Close ();
Delete file;
}
Else
{
M_out + = "Whois query failed. /R/n ";
}
Connection-> Close ();
Delete connection;
}
Else
{
M_out + = "Whois query failed. /R/n ";
}
M_out + = "------------------------------------------------------/r/n ";
UpdateData (FALSE );
}

In this function, the connection = session. GetGopherConnection ("rs.internic.net", NULL, NULL, 43) Statement links the program to the whois server rs.internic.net. Then, we create a gopher location to query the user input domain: CGopherLocator locator = connection-> CreateLocator (NULL, host, GOPHER_TYPE_TEXT_FILE); because the link domain is rs.internic.net, this function can only end. com domain. You can expand the program to other related whois servers to query other types of domains.

Add the following line to the end of the OnQuery () function: TryFinger (m_host );. Re-compile the program. Now we can perform whois query on the domain ending with. com.

So far, this program has all ended. Of course, interested readers can further expand it to complete more functions. The WinInet class can be expanded to access the e-mail and news services through specific ports. In addition, you can link to some famous network search engines and submit the query to enable the program to search. It all depends on your creativity.
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.