HTTP 1.1是一个基于文本的互联网实体信息交互主流协议,协议的分析已经在《HTTP协议格式分析》文中详细介绍。
    

HTTP 1.1协议中的请求类型可以是下面的一种:    
   1. OPTION:返回请求者和相应者之间可以使用的通信选项,主要用来检测服务器处理能力;  
   2. GET:获得以URL标示的文件内容或者程序执行结果。服务器根据文件名后缀判断服务内容,比如该URL是静态文本还是一个程序;  
   3. HEAD:除了不返回响应的信息本体以外,得到的是跟GET一样的信息。一般用来测试链接的有效性、可达性和近期修改;  
   4. POST:把消息本体中的消息发送到一个URL或者其他类似的服务器端定义行为。通常用来提交一个HTML表单或者一些数据操作活动;    
   5.   PUT:把消息本体中的消息发送到一个URL,跟POST类似,但不常用;  
   6.   Delete:删除URL指定的资源;  
   7.   TRACE:调用一个远程应用层请求消息回路。发出这个消息的用户终端除了收到原来的消息内容以外,还得到消息在Internet上的传送路径。    
   最常用的请求类型是GET和POST。我们在访问网页时就会向服务器发出如下GET请求:  
  GET   /   HTTP/1.1    
   accept-charset:   UTF-8    
   accept-language:   ch    
   accept:   text/vnd.wap.wml,   */*,   image/bmp,   text/html    
   user-agent:   UP.Browser/3.1-UPG1   UP.Link/3.2    
   host:   www.wantsoft.com  
   ……    
   其中粗体的部分是HTTP消息头,这里我们忽略了一些与我们关系不大的消息头。  
   accept-charset:   用户终端支持的字符集  
   accept-language:   用户终端目前使用的语言    
   accept:   用户终端可以接受的MIME文件类型    
   user-agent:   用户终端供应商提供的终端描述信息    
   host:   请求信息发送到的域名    
    
  
如果该URL合法的话,服务器的响应会是这样的:    
   HTTP/1.1   200   OK    
   Server:   www/5.0    
   Date:   Fri,   26   Oct   2000   12:15:23   GMT    
   Connection:   Keep-Alive    
   Content-Length:   1211    
   Content_Type:   text/vnd.wap.wml  
   Last-Modified:   Mon,   22   Oct   2000   18:19:24   GMT  
    
   <?xml   version=”1.0”>  
   <!<!DOCTYPE   wml   PUBLIC   “-//WAPFORUM//DTD   WML   1.1//EN”    
   “http://www.wapforum.org/DTD/wml_1.1.xml”>  
    
   ……  

    
   这个响应信息里包括了响应的数字代码和文本描述,然后是一组消息头域。
   Server:   发出响应的服务器    
   Date:   响应发出的时间  
   Connection:   指示用户终端保持连接    
   Content-Length:   响应信息的长度,从DECK的第一个”<“字符开始计算  
   Content_Type:   响应的MIME类型    
   Last-Modified:   响应中DECK的最后修改时间    
    
   当用户终端接收到响应以后,会对其状态信息和消息头进行解码,然后决定对响应做出什么样的动作。如果收到OK响应,一般会把消息本体里的内容显示在屏幕上。    
  
    
了解了HTTP消息和头域的含义之后,我们就可以用CHttpConnection类来实现Get方法。


BOOL GetRequest(LPCTSTR lpszURL,     // 如:www.wantsoft.com
     LPCTSTR lpszObjectName,     // 如:index.asp
     LPCTSTR lpszReferer,     // 如:/modify-new.htm
     OUT CString &csResponse)     //output information
{

     BOOL bRet = FALSE;
     CString csHeaders, csOptionalData = “”;
                 //构造GET的头域
     csHeaders += “Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/msword, application/x-shockwave-flash, */*n”;
     csHeaders += “Referer: http://“;
     csHeaders += lpszURL;
     csHeaders += lpszReferer;
     csHeaders += “n”;
     csHeaders += “Accept-Language: zh-cn,en-us;q=0.5n”;
     csHeaders += “Content-Type: application/x-www-form-urlencodedn”;
     csHeaders += “Proxy-Connection: Keep-Aliven”;
     csHeaders += “User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; .NET CLR 1.0.3705; .NET CLR 1.1.4322)n”;
     csHeaders += “Host: “;
     csHeaders += lpszURL;
     csHeaders += “n”;
     csHeaders += “Pragma: no-cachen”;
     csHeaders += “rn”;

     CHttpFile* pMyHttpFile = NULL;
     CHttpConnection* pConnection = NULL;
     CInternetSession mySession;
     try
     {
         mySession.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10*1000);  
         pConnection = mySession.GetHttpConnection(_T(lpszURL));
         pMyHttpFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, lpszObjectName);
         if ( pMyHttpFile->SendRequest(csHeaders,
             (LPVOID)(LPCTSTR)csOptionalData, csOptionalData.GetLength()) )
         {
             DWORD dwStatus;
             DWORD dwBuffLen = sizeof(dwStatus);
             pMyHttpFile->QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwBuffLen);
             if ( HTTP_STATUS_OK == dwStatus )
             {
                 csResponse.Empty ();
                 CString myData;
                 while ( pMyHttpFile->ReadString ( myData ) )
                 {
                     csResponse += myData;
                 }
                 bRet = TRUE;
             }
         }
     }
     catch ( CInternetException* pEx )
     {
         bRet = FALSE;
         TCHAR   szErr[1024]={0};
         pEx->GetErrorMessage(szErr,1024);
         pEx->Delete();
     }

     if ( pMyHttpFile )
     {
         pMyHttpFile->Close();
         delete pMyHttpFile;
     }
     if ( pConnection )
     {
         pConnection->Close();
         delete pConnection;
     }
     mySession.Close();
     return bRet;
}

把文件通过GET方法保存到本地的代码如下:
BOOL SaveFile(LPCTSTR lpszURL,     // 如:www.wantsoft.com
     LPCTSTR lpszObjectName,     // 如:/main.gif
     LPCTSTR lpszReferer,     // 如:/index.asp
                 CString &lpszFileName)
{
     CInternetSession       mySession;
     CHttpConnection       *pConnection     = NULL;
     CHttpFile             *pMyHttpFile     = NULL;
     DWORD   dwRet,   dwRead =1;

     BOOL   bRet   = FALSE;
     char   szBuff[1024*100];
     CString strFileName;
     try
     {    
         mySession.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10*1000);  
         pConnection =   mySession.GetHttpConnection(_T(lpszURL));
         pMyHttpFile =   pConnection->OpenRequest( CHttpConnection::HTTP_VERB_GET,lpszObjectName);

         pMyHttpFile->SendRequest();
         pMyHttpFile->QueryInfoStatusCode(dwRet);  
                                 //如果该对象GET成功
         if   (dwRet   ==   HTTP_STATUS_OK)
         {
                         memset(   szBuff,   0,   sizeof(szBuff));
             dwRead= pMyHttpFile->Read(szBuff,sizeof(szBuff)-1);      

             DWORD mRet = 0;
             HANDLE hFile;                
             lpszFileName = strFileName;

             if (leaf::IsFileExist(strFileName))
                 (leaf::DeleteFilePedding(strFileName,FALSE));
             hFile=CreateFile(lpszFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,Create_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
             WriteFile(hFile,szBuff,dwRead,&mRet,NULL);
             while(dwRead > 0)
             {
                 dwRead= pMyHttpFile->Read(szBuff,sizeof(szBuff)-1);          
                 WriteFile(hFile,szBuff,dwRead,&mRet,NULL);
             }
             CloseHandle(hFile);
             bRet = TRUE;

         }
         else
         {
             bRet =   FALSE;
         }
     }
     catch ( CInternetException* pEx )
     {
         bRet = FALSE;
         TCHAR   szErr[1024]={0};
         pEx->GetErrorMessage(szErr,1024);
         pEx->Delete();
     }

     if ( pMyHttpFile )
     {
         pMyHttpFile->Close();
         delete pMyHttpFile;
     }
     if ( pConnection )
     {
         pConnection->Close();
         delete pConnection;
     }

     mySession.Close();
     return bRet;
}

本文版权属于《Visual C++网络游戏建模与实现》作者苏羽和http://www.wantsoft.com共同所有,引用者请务必保留本行版权信息,否则作者苏羽和http://www.wantsoft.com保留追究的权利。

Comments are closed.

Post Navigation