首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > Visual C++ > 使用WinInet类进行Internet编程
【标  题】:使用WinInet类进行Internet编程
【关键字】:编程,net,in,Win,Internet,In,WinInet,WinInet,Internet
【来  源】:网络

使用WinInet类进行Internet编程

本编辑框用于向用户显示输出结果。

2、增加另一个编辑框,ID标识符为IDC_EDIT2,选中Mutiline和Want return属性。这个编辑框用于接受用户输入网址。

3、在对话框上布置5个按钮,分别用来实现HTTP、FTP、GOPHER、FINGER和WHOIS查询。ID标识符分别为IDC_BUTTON_HTTP、IDC_BUTTON_FTP、IDC_BUTTON_GOPHER、IDC_BUTTON_FINGER、IDC_BUTTON_WHOIS。

下面,我们开始给控件附加变量和代码,以完成程序功能。首先,我们来看如何使用HTTP协议进行查询。

在编写实际进行查询的代码前,应给两个编辑框附加变量,以实现输入和输出的目的。我们使用classwizard,给编辑框IDC_EDIT1附加变量m_out,给编辑框IDC_EDIT2附加变量m_host。它们都应为Cstring类型的变量。

下面,我们给对话框类CQueryDlg添加一个函数,它用于实现HTTP查询。函数原形为:

void TryURL(Cstring URL);

其实现代码为:

void CQueryDlg::TryURL(Cstring URL)

{

CInternetSession session;

m_out+="正在链接"+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+="已建立链接。\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+="本地址没有发现http主机\r\n";

}

m_out+="------------------------------------------------------\r\n";

UpdateData(FALSE);

 

}

这个函数是如何实现HTTP链接的呢,我们分析如下:

首先,建立一个internet会话,这要定义一个CInternetSession的对象。其构造函数的原形如下:

CInternetSession( LPCTSTR pstrAgent = NULL, DWORD dwContext = 1, DWORD dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG, LPCTSTR pstrProxyName = NULL, LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0 );

这个函数需要定义很多参数,但是,本程序都使用缺省值,即“=”号后的值。CInternetSession构造函数参数说明如下:

LPCTSTR pstrAgent-应用程序名,如果为NULL,它将替你填入你在AppWizard中给定的程序名。

DWORD dwContext-本操作的设备关联符定义。

DWORD dwAccessType-访问类型,为以下参数之一,INTERNET_OPEN_TYPE_PRECONFIG (default), INTERNET_OPEN_TYPE_DIRECT, 或 INTERNET_OPEN_TYPE_PROXY

LPCTSTR pstrProxyName-如访问类型为INTERNET_OPEN_TYPE_PROXY,则给该参数赋予协议名称。

LPCTSTR pstrProxyBypass-如访问类型为INTERNET_OPEN_TYPE_PROXY,则该参数为不通过协议服务器而直接链接的一系列地址。

DWORD dwFlags-可为以下参数,INTERNET_FLAG_DON'T_CACHE, INTERNET_FLAG_ASYNC, 和INTERNET_FLAG_OFFLINE.

dwAccessType值缺省时将使用系统注册簿定义的值。显然,程序允许使用者定义访问类型将比由程序内部直接定义要好。因此,要正确使用本程序,必需先在windows系统中定义好网络访问类型,步骤如下:

1、双击桌面上“my computer"图标。

2、点击“contyol panel".

3、点击“internet ”。

4、在随后弹出的对话框中,选“connection"栏,然后填写网络连接属性。如果你是拨号上网,选中“dial”选择项,并填写相关属性。如果你是通过proxy服务器上网,选中“proxy”选项,点击“setting”按钮,设置proxy服务器地址和端口号。如果你是直接连入internet,应使所有的选项均为非选中状态。

本程序在构造CInternetSession对象时使用缺省值,因此,构造函数将不带任何参数。如下所示:

CInternetSession session;

在构造对象session后,我们需写两行程序作一些输出,表示程序已开始工作。

m_out+="正在链接"+URL+"\r\n";

UpdateData(FALSE);

接下来我们使用session对象的成员函数OpenURL()来打开一个URL资源。该函数返回一个文件的指针,文件类型为以下四种之一:

file:// 如果访问的是本地机器,函数返回一个CStudioFile类对象的指针。

ftp:// 如果访问的是一ftp地址,函数返回一个CInternetFile类对象的指针。

gopher:// 如果访问的是一gopher地址,函数返回一个CGopherFile类对象的指针。

http:// 如果访问的是一http地址,函数返回一个CHttpFile类对象的指针。

本程序用于访问远程机器,因此,函数不会返回一个file://类型的本地文件。而CGopherFile和CHttpFile均派生自CInternetFile,所以将该函数返回值赋给CInternetFile类的指针是安全的。当OpenURL()不能正常打开URL资源时,该函数将会抛出一个异常(exception),从而导致程序运行时错误。由于本程序用于探查未知的网址,该网址可能不提供相应服务或根本不存在,因此OpenURL()有时可能不会正常运行。为了避免程序异常终止,我们需使用try-catch结构来处理异常。本段程序代码如下:

CInternetFile* file=NULL;

try

{

file=(CInternetFile*)session.OpenURL(URL);

}

catch(CInternetException* pEx)

{

file=NULL;//如果发生运行时错误,给file赋空值,程序将继续运行

pEx->Delete();

}

通过以上代码,程序将使用用户指定的地址来试图打开Http网址,如果失败,返回的文件为空,程序将继续运行,尝试用其它协议打开网址。随后,无论网址是否成功打开,我们都应作相应输出以提示用户。如果成功,我们用一个for循环读出返回文件的头20句并输出,如果失败,也要给出相应的提示。程序如下:

if(file) file://判定链接是否成功

{

m_out+="已建立链接。\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+="本地址没有发现http主机\r\n";

}

m_out+="------------------------------------------------------\r\n";

UpdateData(FALSE);

用于查询的函数编写完后,我们还要给按钮的单击事件增加代码,以便按钮按下时,程序开始查询。给按钮IDC_BUTTON_HTTP按钮增加BN_CLICKEDvoid 消息的代码如下:CQueryDlg::OnQueryHttp()

{

const Cstring http = "http://";

UpdateData(TRUE);

m_out = "";

UpdateData(FALSE);

TryURL(http + m_host);

TryURL(http + "www." + m_host);

}

这段代码中,UpdateData(TRUE)的调用将给m_host赋予用户定义的值。UpdateData(FALSE)语句将清空输出编辑框变量m_out的内容。接下来调用两次TryURL(),例如说,当用户输入yahoo.com,程序将首先试一试http://yahoo.com,然后试一试http://www.yahoo.com。好了,我们现在可以编译程序并执行,输入yahoo.com,程序将连接到internet,并输出yahoo主页的头20行。

实现FTP链接

下面,我们来探讨如何实现FTP链接。首先给对话框类增加一个实现链接的函数TryFTP:

void CQueryDlg::TryFTP(Cstring host)

{

CInternetSession session;

m_out += "正在链接FTP地址 " + host + "\r\n";

UpdateData(FALSE);

CFtpConnection* connection = NULL;

try

{

connection = session.GetFtpConnection(host);

}

catch (CInternetException* pEx)

{

connection = NULL;

pEx->Delete();

}

if (connection)

{

m_out += "已建立链接。 \r\n";

Cstring line;

connection->GetCurrentDirectory(line);

m_out += "缺省目录为 " + line + "\r\n";

connection->Close();

delete connection;

}

else

{

m_out += "本地址没有发现ftp主机 。\r\n";

 

}

m_out += "------------------------------------------------------\r\n";

UpdateData(FALSE);

}

本函数和TryURL()很相似,不过,它不使用OpenURL()来打开一个文件,而是用GetFtpConnection()来与ftp服务器建立链接。如果链接成功,将使用GetCurrentDirectory()来得到服务器的缺省目录。

大多数ftp地址前有ftp.的前缀,但一些老的地址没有此前缀。现在,给IDC_BUTTON_FTP链接单击消息的处理函数,并编写如下:

void CQueryDlg::OnButtonFtp()

{

UpdateData(TRUE);

m_out = "";

UpdateData(FALSE);

TryFTP(m_host);

TryFTP("ftp." + m_host);

}

现在我们已完成了FPT连接的实现代码。重新编译程序并运行,键入ftp.microsoft.com。可以发现,在ftp.microsoft.com处提供ftp服务。但是你必须有一点耐性,因为在开始查询到出结果将有较长一段时间,因为程序等结果全部探查到后再一次显示,但实际上现在的商业internet程序都是实时显示的。如果我们希望结果实时地显示,必需使用异步套接字(asynchronous sockets)或多线程编程。

实现Gopher查询

GOPHER是一种基于文本的协议,它和WWW相似,可以通过点击文字内容,实现网络内的链接和浏览。但是,GOPHER是通过逐级文字菜单来组织链接和内容的,它不象WWW那样有丰富的多媒体页面。要实现GOPHER查询,我们应给CQueryDlg类增加另一个成员函数void TryGopher(Cstring host)。如果查询成功,该函数将返回查询地址的第一个Gopher位置(locator)。位置是gopher协议的概念,任何gopher客户程序必需先得到一个gopher位置,然后才能进行相应的gopher操作。TryGopher()函数如下:

void CQueryDlg::TryGopher(Cstring host)

{

CInternetSession session;

m_out += "正在链接gopher地址 " + host + "\r\n";

UpdateData(FALSE);

CGopherConnection* connection = NULL;

try

{

connection = session.GetGopherConnection(host);

}

catch (CInternetException* pEx)

{

connection = NULL;

pEx->Delete();

}

if (connection)

{

m_out += "已建立链接。 \r\n";

Cstring line;

CGopherLocator locator = connection->CreateLocator(NULL, NULL, GOPHER_TYPE_DIRECTORY);

line = locator;

m_out += "第一个Gopher位置是" + line + "\r\n";

connection->Close();

delete connection;

}

else

{

m_out += "本地址没有发现gopher主机 。 \r\n";

}

m_out += "------------------------------------------------------\r\n";

UpdateData(FALSE);

}

本函数和前两个函数大致相似,在通过调用connection = session.GetGopher Connection(host);来建立Gopher链接后,通过语句CGopherLocator locator = connection-> CreateLocator(NULL, NULL, GOPHER_TYPE_DIRECTORY);来建立一个Gopher位置(locator),函数CreateLocator()有多个版本,现在我们使用的是其含三个参数的版本。其原形为CGopherLocator CreateLocator( LPCTSTR pstrDisplayString, LPCTSTR pstrSelectorString, DWORD dwGopherType );。其中参数pstrDisplayString指明要查询的服务器上的具体文件或目录名,如果它为NULL,则返回服务器缺省目录名;参数pstrSelectorString是发送给服务器的字符命令,以便检索某个项目,它可设为空;参数dwGopherType指明Gopher访问类型,本例中定义为GOPHER_TYPE_DIRECTORY,指明要访问的是目录。它的其它可取值请参考VC++5.0文档。Gopher位置(locator)建立后,我们把它强制转换为Cstring类型,并把该位置显示出来。

现在,给IDC_BUTTON_GOPHER链接单击消息的处理函数,并编写如下:

void CQueryDlg::OnButtonGopher()

{

UpdateData(TRUE);

m_out = "";

UpdateData(FALSE);

TryGopher(m_host);

TryGopher("gopher." + m_host); // TODO: Add your control notification handler code here

 

}

重新编译程序,输入地址harvard.edu,程序将会探查出它是一个Gopher地址,并显示出第一个Gopher位置。

如何建立FINGER查询

Finger协议的作用是给你提供一个网址的具体情况,它是Internet上最古老的协议之一。在一个Finger服务器上,你可以查询它的某一个用户或整个网址的情况。当然,这对网络的安全是不利的,实际上,有经验的黑客们在攻击一个未知网络时,第一步就是向它发送Finger和Whois查询,这也是黑客网址上的黑客教程中建议的步骤。为了安全,许多网络服务器不提供Finger服务,然而,当它接受到Finger查询请求时,仍然会返回一些其它的有用信息。

在MFC和WIN32 API中,没有提供直接实现Finger查询的函数,但是,我们仍有变通的办法来实现它。所有的internet链接都需要一个宿主名和端口号,所有的著名的服务都有其特定的端口号,例如:http服务使用远程宿主机上的端口80,ftp服务使用端口21,gopher服务使用端口70。对于finger服务来说,它使用端口79。finger是一种简单的协议,如果你向远程宿主机的端口79发送字符串,finger服务器在端口79侦听到后,将会发送出一个finger回答。如果你发送的字符串仅仅包含\r\n,服务器通常将会把本服务器上所有用户的列表及相关信息(如用户真实姓名等)做为应答返回。因此,如果我们不使用缺省的端口70,而是使用端口79来建立gopher链接,我们就能发出finger查询。给CQueryDlg类增加一个成员函数void TryFinger(Cstring host)如下:

void CQueryDlg::TryFinger(Cstring host)

{

CInternetSession session;

m_out += "正在链接finger地址 " + 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 += "已建立链接。 \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查询失败。\r\n";

}

connection->Close();

delete connection;

}

else

{

m_out += "本地址没有发现finger主机 。 \r\n";

}

m_out += "------------------------------------------------------\r\n";

UpdateData(FALSE);

}

本函数中,语句connection = session.GetGopherConnection(host,NULL,NULL,79);用于建立finger链接。随后,我们创立一个文本文件类型的Gopher位置用来操作服务器返回的信息:CGopherLocator locator = connection->CreateLocator(NULL, NULL, GOPHER_TYPE_TEXT_FILE);。使用该Gopher位置打开文件并使用一个for循环来读出该文件的头20行,随后将它显示出来。

现在,给IDC_BUTTON_FINGER按钮链接单击消息的处理函数,并编写如下:

void CQueryDlg::OnButtonFinger()

{

UpdateData(TRUE);

m_out = "";

UpdateData(FALSE);

TryFinger(m_host);

// TODO: Add your control notification handler code here

}

编译程序,输入地址whitehouse.gov,程序将会返回该服务器的e-mail地址,从返回的信息可知,出于安全考虑,该服务器的其它finger服务已被取消了。如果你输入的网址没有提供finger服务,程序将有较长一段时间没有反应,最后弹出一个消息框,通知用户链接出现超时错误,单击ok按钮即可。

实现WHOIS查询

还有一个协议也能提供网址的相关信息,它也是一种古老的协议,MFC并不直接支持它,这就是whois协议。在整个internet上,只有少数服务器提供whois服务。whois服务建立了internet上的域名数据库,如果对某个域名进行whois查询,服务器将会返回拥有该域的机构或个人的实际姓名、地址、电话号码等信息。国际上的域名注册机构拥有whois服务器,例如,域名结尾为.com的域都在一个称为InterNIC的机构中注册,该机构拥有一个whois服务器称为rs.internic.net。whois协议和finger协议一样,是一种简单的协议,它使用端口43,如果向whois服务器的端口43发送包含域名的字符串,则whois服务器将会返回该域拥有者的情况。给CQueryDlg类增加一个成员函数void TryWhois(Cstring host)如下:

void CQueryDlg::TryWhois(Cstring host)

{

CInternetSession session;

m_out += "正在链接Whois地址 " + 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 += "已建立链接。 \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查询失败。\r\n";

}

connection->Close();

delete connection;

}

else

{

m_out += "Whois查询失败。\r\n";

}

m_out += "------------------------------------------------------\r\n";

UpdateData(FALSE);

}

在本函数中,语句connection = session.GetGopherConnection("rs.internic.net",NULL, NULL,43);使程序链接到了whois服务器rs.internic.net。随后,我们建立一个gopher位置来查询用户输入的域:CGopherLocator locator = connection->CreateLocator(NULL, host, GOPHER_TYPE_TEXT_FILE);由于链接的域为rs.internic.net,所以,本函数只能查询结尾为.com的域。读者可以对本段程序进行扩充,链接到其它相关whois服务器,以查询其它类型的域。

现在,给IDC_BUTTON_WHOIS按钮链接单击消息的处理函数,并编写如下:

void CQueryDlg::OnButtonWhois()

{

UpdateData(TRUE);

m_out = "";

UpdateData(FALSE);

TryWhois(m_host);// TODO: Add your control notification handler code here

 

}

重新编译程序,现在,我们可以对结尾为.com的域进行whois查询了。

至此,本程序已全部结束。当然,有兴趣的读者可以对它进一步扩充,以完成更多的功能。可以对WinInet类进行一些小小的扩充,以便能通过特定的端口访问e-mail和news服务。此外,也可以链接到一些著名的网络搜索引擎上并提交查询,使程序具有搜索功能。这一切,就取决于你的创造力了。

使用DDE使应用程序可以添加新的程序组:【上一篇】
用VC++5.0制作DLL经验一二:【下一篇】
【相关文章】
没有相关文章
【随机文章】
  • 痛斥一些无聊做病毒的人
  • 鸟哥下的DNS服务器的配制
  • 冒泡法字符串排序
  • 解除网虫的心病 用VB做定时断线程序
  • VLAN学习笔记大全(5):IIEEE802.1Q与ISL
  • C#中的cookie编程
  • RedHat Linux 9时区配置
  • MS SQL Server2k字符串分拆与合并处理代码
  • 如何做一个互联网络SOHO族!
  • re: 一种数据库结构体模式讨论
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.