利用Win32的网络函数创建一个网络浏览器Word格式.docx
《利用Win32的网络函数创建一个网络浏览器Word格式.docx》由会员分享,可在线阅读,更多相关《利用Win32的网络函数创建一个网络浏览器Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
个过程种特定的网络部分,但它没有涉及与这个过程有关的用户接口问题或HTML文件的
显示或操作问题。
注意:
这篇文章是基于WININET.DLL一个相当早的版本。
很可能其中的参数名、标识名和
函数名发生了改变。
但是函数的范围和意图应该还是和这篇文章中描述的是一致的。
网络函数
最好的探讨Win32网络函数的方法是直接进入代码。
下面的代码是样本的代码,为了方便
阅读,错误处理部分已经被删除掉了。
HINTERNEThNet=:
:
InternetOpen("
MSDNSurfBear"
PRE_CONFIG_INTERNET_ACCESS,
NULL,
INTERNET_INVALID_PORT_NUMBER,
0);
HINTERNEThUrlFile=:
InternetOpenUrl(hNet,
"
0,
INTERNET_FLAG_RELOAD,
charbuffer[10*1024];
DWORDdwBytesRead=0;
BOOLbRead=:
InternetReadFile(hUrlFile,
buffer,
sizeof(buffer),
&
dwBytesRead);
InternetCloseHandle(hUrlFile);
InternetCloseHandle(hNet);
上面列举的代码包括四个网络函数:
InternetOpen、InternetOpenOrl、InternetReadFile和
InternetCloseHandle。
下面我们依次对这些函数进行分析。
InternetOpen
InternetOpen初始化WININET.DLL。
它在其他的Win32网络函数之前被调用。
InternetOpen(
//1LPCTSTRlpszCallerName
PRE_CONFIG_INTERNET_ACCESS,//2DWORDdwAccessType
//3LPCTSTRlpszProxyName
INTERNET_INVALID_PORT_NUMBER,//4INTERNET_PORTnProxyPort
0//5DWORDdwFlags
);
InternetOpen返回一个类型为HINTERNET的句柄。
其他的Win32网络函数把这个句柄当作
一个参数。
现在你不能把一个HINTERNET句柄用在类似于ReadFile之类的其他Win32函数
中。
但是随着MicrosoftWindows和MicrosoftWindowsNT网络支持的成熟,这一点在将
来不是不可能实现的。
当你已经结束使用Wein32网络函数时,你应该调用InternetCloseHandle释放InternetOpen
分配的资源。
使用Microsoft基础类(MFC)的应用程序将从文件的构造程序里象征性地调
用InternetOpen。
绝大多数应用程序都将在每一进程里调用InternetOpen。
InternetOpen的第一个参数lpszCallerName指定正在使用网络函数的应用程序。
当HTTP
协议使用时,这个名字将变成用户代理。
第二个参数dwAccessType指定访问类型。
在上面的例子里,PRE_CONFIG_INTERNET_ACCESS
访问类型指示Win32网络函数使用登记信息去发现一个服务器。
使用
PRE_CONFIG_INTERNET_ACCESS需要正确设定登记信息。
这里我耍了一个小花招并让网络开
发者替我登记注册。
如果你不想欺骗,你需要按图1所示设定登记信息。
在登记注册中,把AccessType设置为1,则意味着“直接入网”,把AccessType设置为2,
意味着“使用网关”。
把DisableServiceLocation设置为1,将让它使用一个已经命名的
服务器;
否则将找到一个使用注册信息和名字决议(RNR)应用程序接口的服务器,它是
Windows接口的一部分。
其他的访问类型包括以下几种:
LOCAL_INTERNET_ACCESS只连接到当地Internet网站。
例如,如果我使用SurfBear标志,
我就只能访问Microsoft整体的Internet网站。
CERN_PROXY_INTERNET_ACCESS使用一个CERN代理去访问web。
CERN代理是一个充当网关的
web服务器并且能向要使用代理的服务器发送HTTP请求。
GATEWAY_INTERNET_ACCESS允许连接到WorldWideWeb。
我可以用这个访问类型去访问web
上的任何站点。
GATEWAY_PROXY_INTERNET_ACCESS和CERN_PROXY_ACCESS访问类型要求第三个参数给
InternetOpen:
服务器名(lpszProxyName)。
PRE_CONFIG_INTERNET_ACCESS不要求服务
器名,因为他可以为服务器搜索寄存信息。
NProxyPort参数用在CERN_PROXY_INTERNET_ACCESS中用来指定使用的端口数。
INTERNET_INVALID_PORT_NUMBER相当于提供却省的端口数。
最后一个参数棗dwFlags,设置额外的选择。
你可以使用INTERNET_FLAG_ASYNC标志去
指示使用返回句句柄的将来的Internet函数将为回调函数发送状态信息,使用
InternetSetStatusCallback进行此项设置。
InternetOpenUrl
一旦你把Win32网络函数初始化了,你就可以使用其他网络函数。
下一个要调用的
Internet函数是InternetOpenUrl。
这个函数连接到一个网络服务器上并且最被从
服务器上读取数据。
InternetOpenUrl能对FTP,Gopher或HTTP协议起作用。
在这篇
文章中,我们只涉及HTTP协议。
InternetOpenUrl(
hNet,//1HINTERNEThInternetSession
//2LPCTSTRlpszUrl
NULL,//3LPCTSTRlpszHeaders
0,//4DWORDdwHeadersLength
INTERNET_FLAG_RELOAD,//5DWORDdwFlags
0//6DWORDdwContext
InternetOpenUrl也返回一个HINTERNET,它被传递给在这个URL(统一资源定位)上操作
的函数。
你应该使用InternetClose来关闭这个句柄的处理。
InternetOpenUrl的第一个参数hInternetSession是从InternetOpen返回的句柄。
第二
个参数lpszUrl是我们需要的资源的URL(统一资源定位)。
在上面的例子中,我们想得
到一个Microsoft的web主页。
下面两个参数lpszHeaders和HeaderLength用来向服务器
传送额外的信息。
使用这些参数要求具有正在使用的特定协议的知识。
DwFlag是一个可以用几种方式修改InternetOpenUrl行为的标志,InternetOpenUrl的行
为包括关闭、隐藏,使原始数据可用和用存在的连接取代开辟一个新的连接。
最后一个参数dwContext是一个DWORD上下文值。
如果有一个值已经被指定,它将被送到
状态回调函数。
如果这个值是0,信息将不会被送到状态回调函数。
InternetReadFile
你打开一个文件后,就要读它,所以下一个函数是InternetReadFile是符合逻辑的:
InternetReadFile(
hUrlFile,//1HINTERNEThFile
buffer,//2LPVOIDlpBuffer
sizeof(buffer),//3DWORDdwNumberOfBytesToRead
dwBytesRead//4LPDWORDlpdwNumberOfBytesRead
);
buffer[dwBytesRead]=0;
pEditCtrl->
SetWindowText(buffer);
InternetReadFile接收InternetOpenUrl返回的句柄。
它也对其他Win32网络函数,例如
FtpOpenFile,FopherOpenFile和HttpOpenRequest返回的句柄有影响。
剩下的InternetReadFile的三个参数也非常的明白直接。
Inbuffer是指向保留数据的缓冲
区的一个无返回值指针,dwNumberOfByteToRead以字节为单位指定缓冲区的尺寸。
最后一
个参数,lpdwNumberOfBytesRead是一个指向包含读入缓冲区字节数的变量的指针。
如果
返回值是TRUE,而且lpdwNumberOfBytesRead指向0,则文件已经读到了文件的末尾。
这个
行为与Win32Re3adFile的函数的行为是一致的。
一个真正的web浏览器将在InternetReadFile
上循环,不停地从Internet上读入数据块。
为了显示缓冲区,向缓冲区添加一个0并把它送到编辑器控制。
这样,InternetOpen、InternetOpenUrl和InternetReadFile一起创建了Internet浏览
器的基础。
他们使从Internet上读取文件就象从你的本地硬盘驱动器上读取文件一样容易。
HTTP函数
在一些例子中,InternetOpenUrl太普通了,所以你可能需要其他的Win32网络函数。
InternetOpenUrl相当与不同的FTP,GOPHER和HTTP函数的封皮。
当使用HTTP时,
InternetOpenUrl调用InternetConnect,HttpOpenRequest以及HttpSendRequest,
比如说我们想要在下载一个HTML页之前得到它的尺寸以便于我们在缓冲区中为其分
配适当的尺寸,HttpQueryInfo将得到web页的大小。
警告:
不是所有web页都支持得到页尺寸。
(例如:
和不
支持这个功能)另外,TCP/IP能传递的数据也比要求的要少。
所以,你的应用程序应该处理着
两种情况并且围绕InternetReadFile循环直到结果为TRUE同时*lpdwNumberOfBytesRead为0。
使用HttpOpenRequest,HttpSendRequest和HttpQueryInfo去打开文件
//OpenInternetsession.
HINTERNEThSession=:
NULL,
//Connectto.
HINTERNEThConnect=:
InternetConnect(hSession,
INTERNET_SERVICE_HTTP,
//Requestthefile/MSDN/MSDNINFO/fromtheserver.
HINTERNEThHttpFile=:
HttpOpenRequest(hConnect,
GET"
/MSDN/MSDNINFO/"
HTTP_VERSION,
INTERNET_FLAG_DONT_CACHE,
//Sendtherequest.
BOOLbSendRequest=:
HttpSendRequest(hHttpFile,NULL,0,0,0);
//Getthelengthofthefile.
charbufQuery[32];
DWORDdwLengthBufQuery=sizeof(bufQuery);
BOOLbQuery=:
HttpQueryInfo(hHttpFile,
HTTP_QUERY_CONTENT_LENGTH,
bufQuery,
dwLengthBufQuery);
//ConvertlengthfromASCIIstringtoaDWORD.
DWORDdwFileSize=(DWORD)atol(bufQuery);
//Allocateabufferforthefile.
char*buffer=newchar[dwFileSize+1];
//Readthefileintothebuffer.
DWORDdwBytesRead;
InternetReadFile(hHttpFile,
dwFileSize+1,
//Putazeroontheendofthebuffer.
//ClosealloftheInternethandles.
InternetCloseHandle(hHttpFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
//Displaythefileinaneditcontrol.
InternetConnect
InternetConnet函数连接到一个HTTP,FTP或Gopher服务器:
InternetConnect(
hSession,//1HINTERNEThInternetSession
//2LPCTSTRlpszServerName
INTERNET_INVALID_PORT_NUMBER,//3INTERNET_PORTnServerPort
//4LPCTSTRlpszUsername
//5LPCTSTRlpszPassword
INTERNET_SERVICE_HTTP,//6DWORDdwService
0,//7DWORDdwFlags
O//8DWORDdwContext
第六个参数dwService决定服务类型(HTTP,FTP或Gopher)。
在上面的例子中,InternetConnect连接到一个HTTP服务器上,因为dwService被设置成INTERNET_SERVICE_HTTP。
第二个参数(设置成)提供了服务器的地址。
注意,HTTP地址必须为服务器名作语法分析,InternetOpenUrl为我们作语法分析。
第一个参数hInternetSession是从InternetOpen返回的句柄。
第四个、第五个参数提供一个用户姓名和密码。
这七个参数没有控制任何标志影响HTTP操作。
最后一个参数为状态回调函数提供前后关系的信息。
HttpOpenRequest
一旦和服务器的连接已经建立,我们打开了想要的文件。
HttpOpenRequest和HttpSenRequest一起工作打开文件。
HttpOpenRequest去创建一个请求句柄并且把参数存储在句柄中。
HttpOpenRequest把请求参数送到HTTP服务器。
HttpOpenRequest(
hConnect,//1HINTERNEThHttpSession
//2LPCTSTRlpszVerb
//3LPCTSTRlpszObjectName
HTTP_VERSION,//4LPCTSTRlpszVersion
NULL,//5LPCTSTRlpszReferer
0,//6LPCTSTRFAR*lplpszAcceptTypes
INTERNET_FLAG_DONT_CACHE,//7DWORDdwFlags
0//8DWORDdwContext
到现在为止,网络函数的许多参数看起来都类似。
HttpOpenResult的第一个参数是由InternetConnet返回的HINTERNET。
HttpOpenRequest的第七和第八个参数执行与InternetConnect中有相同名字的参数一样的功能。
第二个参数(“GET”)指定我们想要得到由第三个参数(“/MSDN/MSDNINFO/”)命名的对象。
HTTP版已经传递第四个参数;
现在,它肯定是HTTP棗VERSION。
因为“GET”是最流行的动词类型,HttpOpenRequest将为这个参数接收一个空指针。
第五个参数lpszReferer是一个网点的地址。
在这个网点上我们发现了我们现在想要看见的URL(统一资源定位)。
换而言之,如果你在上而且单击了跳到的一个连接,第五个参数就是。
因为它使你指向了目标URL(统一资源定位)。
这个值可以为空。
第六个参数执行一个我们的程序接收的文件类型列表。
把空值传递给HttpOpenRequest即通知了服务器只有文本文件可以被接收。
HttpSendRequest
除了传送请求外,HttpSendRequest允许你传送额外的HTTP标题给服务器。
关于HTTP标题的信息可以在http:
//www.w3.org/.上的最新HTTP上的最新的说明上找到。
在这个例子中,HttpSendRequest的所有参数都被传递为缺省值。
HttpSendRequest(
hHttpFile,//1HINTERNEThHttpRequest
NULL,//2LPCTSTRlpszHeaders
0,//3DWORDdwHeadersLength
0,//4LPVOIDlpOptional
0//5DWORDdwOptionalLength
HttpQueryInfo
为了得到关于文件的信息,在调用HttpSendRequest后使用HttpQueryInfo函数:
HttpQueryInfo(
HTTP_QUERY_CONTENT_LENGTH,//2DWORDdwInfoLevel
bufQuery,//3LPVOIDlpvBuffer
dwLengthBufQuery//4LPDWORDlpdwBufferLength
查询的结构是字符串或lpvBuffer中的字符串列表。
HTTP_QUERY_CONTENT_LENGTH查询
得到文件的长度。
你可以使用HttpQueryInfo查询大范围的信息。
要获知详细情形可查
阅网点Win32网
络函数专题。
SurfBear样本应用程序
SurBear样本应用程序使用Win32网络函数从Internet上得到文件并且在编辑器上显示原
始的HTML格式。
SurfBear使用HttpOpenRequest和HttpSendRequest取代InternetOpenUrl,
纯粹是为了演示的需要。
图2SurfBear屏幕
SurfBear是一个MFC4.0版本的对话应用程序。
它所有与Internet有关的功能都在
InternetThread.h和InternetThread.cpp文件中。
从internet上读取文件要花费相当数量的时间,所以从一个工作线程调用网络函数是
一个明智的主意。
通过这种方式,当系统在等待得到数据时,应用程序的窗口能被改
变尺寸和移动。
图3显示了SurfBear的控制流。
当用户按下GOTO按钮时,CsurfBearDlg:
OnBtnGoto调用CinternetThread:
GetWebPoge,
传递想要的web页的HTTP地址。
GetWe