Writing Internet query programs using MFC Duranong In VC 5.0, the MFC's Wininet class wrapped the associated Win32 API function for Internet client program programming. Thus, there is no need to understand the details of Winsock or TCP / IP, you can have an Internet client program. In this article, we will explore how to use the Wininet class to write an Internet query program, which is called "Pathfinder". The program can use a variety of protocol to query the network, including ancient Finger and WHOIS. As the name suggests, "Pathfinder" is used to explore the situation of an Internet server and see which services it can provide. For example, you know that someone's E-mail address, assuming is wang@eop.com, we can pass the program, try to establish a link to EOP.com with a variety of ways, and then use WWW queries to this specified domain , FTP query, gopher query, finger query and WHOIS query. According to the result of the return, it can be determined which services can provide. Also, if you want to give your own server, you can also know if this domain name is already adopted. First, implement the user interface of the program interface of this program will be implemented based on the dialog. The steps to establish the interface are as follows: In Developer Studio, 1, select File-New ..., highlight MFC AppWizard (exe), name Query in the Project Name column, click OK. 2, in STEP-1, click Dialog Based, select ENGLISH as a resource language. Click Next. 3. In STEP-2, cancel the select tag of ActiveX Controls. Don't choose Windows Socket (the program is not directly called the socket function), type "Pathfinder" in the dialog 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, we are ready to write the core part of the handwritten program. AppWizard has established an empty dialog that we will start working on it. Below, the editorial dialog box: Select Resource View, Double-click IDD-Query-Dialogs, and edit the dialog box below: 1, change the OK button to "Query Host", right-click this button, select Properties, The ID name of the button is changed to ID-Query. 2, change the CANCEL button to "End Query". 3, delete static text such as To do. 4, increase the dialog to 300 pixels wide 5, add an edit box at the top of the dialog box, the resource ID is named IDC-Host, and the edit box is stretched to the widest. 6, add a label named "Address Name" to the edit box. 7, pull the dialog box to 150 pixels. 8, add another edit box at the bottom of the dialog, ID named IDC-OUT, stretch it to the remaining space of the dialog box as much as possible, fill the remaining space of the dialog. 9. Increase the characteristics such as Multi-Line, Horizontal Scroll, Vertical Scroll, Border, Read-Only. When the user clicks the "Query Host" button, the program will query the URL using various methods. 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 and the host name will be accepted by this class. 3, highlight ID-Query, highlight BN-Clicked in the right list column. 4, press the Add FUCTION button to add a function.
5, the name of the Class Wizard is ONOK, change it to ONQUERY, click OK 6, click the member variable bar, ready to connect the EDIT to the variable 7 of the dialog class, highlight IDC-Host and click AddDD Variable. The CSTRING member variable that will be connected to the dialog class, named m_host 8, similar to the above steps, link IDC-OUT to the cstring variable m_out click OK to close ClassWizard, the rest is written CQuerydlg :: ONQUERY () function It will use the m_host value to query and output the result to the m_out variable. Second, write the code, perform HTTP query query an Internet address, first try to establish an HTTP link. This is because a large number of addresses contain a web page. The easiest way to use the HTTP to create a link is to use the WinlNet class CinternetSession and call its member function OpenURL (). This function will return a file, we display a few lines of text of the file in m_out. First, add the following lines at querydlg.cpp: # include'afxinet.h 'This will define the code that accesses the WinLnet class. Since this program will access a large number of URLs, add a function called TRYURL in CQueryDLG, which contains a parameter of a CString class, named URL, and the return value is Void. Right click on the CQueryDLG class and select Add Member Function .... Add function tryURL (), define it as a protected type. This new function will call from CQuerydlg :: ONQUERY (). Add the following code in ONQUERY (): void CQuerydlg :: ONQUERY () {const cstring http = "http: //"; Updatedata (TRUE); m_out = ""; Updatedata (false); tryurl (http m_host); Tryurl (http "www." M_host);} Updatedata (TRUE) call will give m_host to user-defined values. The Updatedata (false) statement will clear the contents of the output edit box variable m_out. Next, Tryurl (), for example, when the user enters Microsoft.com, the program will first try a try http://microsoft.com, then try it http://www.microsoft.com. The following is the code of TRYURL. Void CQuerydlg :: Tryurl (CSTRING URL) {CinternetSession session; m_out = "Link" 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 = "has established links.
/ r / n "; cstract line; for (int i = 0; i <20 && file-> readstring (line); i ) {m_out = line " / r / n ";} file-> close (); delete file; } else {m_out = "This address did not find HTTP host / r / n";} m_out = "---------------------------- ------------------------ / r / n "; Updatedata (false);} Und, we analyze the above code. First establish an internet area, which to define the object CInternetSession its prototype constructor is as follows:. CInternetSession (LPCTSTR pstrAgent = NULL, DWORD dwContext = 1, DWORD dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG, LPCTSTR pstrProxyName = NULL, LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0); This requires a lot of parameters, but this program uses the default value, ie the value after the "=" number. ThecinternetSession constructor parameter is as follows: lpctstr pstragent- Application name, if null, it will replace it you you fill AppWizard given program name. DWORD dwContext- device associated character of this operation is defined. DWORD dwAccessType- access type, one of the following parameters, INTERNET_OPEN_TYPE_PRECONFIG (default), INTERNET_OPEN_TYPE_DIRECT, such as access or INTERNET_OPEN_TYPE_PROXY LPCTSTR pstrProxyName- type INTERNET_OPEN_TYPE_PROXY, then to the parameter name given to the agreement. LPCTSTR pstrProxyBypass- such as access type INTERNET_OPEN_TYPE_PROXY, the argument is a series of addresses are not linked directly through the protocol server. DWORD dwFlags- available for the following parameters, INTERNET_FLAG_DONT_CACHE, INTERNET_FLAG_A Sync, and Internet_flag_offline. DwaccessType value will use the value defined by the system registration book when defined. Obviously, the program allows the user to define the access type will be better than direct definitions directly within the program. Therefore, to properly use this program, you must first define the type of network access in the Windows system, steps below: 1. Double-click the "My Computer" icon on your desktop. 2, click "Contyol Panel". 3, click "Internet". 4. In the dialog box that will be ejected, select the "Connection" column and fill in the network connection properties. If you are dial-up, select the "Dial" selection, and fill in the relevant properties. If you are using the Proxy server, select the "Proxy" option, click the "Setting" button, set the Proxy server address and port number. If you are directly connected to the Internet, all options should be made non-selective. This program uses the default value when constructing the CinternetSession object, so the constructor will bring any parameters.
As shown below: CinternetSession session; After constructing the SESSION, we need to write two lines to make some output, indicating that the program has started working. m_out = "Link" URL "/ R / N"; Updatedata (false); Next, we use the members of the Session object OpenURL () to open a URL resource. This function returns a file's pointer, the file type is one of the following: file: // If access is the local machine, the function returns a pointer to a CSTUDIOFILE class object. FTP: // If the access is an FTP address, the function returns a pointer to a CinternetFile class object. Gopher: // If you are accessing a gopher address, the function returns a pointer to a CGOPHERFILE class object. http: // If the access is an HTTP address, the function returns a pointer to a chttpfile class object. This program is used to access the remote machine, so the function will not return a file: // type of local file. CGOPHERFILE and Chttpfile are derived from CinternetFile, so the pointer to the CINTERNETFILE class is secure. When OpenURL () does not open the URL resource normally, the function will throw an exception, resulting in an error when the program is running. Since this program is used to explore unknown URLs, the website may not provide the corresponding service or not, OpenURL () may not run normally. In order to avoid the termination of the program, we need to use the try-catch structure to handle exceptions. This section code code is as follows: CinternetFile * file = null; try {file = (cinternetFile *) session.openurl (URL);} catch (cinternetException * pex) {file = null; // If a runtime error occurs, give File assignment Null value, the program will continue to run the pex-> delete ();} The program will use the user to try to open the HTTP URL using the user, if it fails, the returned file is empty, the program will continue to run, try other protocols Open the URL. Subsequently, we should make the corresponding output to prompt the user regardless of whether the website is successful. If successful, we read the header 20 sentences that return the file with a FOR loop and output it, if it fails, the corresponding prompt is given. The procedure is as follows: if (file) // determines whether the link is successful {m_out = "established link ./r/N"; cstract line; for (int i = 0; i <20 && file-> readstring (line); i ) { m_out = line "/ r / n";} file-> close (); delete file;} else {m_out = "This address did not find HTTP host / r / n";} m_out = "------- ---------------------------------------------- / r / n "; Updatedata (false); Now we can compile the program and run, type the address Microsof.com and query, the output information indicates that the program is at http://www.microsoft.com The WWW page was found and the head 20 row of the HTML file of the home page was output.
Third, the implementation of the FTP query is now we continue to program, to explore whether the URL entered by the user provides FTP services. FTP is a file transfer protocol on the Internet, primarily used to transfer files between servers and clients. Re-calling tryurl () is not possible, because tryurl () assumes that the URL points to a file, and an FTP URL points to a series of files. You must rewrite a function, add the previous step, add another member function void tryftp (CString Host) to the CQueryDLG class. If the pricing URL provides an FTP service, the function will find the FTP default directory and display it. The code is as follows: void CQuerydlg :: tryftp (cstring host) {cinternetSession session; m_out = "Link FTP address" host "/ r / n"; updatedata (false); cftpConnection * connection = null; try {connect = Session.GetftPConnection (Host); Catch (CinternetException * PEX) {connection = null; pex-> delete ();} If (connection) {m_out = "has been established. / r / n"; CSTRING LINE; Connection -> getCurrentDirectory (line); m_out = "Default directory is" line "/ r / n"; connection-> close (); delete connection;} else {m_out = "This address did not find FTP hosts. / r / n ";} m_out =" ------------------------------------- ------------- / r / n "; Updatedata (false);} This function is very similar, however, it does not use OpenURL () to open a file, and It is used to establish a link with the FTP server with getftpConnection (). If the link is successful, getCurrentDirectory () will be used to get the default directory of the server. Most FTP addresses have ftp. The prefix, 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 ("ftp." M_host; recompilation and run, you can find, at ftp.microsoft.com Provide FTP services. There will be some delays in the start of the query, because the results of the program, all probes, once again, if we want the results display in real time, you must use asynchronous sockets or multi-threaded programming. Fourth, Gopher query implementation Gopher is a text-based protocol, which is similar to WWW, which can enable links and browsses within the network by clicking on text content. However, Gopher is organized by the step-by-step text menu, which is not like WWW has a rich multimedia page. To implement a gopher query, we should add another member function void trygopher (CString Host) to the CQueryDLG class. If the query is successful, the function will return the first gopher location (Locator) of the query address.
The location is the concept of the Gopher protocol, and any gopher client must first get a gopher location before you can perform the corresponding gopher operation. The trygopher () function is as follows: void CQuerydlg :: trygopher (cstring host) {cinternetSession session; m_out = "Link 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 = "has established links. / r / n"; cstring Line; cgopherlocator locator = connection-> CreateLocator (null, null, gopher_type_directory); line = locator; m_out = "The first gopher position is" line "/ r / n"; connection-> close (); delete CONNECTION;} else {m_out = "This address did not find Gopher host. / r / n";} m_out = "----------------------- ----------------------------- / r / n "; Updatedata (false);} This function and the first two functions substantially similar, by calling connection = session.GetGopher Connection (host); Gopher after establishing the link, the statement by CGopherLocator locator = connection-> CreateLocator (NULL, NULL, GOPHER_TYPE_DIRECTORY); Gopher to establish a position (Locator), function CreateLocator () There are multiple versions, now we use the version containing three parameters. Its prototype is CGOPHERLOCATOR CREATELOCATOR (LPCTSTSTR PSTRSPLAYSTRING, DWORD DWGOPHERTYPE) ;. The parameter PSTRDISPLAYSTRING indicates the specific file or directory name on the server you want to query. If it is null, return the server default directory name; parameter pstrselectorstring is a character command to send to the server to retrieve a project, it can be set to empty The parameter dwgophertype indicates the GOPHER access type. In this example, it is defined as gopher_type_directory, indicating that the directory to access is. Other values of it refers to the VC 5.0 documentation. After the GoCator is established, we force it to convert it into a CString type and display this location.
Add the following line: trygopher ("gopher." M_host; recompilated program, enter the address harvard.edu, the program will explore it is a gopher address and displayed The first Gopher position. 5. Use gopher to implement the Finger Query Finger protocol to provide you with a specific situation of an URL, which is one of the oldest agreements on the Internet. On a finger server, you can query a user of its user or the entire URL. Of course, this is unfavorable. In fact, when an experienced hacker is attacking an unknown network, the first step is to send Finger and WHOIS inquiry, which is also a hacker tutorial on the hacker website. . For security, many web servers do not provide a Finger service, however, some other useful information will still be returned when it accepts the finger query request. In the MFC and Win32 API, there is no function to implement the finger query directly, but we still have a variety of ways to implement it. All Internet links require a host name and port number, all of which have their specific port numbers, such as the HTTP service uses port 80 on the remote host, the FTP service uses port 21, and the GOPHER service uses port 70. For Finger services, it uses port 79. Finger is a simple protocol if you send a string to the port 79 of the remote host, and the Finger server will send a finger answer after the port 79 is listened. If you send a string contains only / r / n, the server will usually return to the list and related information (such as user real names, etc.) on this server. Therefore, if we do not use the default port 70, but use port 79 to create a gopher link, we can issue a finger query. Add a member function void tryfinger (CString host) to the CQueryDLG class: void CQuerydlg :: tryfinger (cstring host) {cinternetSession session; m_out = "Link 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 = "has been established.
/ 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 =" This address did not find the finger host. / r / n ";} m_out =" ------------------------------------- ------------- / r / n "; Updatedata (false);} This function, statement connection = session.getgopherConnection (Host, NULL, NULL, 79); for establishing Finger link. Subsequently, we create a gopher location of a text file type to operate the information returned by the server: cgopherlocator locator = connection-> CreateLocator (null, null, gopher_type_text_file); use the gopher position to open the file and use a for loop After reading the header 20 line of the file, then display it. Add the following line: tryfinger (m_host); Compiler, enter the address Whitehouse.gov, the program will return the server E- Mail address, can be known from the return information, other Finger services of the server have been canceled if the URL you entered does not provide a finger service, the program will have a longer period of time, and finally pop up a message box. Notifying the user links showing timeout errors, click the OK button. Sixth, use the Gopher protocol to send the WHOIS query and one protocol can also provide the website related information, it is an ancient protocol, MFC does not directly support it, This is the WHOIS protocol. On the entire Internet, only a few servers provide the WHOIS service. The WHOIS service establishes the domain name database on the Internet. If you perform WHOIS queries for a domain name, the server will return the actual name of the domain or individual. , Address, telephone number and other information. International domain name registration agencies have a WHOIS server, for example, the domain of the domain name is registered in a region called InterniC, which has a WHOIS server called RS.ISTERNIC. The NET.WHOIS protocol is the same as the Finger protocol, which is a simple protocol that uses port 43, and if the domain contains a domain name, the WHOIS server will return the domain owner.
Add a member function void trywhois (cstring host) to the CQueryDLG class: void CQuerydlg :: trywhois (cstring host) {cinternetSession session; m_out = "Link 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 = "link established / 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) {cstract 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 ./n";} connection-> close (); DELETE Connection;} else {m_out = "WHOIS query failed ./R/N";} m_out = "------------------------- --------------------------- / r / n "; Updatedata (false);} In this function, statement connection = sessio N.GETGOPHERCONNECTION ("RS.Nternic.Net", NULL, NULL, 43); make the program chain to the Whois server rs.internic.net. Subsequently, we build a gopher location to query the domain entered by the user: cgopherlocator locator = connection-> CreateLocator (NULL, HOST, GOPHER_TYPE_TEXT_FILE); This function can only query the end because the link is rsinternic.NET, so this function can only query the end. COM domain. The reader can expand this segment, link to other related WHOIS servers to query other types of domains. Add the following line at the end of the onquery () function: Tryfinger (m_host) ;. Re-compile the program, now we can perform WHOIS for the .com's domain. At this point, this program has all ended. Of course, interested readers can further expand it to complete more features.