wininet相关函数 wininet
网络函数
最好的探讨Win32网络函数的方法是直接进入代码。下面的代码是样本的代码,为了方便阅读,错误处理部分已经被删除掉了。
HINTERNEThNet=::InternetOpen("MSDNSurfBear",
PRE_CONFIG_INTERNET_ACCESS,
NULL,
INTERNET_INVALID_PORT_NUMBER,
0);
HINTERNEThUrlFile=::InternetOpenUrl(hNet,
"http://www.microsoft.com",
NULL,
0,
INTERNET_FLAG_RELOAD,
0);
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网络函数之前被调用。
HINTERNEThNet=::InternetOpen(
"MSDNSurfBear",//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协议。
HINTERNEThUrlFile=::InternetOpenUrl(
hNet,//1HINTERNEThInternetSession
"http://www.microsoft.com",//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是符合逻辑的:
charbuffer[10*1024];
DWORDdwBytesRead=0;
BOOLbRead=::InternetReadFile(
hUrlFile,//1HINTERNEThFile
buffer,//2LPVOIDlpBuffer
sizeof(buffer),//3DWORDdwNumberOfBytesToRead
&dwBytesRead//4LPDWORDlpdwNumberOfBytesRead
);
buffer[dwBytesRead]=0;
pEditCtrl->tSetWindowText(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页都支持得到页尺寸。(例如:[url]www.toystory.com[/url]和[url]www.movielink.com[/url]不支持这个功能)另外,TCP/IP能传递的数据也比要求的要少。所以,你的应用程序应该处理着两种情况并且围绕InternetReadFile循环直到结果为TRUE同时*lpdwNumberOfBytesRead为0。
使用HttpOpenRequest,HttpSendRequest和HttpQueryInfo去打开文件[url]http://www.microsoft.com/msdn/msdninfo[/url]的代码显示如下,错误检测已经被删除。
//OpenInternetsession.
HINTERNEThSession=::InternetOpen("MSDNSurfBear",
PRE_CONFIG_INTERNET_ACCESS,
NULL,
INTERNET_INVALID_PORT_NUMBER,
0);
//Connecttowww.microsoft.com.
HINTERNEThConnect=::InternetConnect(hSession,
"www.microsoft.com",
INTERNET_INVALID_PORT_NUMBER,
"",
"",
INTERNET_SERVICE_HTTP,
0,
0);
//Requestthefile/MSDN/MSDNINFO/fromtheserver.
HINTERNEThHttpFile=::HttpOpenRequest(hConnect,
"GET",
"/MSDN/MSDNINFO/",
HTTP_VERSION,
NULL,
0,
INTERNET_FLAG_DONT_CACHE,
0);
//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;
BOOLbRead=::InternetReadFile(hHttpFile,
buffer,
dwFileSize+1,
&dwBytesRead);
//Putazeroontheendofthebuffer.
buffer[dwBytesRead]=0;
//ClosealloftheInternethandles.
::InternetCloseHandle(hHttpFile);
::InternetCloseHandle(hConnect);
::InternetCloseHandle(hSession);
//Displaythefileinaneditcontrol.
pEditCtrl->tSetWindowText(buffer);
InternetConnect
InternetConnet函数连接到一个HTTP,FTP或Gopher服务器:
HINTERNEThConnect=::InternetConnect(
hSession,//1HINTERNEThInternetSession
"www.microsoft.com",//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。第二个参数(设置成[url]www.microsoft.com[/url])提供了服务器的地址。注意,HTTP地址必须为服务器名作语法分析,InternetOpenUrl为我们作语法分析。第一个参数hInternetSession是从InternetOpen返回的句柄。第四个、第五个参数提供一个用户姓名和密码。这七个参数没有控制任何标志影响HTTP操作。最后一个参数为状态回调函数提供前后关系的信息。
HttpOpenRequest
一旦和服务器的连接已经建立,我们打开了想要的文件。HttpOpenRequest和HttpSenRequest一起工作打开文件。HttpOpenRequest去创建一个请求句柄并且把参数存储在句柄中。HttpOpenRequest把请求参数送到HTTP服务器。
HINTERNEThHttpFile=::HttpOpenRequest(
hConnect,//1HINTERNEThHttpSession
"GET",//2LPCTSTRlpszVerb
"/MSDN/MSDNINFO/",//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]www.home.com[/url]上而且单击了跳到[url]www.microsoft.com[/url]的一个连接,第五个参数就是[url]www.home.com[/url]。因为它使你指向了目标URL(统一资源定位)。这个值可以为空。第六个参数执行一个我们的程序接收的文件类型列表。把空值传递给HttpOpenRequest即通知了服务器只有文本文件可以被接收。
HttpSendRequest
除了传送请求外,HttpSendRequest允许你传送额外的HTTP标题给服务器。关于HTTP标题的信息可以在[url]http://www.w3.org/[/url]上的最新的说明上找到。在这个例子中,HttpSendRequest的所有参数都被传递为缺省值。
BOOLbSendRequest=::HttpSendRequest(
hHttpFile,//1HINTERNEThHttpRequest
NULL,//2LPCTSTRlpszHeaders
0,//3DWORDdwHeadersLength
0,//4LPVOIDlpOptional
0//5DWORDdwOptionalLength
);
HttpQueryInfo
为了得到关于文件的信息,在调用HttpSendRequest后使用HttpQueryInfo函数:
BOOLbQuery=::HttpQueryInfo(
hHttpFile,//1HINTERNEThHttpRequest
HTTP_QUERY_CONTENT_LENGTH,//2DWORDdwInfoLevel
bufQuery,//3LPVOIDlpvBuffer
&dwLengthBufQuery//4LPDWORDlpdwBufferLength
);
查询的结构是字符串或lpvBuffer中的字符串列表。HTTP_QUERY_CONTENT_LENGTH查询得到文件的长度。你可以使用HttpQueryInfo查询大范围的信息。
总结
Win32网络函数使从FTP,Gopher和HTTP服务器上读取信息就想从你的硬盘驱动器上读取信息一样容易。仅仅使用4个函数棗InternetOpen,InternetOpenUrl,InternetReadFile和InternetCloseHandle和很少的HTTP知识,你就可以写一个简单的网络浏览器。
二、使用WinINET访问加密协议
---- 使用WinINET访问加密协议是使用加密协议最简单的方法。
---- 使用WinINET访问加密协议的步骤
---- 1. 使用InternetConnect函数连接,将dwFlags参数设置为INTERNET_FLAG_SECURE。
---- InternetConnect函数用于打开一个FTP、Gopher或HTTP站点。如果成功,将返回该FTP、Gopher或HTTP会话的句柄;如果不成功,返回NULL。InternetConnect的函数原型为:
HINTERNET InterConnect(?hInternetSession, IN LPCSTR lpszServerName, IN INTERNET_PORT nServerPort, IN LPCSTR lpszUsername, <br />??????? IN LPCSTR lpszPassword, IN DWORD dwService, IN DWORD dwFlags, IN DWORD dwContext ); <font color="#ffffff">----</font>
这里需要设置8个参数,其中:
hInternetSession为目前会话的句柄。该句柄必须是上一个InternetOpen函数的返回值;
lpszServerName指向包含Internet服务器的主机名称(如[url]http://www.mit.edu[/url])或IP地址(如202.102.13.141)的字符串;
nServerPort是将要连结到的TCP/IP的端口号,可以使用一些预定的常量,详见表1;
---- 表1:预定义的TCP/IP端口值
名称 端口值
INTERNET_DEFAULT_FTP_PORT 21
INTERNET_DEFAULT_GOPHER_PORT 70
INTERNET_DEFAULT_HTTP_PORT 80
INTERNET_DEFAULT_HTTPS_PORT 443
INTERNET_DEFAULT_SOCKS_PORT 1080
INTERNET_INVALID_PORT_NUMBER 使用由dwService指定的服务的默认端口值
---- lpszUsername指向包含用户用于登录的名字的字符串。其默认值详见表2;
---- lpszPassword指向包含用户登录密码的字符串,其默认值详见表2;
---- 表2:lpszUsername和lpszPassword的默认值
lpszUsername的值 lpszPassword的值 lpszUsername的默认值 lpszPassword的默认值
NULL NULL "anonymous" 用户的电子邮件名称
NULL 非空字符串 错误 错误
非空字符串 NULL lpszUsername的值 ""
非空字符串 非空字符串 lpszUsername的值 lpszPassword的值
---- l dwService是要访问的服务类型,其值详见表3;
---- 表3:Internet服务的预定义值
预定义名称 意义
INTERNET_SERVICE_FTP FTP服务
INTERNET_SERVICE_GOPHER Gopher服务
INTERNET_SERVICE_HTTP HTTP服务
---- dwFlags为可选标记,此处设置为INTERNET_FLAG_SECURE,表示使用SSL/PCT协议完成事务;
---- dwContext为应用程序定义的值,用来为返回的句柄标识应用程序设备场境。
---- 2. 对于HTTP,需要调用HttpOpenRequest函数。
---- HttpOpenRequest函数用于打开HTTP申请,如果成功则返回该申请的句柄,否则返回NULL。该函数原型为:
HINTERNET HttpOpenRequest(HINTERNET hHttpSession, IN LPCSTR lpszVerb, IN LPCSTR lpszObjectName, IN LPCSTR lpszVersion, IN LPCSTR lpszReferer, IN LPCSTR FAR * lpszAcceptTypes, IN DWORD dwFlags, IN DWORD dwContext );
---- 该函数有8个参数需要设置,其中:
hHttpSession是由InternetConnect返回的HTTP会话句柄;
lpszVerb指向在申请中使用的"动词"的字符串,如果设置为NULL,则使用"GET";
lpszObjectName指向包含动词的目标对象名称的字符串,通常是文件名称、可执行模块或搜索说明符;
lpszVersion指向包含HTTP版本的字符串,如果为NULL,则默认为"HTTP/1.0";
lpszReferer指向包含文档地址(URL)的字符串,申请的URL必须是从该文档获取的;
lpszAcceptTypes指向客户接收的内容的类型;
dwFlags、dwContext与InternetConnect函数中的同名参数意义相同,
---- 3. 按通常使用WinINET的方法完成对HTTP的访问。
三、使用Winsock访问加密协议
---- 3-1 证书验证
---- 验证(Authentication)是确定远程主机是否可信的过程。远程主机只有从认证中心(Certificate Authority,以下简称CA)获得了基于公钥加密的鉴定证书,才能够被看作可信的。认证中心可以从级别更高的认证中心获得证书,依此类推。这样就形成了一个认证链。要验证一个证书的真伪,应用程序必须确定基层CA的一致性。Windows CE支持X.509型证书。
---- Windows CE维护了一个可以信赖的CA的数据库。当应用程序试图启动加密连结时,Windows CE从认证链的底层提取CA并检查它是否在自己的CA数据库中。应用程序最终承担判断证书值否可以接受的责任。它们可以自由的决定接受或拒绝证书,这取决于它们判断的标准和要求保密性的高低。如果证书被拒绝了,那么连结将不能完成。至少,证书应当满足下列需求:(1)他们应当是当前的;(2)证书的基层CA应当在Windows CE的CA数据库中。
---- 证书的确认回叫函数必须被所有使用加密套接字的客户应用所实现。他们的返回值决定了连结是否能够通过Winsock完成,语法如下:
int SslValidate ( DWORD dwType, LPVOID pvArg, DWORD dwChainLen, LPBLOB pCertChain, DWORD dwFlags, );
---- 返回值详见表4:
---- 表4:SslValidate函数的返回值
返回值 意义
SSL_ERR_BAD_DATA 证书格式不正确
SSL_ERR_BAD_SIG 签名检验失败
SSL_ERR_CERT_EXPIRED 证书到期
SSL_ERR_CERT_REVOKED 证书被自己的发行商撤销
SSL_ERR_CERT_UNKNOWN 发行尚未知,或者一些未知问题出现在验证过程中
---- SslValidate的5个参数意义如下:
dwType制定了被pCertChain指定的数据类型,它必须为SSL_CERT_X.509,表示pCertChain是一个指向X.509型证书的指针;
pvArg是应用程序定义的设备场境,被SSLVALIDATECERTHOOK结构传递;
dwChainLen参数是pCertChain指向的证书数量。它必须为1;
pCertChain是一个指向底层证书的指针;
证书发行商没有在CA数据库中找到,dwFlags应当包含SSL_CERT_FLAG_ISSUER_UNKNOWN。应用程序可以使者验证发行商自己,或返回SSL_ERR_CERT_UNKNOWN。
---- 3-2 实现加密套接字
---- 下面介绍如何建立加密套接字连结。
---- 实现加密套接字的步骤
---- 1. 使用socket函数建立一个套接字。
---- socket函数用于建立绑定到指定服务提供商的套接字。其函数原型如下:
---- SOCKET socket (int af, int type, int protocol);
---- 其中:
af是地址规范,Windows CE支持PF_INET和AF_IRDA APAR Internet地址格式;
---- type是新套接字的类型规范,其值见表5:
---- 表5:套接字类型
类型 说明
SOCK_STREAM 使用带外数据传输机制提供连续的、可信的、双向的、基于连结的字节流。
SOCK_DGRAM 支持非连结的、限定最大长度的不可靠缓冲的数据报。
---- l protocol是在socket中使用的协议,以指定地址家族。
---- 2. 使用setsockopt函数将套接字设置为加密模式。该函数原型如下:
---- int setsockopt (SOCKET s, int level, int optname, const char FAR * optval, int optlen);
---- 其中:
s是一个套接字的描述符;
level是选项被定义的级别,其值可以是SOL_SOCKET或IPPROTO_TCP。这里设置为SOL_SOCKET,此时,将有如下选项;
optname是将要设置的套接字选项名称,这里设置为SO_SECURE;
optval指向存储被申请套接字选项的值的缓冲区,这里设置为指向DWORD的值为SO_SEC_SSL的指针;
optlen是optival缓冲区的大小;
---- 3. 通过调用WSAIoctl指定认证验证回叫函数,函数原型如下:
int WSAIoctl ( SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOUTBuffer, DWORD cbOUTBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE );
---- 其中:
s是一个套接字的描述符;
dwIoControlCode是待执行操作的控制代码,这里为SO_SSL_SET_VALIDATE_CERT_HOOK,表示将指针设置为证书验证指令;
lpvInBuffer是一个指向输入缓冲区的指针;
cbInBuffer是输入缓冲区大小;
lpvOutBuffer是指向输出缓冲区的指针;
cbOutBuffer是输出缓冲区大小;
lpcbBytesReturned是指向真实的输出字节的数值;
lpOverlapped和lpCompletionROUTINE这里必须为NULL。
---- 4. 要指定特定的安全协议,调用WSAIoctl,并将dwIoControlCode设置为SO_SSL_GETPROTOCOLS来决定默认协议。然后调用WSAIoctl,将dwIoControlCode设置为SO_SSL_SET_PROTOCOLS来选择将被使用的协议。
---- 5. 使用connect建立连结。
---- connect函数用于建立一个到指定套接字的连接。其函数原型为:
---- int connect (SOCKET s, const struct sockaddr FAR* name, int namelen);
---- 其中:
s为一个套接字的描述符;
name时要连结到的套接字名称;
namelen是name参数的长度。
---- 6. 正常传输和接受信息。使用send和recv函数自动加密和解密数据。
---- recv用来从连结的套接字中接受数据。
---- int recv (SOCKET s, char FAR* buf, int len, int flags);
---- 其中:
s为一个套接字的描述符;
buf是输入数据的缓冲;
len是buf的长度;
flags指定访问建立的方式。
---- 7. 完成后,使用closesocket函数关闭套接字。closesocket的函数原型为:
---- int closesocket (SOCKET s);
---- l s是将被关闭的套接字的描述符。
---- 3-3 使用延时握手
---- 延时握手允许应用程序建立一个不加密连结,以后将其转换为加密连结。使用延时握手实现加密套接字
同"实现加密套接字"步骤的1~3步。
Set the socket in deferred handshake mode with WSAIoctl. The control code should be set to SO_SSL_SET_FLAGS and the flag set to SSL_FLAG_DEFER_HANDSHAKE. 使用WSAIoctl将套接字设置为握手模式。dwIoControlCode为SO_SSL_SET_FLAGS并将标记设置为SSL_FLAG_DEFER_HANDSHAKE。
使用connect函数建立非加密到远程客户的连结。
正常传输和解收费加密数据。
要切换到加密模式,调用WSAIoctl函数,将dwIoControlCode设置为SO_SSL_PERFORM_HANDSHAKE。证书回叫函数将被自动调用。
正常传输数据。使用send和recv函数自动加密和解密数据。
使用closesocket关闭套接字。
更多阅读
matlab的使用:8 如何画不同类型的三维图像
matlab的使用:[8]如何画不同类型的三维图像——简介这是本系列经验的第八篇,主要介绍用matlab软件画三维图像的一些相关函数,使用这些函数可以很方便的画出想要的图形,非常直观好用。matlab的使用:[8]如何画不同类型的三维图像——工具/
string.h函数介绍详细2zz string append函数
bcmp(比较存内容)相关函数bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp表头文件#include<str
如何把16进制字符串转换成相应的16进制数 字符串转换为16进制
今天在某个程序当中需要把文本16进制转换成对应的16进制数,比如字符串"0x1a"转换成10进制的22,可以用以下函数来实现相关函数: atof, atoi, atol, strtod, strtoul表头文件: #include <stdlib.h>定义函数: long int strtol(const char
触发器、存储过程和函数三者有何区别 存储过程和触发器
触发器是特殊的存储过程,存储过程需要程序调用,而触发器会自动执行;你所说的函数是自定义函数吧,函数是根据输入产生输出,自定义只不过输入输出的关系由用户来定义。在什么时候用触发器?要求系统根据某些操作自动完成相关任务,比如,根据买掉
VBA函数参考 excelvba函数参考手册
1.字符串函数序号函数名功 能001Asc返回一个Integer,代表字符串中首字母的字符代码002Chr返回String,其中包含有与指定的字符代码相关的字符003InStr指定一字符串在另一字符串中最