精华内容
下载资源
问答
  • 实现winInet库 HTTP协议的实现,下载Web资源
  • 1.WinInet(这种方式很简单,但不是很灵活) 2.WinSock(也就是Socket,这种方式有点繁琐,但是可以自定义发送HTTP的报文头和接收响应头,很灵活) 因作者编程水平有限,错误之处,在所难免,欢迎批评指正。
  • 资源介绍:wininet实现GET和POST访问网页资源作者:易语言在线自学资源界面:资源下载:
  • 易语言WinInet模块源码

    2020-08-16 00:42:04
    易语言WinInet模块源码 系统结构:读取数据,提交数据,InternetOpen,InternetConnect,InternetReadFile,HttpOpenRequest,HttpSendRequest,HttpAddRequestHeaders,InternetCloseHandle,InternetOpenUrl, ======程序集1 ...
  • HTTPRequest:WinInet HTTP请求示例
  • (1)理解 WinInet API 的基本概念与操作流程。 (2)掌握使用 WinInet 编写程序的方法。 (3)掌握 MFC WinInet 类层次结构和编程方法。 (4)掌握多线程网络编程的方法。 WinInet 是 Windows Internet 扩展应用...
  • 易语言Wininet访问类v2.2模块源码,Wininet访问类v2.2模块,Reset,Auto,SetLocal,SetOption,SetTimeouts,SetProxy,SetCredentials,SetGzipAuto,SetRequestHeader,DelRequestHeader,Open,Send,Send_Bin,GetResponseBody...
  • WinInet

    2016-08-23 16:53:36
    WinINet是干什么的? 二如果完成一个基本的WinINet操作流程 三如何异步完成,异步操作的好处。 四 unicode以及mutilbyte 五代码样例 一 WinINet是微软开发的一个库,可以完成http ftp客户端的工作。让...
    一 WinINet是干什么的?
    
    二如果完成一个基本的WinINet操作流程
    三如何异步完成,异步操作的好处。
    四 unicode以及mutilbyte
    五代码样例

    一 WinINet是微软开发的一个库,可以完成http ftp客户端的工作。让程序员从复杂的协议中节省大量体力。

    二我会用了http, ftp类似。用WinINet完成一个http下载需要以下步骤 。 下面这个是同步操作(也就是一步步操作,每个函数执行完才会返回一个结果的意思)

        1   InternetOpen      Initializes anapplication's use of the WinINet functions.
                      需要的话 InternetSetOption 设置代理服务器地址以及端口。
                      http:    ip:port 或者 http=http://ip:port
                      socks:SOCKS=ip:port
        2   InternetConnect    关联目标地址或者域名以及服务ip

        3   HttpOpenRequest   关联要下载的内容名字
                      InternetSetOption 设置用户名密码

        4   HttpSendRequest     这步就是用HttpOpenRequest 的返回值(已经关联了上面的所有信息)发送出去,第一次用了网络。向目标服务器或者代理服务器。

        5   HttpQueryInfo
               该函数查询返回值,不参与网络操作。可以查询服务器的返回信息,比如目标文件的大小,该文件是否存在,代理服务返回了要求用户名,密码等等(这几个最常用),还有很多信息。

        6   InternetReadFile
               很普通的读函数,就是下载文件。不知道是否和底层网络同步,底层会不会提前下载呢?

        7   InternetCloseHandle 释放资源

    三    异步操作,比较复杂的。   为什么需要异步操作呢? 因为涉及到网络操作,某些函数在操作中可能需要时间,如果一直不返回(比如1秒)时,这时主线程要结束程序,岂不就出现意想不到的结果了,但是如果每个函数都能够瞬间返回,然后通过WaitForMultipleObjects或者WaitForSingleObject等待结果的出现(此时就不会操作那个消耗1秒的函数了,而这个1秒函数正是要用到系统资源HINTERNET的)。

          异步操作的目的上如,原理呢? 其实原理就是注册一个函数,在这里叫InternetStatusCallback,因为微软写得底层代码要用到,所以必须格式统一。一旦有结果来了就通过事件通知我们,WaitForSingleObject函数就可以走了。比如等到了HINTERNET创建或者命令发送成功等结果。然后我们就可以第一时间安全的使用了。
         API 函数如果名字最后可以带EX,那么带ex的就是异步操作的。

    四一定要注意,凡是有unicode和mutilbyte函数的一定要统一,最好都用mutilbyte的。


    五: 代码如下:
    // crt_assert.c
    // compile with: /c
    #include<stdio.h>
    #include<assert.h>
    #include<stdlib.h>


    #include <iostream>

    #include"winsock2.h"
    #include <string>
    #include<Wininet.h>
    #include<windows.h>
    #include<fstream> //要使用文件输入输出流必须的头文件
    using namespace std;
    #define__HTTP_VERB_GET    "GET"
    #define__HTTP_VERB_POST "POST"
    #define__HTTP_ACCEPT_TYPE "*/*"
    #define __HTTP_ACCEPT"Accept: */*\r\n"
    #define__SIZE_HTTP_BUFFER    100000
    #define__SIZE_HTTP_RESPONSE_BUFFER    100000
    #define__SIZE_HTTP_HEAD_LINE    2048

    void CALLBACKInternetStatusCallback(

                                     HINTERNET hInternet,
                                     DWORD dwContext,
                                     DWORD dwInternetStatus,
                                     LPVOID lpvStatusInformation,
                                     DWORD dwStatusInformationLength);
    HANDLE hEvent[3];

    HINTERNET hFile;
    HINTERNET hNet;
    HINTERNEThSession,hConnect,hRequest;
    int WaitExitEvent()
    {
       //return 1;
       DWORD dwRet = ::WaitForMultipleObjects(3, hEvent, FALSE, 30000);//INFINITE);
       int x=-1;
       switch (dwRet)
        {
           //句柄被创建事件或者读数据请求成功完成事件
       case WAIT_OBJECT_0:
           x=0;
           cout<<"WAIT_OBJECT_0"<<endl;
           //句柄被关闭事件
           break;
       case WAIT_OBJECT_0+1:
           x=1;
           cout<<"WAIT_OBJECT_1"<<endl;
           //用户要求终止子线程事件或者发生错误事件
           break;
       case WAIT_OBJECT_0+2:
           x=2;
           cout<<"WAIT_OBJECT_2"<<endl;
           
           break;
       default:
           cout<<"WaitForMultipleObjects timeout"<<endl;
           return -1;

        }
       return x;
    }

    // 支持代理设置, 是否异步设置; 采用事件驱动
    void WinINet3(boolsetProxy, bool ASYNC)
    {
       hSession=NULL;
       hConnect=NULL;
       hRequest=NULL;
       for (int i = 0; i < 3; i++) 
       { 
           hEvent[i] = CreateEvent( 
               NULL,   // default securityattributes
               FALSE, // auto-reset event object
               FALSE, // initial state is nonsignaled
               NULL); // unnamed object

           if (hEvent[i] == NULL) 
           { 
               printf("CreateEvent error:%d\n", GetLastError() ); 
               ExitProcess(0); 
           } 
       } 
       char *url = "http://down.360safe.com/setup.exe";
       char *pip = "down.360safe.com";
       char *paim = "/setup.exe";



       //   step 1
       if(ASYNC)    cout<<"异步模式"<<endl;
       //setProxy =false;
       if(setProxy)
        {
           cout<<"代理模式"<<endl;
           if(ASYNC)
             hSession = InternetOpen("name",
           INTERNET_OPEN_TYPE_DIRECT,//|INTERNET_OPEN_TYPE_PROXY,//INTERNET_OPEN_TYPE_PROXY,
           NULL,NULL,INTERNET_FLAG_ASYNC); // 异步
           else
             hSession = InternetOpen("name",INTERNET_OPEN_TYPE_PROXY,NULL,NULL,0);// 同步
        }
       else
        {
           if(ASYNC)
               hSession =InternetOpen("name",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,INTERNET_FLAG_ASYNC);// 异步
           else
               hSession =InternetOpen("name",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); // 同步
        }
       if(!hSession){
           DWORD er = ::GetLastError();
           cout<<"InternetOpen error"<<endl;//,"Err", MB_OK);
           return;
        }
       if(ASYNC)
        {
           //Sleep(500);
           INTERNET_STATUS_CALLBACK res =::InternetSetStatusCallback(hSession,InternetStatusCallback);
           if(res == INTERNET_INVALID_STATUS_CALLBACK)
           {
              cout<<"InternetSetStatusCallback failed, so return"<<endl;
               return ;    
           }
           else
           {
               cout<<"InternetSetStatusCallbacksucceed, so go on "<<endl;

           }
           //Sleep(500);
        }
        
       char   strProxyList[MAX_PATH],  strUsername[64],   strPassword[64];
       strcpy(strProxyList,   "SOCKS=58.56.87.2:1080");//   写上socks怎么就无效了呢???SOCKS5=172.18.132.27:1080
       strcpy(strUsername,   "user01"); 
       strcpy(strPassword,   "baidu"); 
       INTERNET_PROXY_INFO proxy;
       proxy.dwAccessType = INTERNET_OPEN_TYPE_PROXY;
       proxy.lpszProxy    = strProxyList;
       proxy.lpszProxyBypass = NULL;
       if( setProxy &&!InternetSetOption(hSession,INTERNET_OPTION_PROXY,&proxy,sizeof(INTERNET_PROXY_INFO)))
        {
           cout<<"InternetSetOption failed"<<endl;
           return ;
        }
        
       // step 2
       //如果明确知道需要认证,第4,5个参数可以输入用户名,密码"administrator","password"
       //第2,3个参数为目标主机IP、端口号(不是代理服务器的参数)
       hConnect =InternetConnect(hSession,pip,INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RELOAD,0);
       if(!ASYNC &&!hConnect){
           cout<<"同步,InternetConnecterror"<<endl;//, "Err", MB_OK);
           return;
        }
       if( ASYNC&& hConnect== NULL)// 异步 需要等待   竟然直接创建好了
        {
           int er = GetLastError();
           DWORD dwError = ::GetLastError();
           if (dwError != ERROR_IO_PENDING) 
           {
              cout<<"CHttpDownload::OpenInternetConnection| 连接失败" <<endl;
               return ;
           }
           else //
           {
               cout<<"hConnect == NULL, sorun WaitExitEvent"<<endl;
               WaitExitEvent(); // 等待成功创建 // 这里应该等待   这里应该显示一次呀
               ::ResetEvent(hEvent[0]);
               ::ResetEvent(hEvent[1]);
               ::ResetEvent(hEvent[2]);
           }
        }
       cout<<"step 2 :InternetConnect secced"<<endl;

       // ::InternetSetStatusCallback(hConnect,InternetStatusCallback);
        
       // step 3!!!
       char   szHead[] = "Accept: */*\r\n\r\n";
       char **p = new char*[2];*p = szHead;*(p+1) = NULL;

       //hRequest =HttpOpenRequest(hConnect,"GET","download/BaiduHi_1.0_Beta2.exe",NULL,NULL,/*(constchar **)p*/NULL,0/*INTERNET_FLAG_NO_COOKIES|INTERNET_FLAG_RELOAD*/,0); // norequest;
       CONST TCHAR *szAcceptType=__HTTP_ACCEPT_TYPE;
       hRequest = ::HttpOpenRequest(hConnect,
           "GET",
           paim,
           HTTP_VERSION,
           "",
           &szAcceptType,
          INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE,
           0);
        
       //::HttpAddRequestHeaders( hRequest, __HTTP_ACCEPT, strlen(__HTTP_ACCEPT),HTTP_ADDREQ_FLAG_REPLACE);
       /*_hHTTPRequest=::HttpOpenRequest(    _hHTTPConnection,
           __HTTP_VERB_GET, // HTTP Verb
           szURI, // Object Name
           HTTP_VERSION, // Version
           "", // Reference
           &szAcceptType, // Accept Type
           INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE,
           0); // context call-back point
       */
       if (!ASYNC&& !hRequest){
           cout<<"同步,HttpOpenRequesterror"<<endl;//, "Err", MB_OK);
           return;
        }
       if( ASYNC&& hRequest== NULL)// 异步 需要等待
        {
           int er = GetLastError();
           DWORD dwError = ::GetLastError();
           if (dwError != ERROR_IO_PENDING) 
           {
               cout<<"CHttpDownload::OpenInternetConnection|连接失败" <<endl;
               return ;
           }
           else //
           {
               cout<<"hRequest == NULL, sorun WaitExitEvent"<<endl;
               WaitExitEvent(); // 等待成功创建
               ::ResetEvent(hEvent[0]);
               ::ResetEvent(hEvent[1]);
               ::ResetEvent(hEvent[2]);
           }
        }
       //Sleep(10000);
       cout << "step 3 : HttpOpenRequest success"<<endl;
       //::InternetSetStatusCallback(hRequest,InternetStatusCallback);
       //
       if (setProxy )
        {
           // InternetSetOption 不要异步等待
           if(!InternetSetOption(hRequest,INTERNET_OPTION_PROXY_USERNAME,strUsername,strlen(strUsername)+1))
           {
               cout<<"InternetSetOptionUsername failed"<<endl;
               return ;
           }
           if(!InternetSetOption(hRequest,INTERNET_OPTION_PROXY_PASSWORD,strPassword,strlen(strPassword)+1))
           {
               cout<<"InternetSetOptionPassword failed"<<endl;
               return ;
           }
        }
       // step 4
       //HttpSendRequest(hRequest,NULL,0,NULL,0);
       //Sleep(3000);
       ::ResetEvent(hEvent[0]);
       ::ResetEvent(hEvent[1]);
       ::ResetEvent(hEvent[2]);
       if(!::HttpSendRequest(hRequest,NULL,0,NULL,0)) // 为什么失败???
        {
           //Sleep(3000);
           if(!ASYNC)// 同步
           {
               DWORD dwError = ::GetLastError();
                 cout<<"同步,HttpSendRequest failed,GetLastError=="<<dwError<<endl;
               return ;
           
           }
           else
           {
               Sleep(3000);
               DWORD dwError = ::GetLastError();
               cout<<"dwError=="<<dwError<<endl;
               if (dwError != ERROR_IO_PENDING) 
               {
                  cout<<"dwError != ERROR_IO_PENDING, so quit,dwError=="<<dwError<<endl;
                   return ;
               }
               else //
               {
                  cout<<"HttpSendRequest, so run WaitExitEvent"<<endl;
                   Sleep(3000);
                  //if(WaitExitEvent()!=2)//; // 等待成功创建 等待是否不对???
                   {
                          cout<<"had not recv complete event, so quit"<<endl;
                       //return ;
                   }
               }
           }
           
        }
       Sleep(3000);
       cout << "step 4: HttpSendRequest success!"<<endl;

       int bufh[1000];
       DWORD dwLen,dwIndex;
        /*if(!::HttpQueryInfo(hRequest,HTTP_QUERY_RAW_HEADERS_CRLF, bufh, &dwLen, &dwIndex))// 这句话???
        {
           //return E_FAIL;
           return;
        }
    */
       // 判断状态码;
       char m_dwStatusCode[90];
       DWORD dwStatusSize = sizeof(m_dwStatusCode);
       /*if (FALSE == ::HttpQueryInfo(hRequest,   // 查询失效??
           HTTP_QUERY_STATUS_CO DE |HTTP_QUERY_FLAG_NUMBER,
           &m_dwStatusCode,
           &dwStatusSize,
           NULL))   //获取返回状态码
        {
           return ;
        }
       //判断状态码是不是 200
       //if (HTTP_STATUS_OK != m_dwStatusCode)
        {
           //return ;
        }
    */

       DWORD dwByteToRead = 0;
       DWORD dwSizeOfRq = 4;
       DWORD dwBytes = 0;
       //这三个值分别存储文件的大小,HttpQueryInfo内容的大小和总共读取的字节数。
       //HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead,&dwSizeOfRq, NULL);
       //需要说明的是 HttpQueryInfo 并不进行网络操作,因此它不需要进行异步操作的处理。 
       if (!HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH |HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwByteToRead, &dwSizeOfRq, NULL))
       { // 这里失败了???
           
           DWORD dwError = ::GetLastError();
           cout<<"HttpQueryInfo failed, so return, GetLastError() =="<<dwError<<endl;
           return ;
        }
       FILE * pFile = fopen("e://baidu01.exe", "wb" );
       //ofstream mfile("out.txt");//定义文件输出流ouf,并关联到out.txt
        inti=0;
       DWORD leftB = dwByteToRead;
       cout<<"开始下载"<<endl;
       if( !ASYNC) // 同步下载
        {
           while(true)
           {
               const int MAX_BUFFER_SIZE = 65536;
               unsigned long nSize = 0;
               char szBuffer[MAX_BUFFER_SIZE+2];
               int num = MAX_BUFFER_SIZE;
               if( leftB < num);
               num = leftB;
               BOOL bRet = ::InternetReadFile(hRequest,szBuffer, num, &nSize); // 异步 需要等待

               leftB -= nSize;
               cout<<i++<<" size:"<<nSize<<endl;
               if(!bRet || nSize <= 0)
                   break;
               fwrite(szBuffer, sizeof(char), nSize,pFile);
           }
        }
       else // 异步下载
        {
           INTERNET_BUFFERS i_buf = {0};
           i_buf.dwStructSize = sizeof(INTERNET_BUFFERS);
           i_buf.lpvBuffer = new TCHAR[10242];
           i_buf.dwBufferLength = 10240;
            for( DWORD i=0;i<dwByteToRead;)
           {
               //重置读数据事件
               ::ResetEvent( hEvent[0]);
               int num = 10240;
               if(dwByteToRead-i<10240)
               {
                   num = dwByteToRead-i;
                      i_buf.dwBufferLength = dwByteToRead-i;
               }
               if (FALSE ==::InternetReadFileEx(hRequest,
                   &i_buf,
                   IRF_ASYNC,
                   NULL))
               {
                   if (ERROR_IO_PENDING== ::GetLastError())
                   {
                       if( NULL)//WaitExitEvent()!=2)
                       {
                          delete[] i_buf.lpvBuffer;
                          return ;
                       }
                   }
                   else 
                   {
                      cout<<"down failed,so return"<<endl;
                      delete[] i_buf.lpvBuffer;
                      return ;
                   }
               }
               else
               {
                   //在网络传输速度快,步长较小的情况下,
                   //InternetReadFileEx 经常会直接返回成功,
                   //因此要判断是否发生了用户要求终止子线程事件。
                   cout<<"网络很好,InternetReadFileEx返回true"<<endl;

                   // 暂不考虑用户退出
               }
               i += i_buf.dwBufferLength; // 最后一次写多了!!!
               fwrite(i_buf.lpvBuffer, sizeof(char),i_buf.dwBufferLength, pFile);
               cout<<"i=="<<i<<endl;
               //保存数据
                //通知主线程下载进度
                       
           }
        }
       InternetCloseHandle(hRequest);
       InternetCloseHandle(hConnect);
       InternetCloseHandle(hSession);
       cout<<"success download file"<<endl;
        
       return;
    }

    int main( void )
    {
        
       WinINet3(true,true);
       return 1;
    }

    void On InternetHandleCreated(HINTERNET hInternet, LPINTERNET_ASYNC_RESULTlpInetStatusResult)
    {
       if(NULL == lpInetStatusResult)
        {
           //ATLASSERT( 0 );
           return;
        }
       hFile = HINTERNET(lpInetStatusResult->dwResult);
       HINTERNET    hInet = HINTERNET(lpInetStatusResult->dwResult);
        DWORD       dwInetHandleType;
       DWORD        dwTypeLen = sizeof(dwInetHandleType);

       InternetQueryOption( hInet, INTERNET_OPTION_HANDLE_TYPE, &dwInetHandleType,&dwTypeLen);
       switch(dwInetHandleType) 
        {
       case INTERNET_HANDLE_TYPE_CONNECT_HTTP:
           //CloseInternetConnection(); //   这里是何意???? 通过回调 设置httpConnect
           hConnect = hInet;     // 
           break;
       case INTERNET_HANDLE_TYPE_HTTP_REQUEST:
           //CloseInternetFile();   //    这里是何意??    通过回调设置httpFile
           hRequest = hInet;    //
           break; 
       default:
           break;
        }
       cout<<"On InternetHandleCreated,so ::SetEvent(hEvent[0])"<<endl;
       // HANDLE已创建事件(异步控制)
       ::SetEvent(hEvent[0]);
    }
    void On InternetRequestComplete(HINTERNET hInternet,LPINTERNET_ASYNC_RESULT lpInetStatusResult)
    {

       if( lpInetStatusResult == NULL )
        {
           //ATLASSERT( 0 );
           return;
        }
       cout<<"On InternetRequestComplete,so ::SetEvent(hEvent[2])"<<endl;
       // 激发请求完成事件(异步控制)
       ::SetEvent(hEvent[0]);
    }

    void CALLBACK InternetStatusCallback(
                                     HINTERNET hInternet,
                                     DWORD_PTR dwContext,
                                     DWORD dwInternetStatus,
                                     LPVOID lpvStatusInformation,
                                     DWORD dwStatusInformationLength
                                      )
    {
       cout<<"进入回调"<<endl;
       switch (dwInternetStatus)
        {
       case INTERNET_STATUS_RESOLVING_NAME:
           break;
       case INTERNET_STATUS_NAME_RESOLVED:
           break;
       case INTERNET_STATUS_CONNECTING_TO_SERVER:
           break;
       case INTERNET_STATUS_CONNECTED_TO_SERVER:
           break;
       case INTERNET_STATUS_SENDING_REQUEST:
           break;
       case INTERNET_STATUS_REQUEST_SENT:
           break;
       case INTERNET_STATUS_RECEIVING_RESPONSE:
           break;
       case INTERNET_STATUS_RESPONSE_RECEIVED:
           break;
       case INTERNET_STATUS_CLOSING_CONNECTION:
           break;
       case INTERNET_STATUS_CONNECTION_CLOSED:
           break;
       case INTERNET_STATUS_HANDLE_CREATED:
           cout<<"回调是INTERNET_STATUS_HANDLE_CREATED"<<endl;
           On InternetHandleCreated(hInternet,LPINTERNET_ASYNC_RESULT(lpvStatusInformation)); // 传递了HINTERNET 这是精髓呀
           break;
       case INTERNET_STATUS_HANDLE_CLOSING:
           break;
       case INTERNET_STATUS_REQUEST_COMPLETE:
           cout<<"回调是INTERNET_STATUS_REQUEST_COMPLETE"<<endl;
           On InternetRequestComplete(hInternet,LPINTERNET_ASYNC_RESULT(lpvStatusInformation));
           break;
       case INTERNET_STATUS_REDIRECT:
       case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
       case INTERNET_STATUS_STATE_CHANGE:
       default:
           break;
        }
    }

    谢谢!


       网址:http://blog.csdn.net/jiht594/article/details/7481889

    展开全文
  • WinInet包装的Http协议,支持Http代理(HttpProxy),Socket4代理。
  • wininet实现GET和POST访问网页 易语言在线自学
  • 易语言WinInet模块源码
  • WinInet Http 异步封装类

    2018-09-06 15:44:53
    WinInet Http 异步封装类 异步:避免线程安全问题。提供上传下载文件方法
  • 易语言Wininet访问类v2.2模块源码例程程序调用API函数实现Wininet访问。 鱼刺
  • WinInet http post

    2014-02-12 17:30:20
    VC编程实现使用WinInet通过HTTP协议读取网上文件
  • 1、基于wininet的文件上传 2、测试时可使用hfs作为http服务端程序 3、有封装好的类,可直接使用 4、可能因为字符编码问题,需要自行调整
  • WinInet简单封装示例程序,支持HTTP头、Cookie、附加数据设置发送成功后可以查询返回Cookie、内容、消息头数据。部分函数如下: void ClearHeaders(); void AddHeader(const char* lpszName, const char* lpszValue)...
  • 易语言Wininet访问类v2.2模块源码
  • VC 6.0 使用WinInet通过HTTP协议读取网上文件  在一个按钮事件中定义了网络连接Session:  CInternetSession httpsession;//定义网络连接Session  CString Line;  CInternetFile* webfile=NULL;//定义一个文件...
  • wininet上传文件到ftp服务器,代码量很少,已测试成功,使用到项目中。
  • WinInet Component Suite v1.6.rar
  • WinInet库之FTP通信

    2021-10-09 23:47:51
    // 文件传输协议(File Transfer Protocol,简称FTP)用在互联网上文件的双向传输,是主用于文件的上传和下载...// 在Windows上,微软提供了WinInet(即Windows Internet)库用于方便网络程序的开发。WinInet支持FTP、HTTP
    // 文件传输协议(File Transfer Protocol,简称FTP)用在互联网上文件的双向传输,是主用于文件的上传和下载处理的协议。
    // 上传是指将文件从本地计算机中复制到远程主机上。下载是指将远程主机上的文件复制到本地计算机上。
    // FTP是专门为文件传输而生的,传输效率高,稳定性好。公司内部通常会有多个FTP服务器,用于共享公司内部的资料。
    
    // 在Windows上,微软提供了WinInet(即Windows Internet)库用于方便网络程序的开发。WinInet支持FTP、HTTP(s)、Gopher类型的网络开发。
    // 也就是有专门的WIN32 API函数。
    
    // PS:InternetOpen函数:
    // 功能:初始化一个应用程序,以使用WinInet函数。
    // 原型:HINTERNET InternetOpen(
    //         _In_ LPCTSTR lpszAgent,
    //         _In_ DWORD dwAccessType,
    //         _In_ LPCTSTR lpszProxyName,
    //         _In_ LPCTSTR lpszProxyBypass,
    //         _In_ DWORD dwFlags
    //      )
    // 参数:lpszAgent:指定调用WinInet函数的应用程序或实体的名称,也就是给定一个字符串,用于标识这个程序。
    //       dwAccessType:访问类型,参数可以是以下值之一:
    //           INTERNET_OPEN_TYPE_DIRECT:直接连接网络(不使用代理)
    //           INTERNET_OPEN_TYPE_PRECONFIG:获取代理或者直接从注册表中获取的配置,使用代理连接网络
    //           INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY:获取代理或者直接从注册表中获取的配置,并防止启用Microsoft JScript或互联网设置(INS)文件的使用
    //           INTERNET_OPEN_TYPE_PROXY:通过代理来请求,除非代理旁路列表中提供的名称解析绕过代理。在这种情况下,使用该功能。
    //       lpszProxyName:指定代理服务器的名称,如果dwAccessType为INTERNET_OPEN_TYPE_PROXY,则此参数应当设置为NULL
    //       lpszProxyBypass:指定可选列表的主机名或IP地址。如果dwAccessType设置为INTERNET_OPEN_TYPE_PROXY,则此参数省略为NULL
    //       dwFlags:可以是以下值的组合:
    //           INTERNET_FLAG_ASYNC:异步请求
    //           INTERNET_FLAG_FROM_CACHE:不进行网络请求,从缓存中返回所有实体。
    //           INTERNET_FLAG_OFFLINE:与INTERNET_FLAG_CACHE相同,不发出网络请求,所有实体都从缓存中返回。
    // 结果:成功,返回一个有效的句柄,失败,返回NULL。
    
    // PS:InternetConnect函数
    // 功能:建立互联网的连接。
    // 原型:HINTERNET WINAPI InternetConnect(
    //          HINTERNET hInternet,
    //          LPCTSTR lpszServerName,
    //          INTERNET_PORT nServerPort,
    //          LPCTSTR lpszUserName,
    //          lPCTSTR lpszPassword,
    //          DWORD dwService,
    //          DWORD dwFlags,
    //          DWORD dwContext
    //       )
    // 参数:hInternet:由InternetOpen函数返回的句柄。
    //       lpszServerName:连接的IP或主机名。
    //       nServerPort:连接的端口。
    //       lpszUserName:用户名,没有则设置NULL。
    //       lpszPassword:密码,没有则设置为NULL。
    //       dwService:使用的服务器类型,可以使用以下值之一:
    //          INTERNET_SERVICE_FTP = 1:连接到一个FTP服务器上。
    //          INTERNET_SERVICE_GOPHER = 2:连接到一个Gopher服务器上。
    //          INTERNET_SERVICE_HTTP = 3:连接到一个HTTP服务器上。
    //       dwFlags:文件传输形式及缓存标记,一般置零。
    //       dwContext:置为零。
    // 结果:成功返回非零,失败返回零。
    
    // PS:FtpOpenFile函数:
    // 功能:访问FTP服务器上的远程文件以执行读取或写入操作。
    // 原型:HINTERNET FtpOpenFile(
    //          _In_ HINTERNET hConnect,
    //          _In_ LPCTSTR lpszFileName,
    //          _In_ DWORD dwAccess,
    //          _In_ DWORD dwFlags,
    //          _In_ DWORD_PTR dwContext
    //      )
    // 参数:hConnect:由InternetConnect返回的句柄。
    //       lpszFileName:要访问的文件名。通常是URL+文件后缀
    //       dwAcess:可以是GENERIC_READ或者GENERIC_WRITE,但不能同时拥有。
    //       dwFlags:传输类型,可以是以下值之一:
    //           FTP_TRANSFER_TYPE_ASCII:使用FTP的ASCII传输方法。
    //           FTP_TRANSFER_TYPE_BINARY:使用FTP的图像传输方法传输文件,也就是二进制方式。
    //           FTP_TRANSFER_TYPE_UNKNOWN:默认使用FTP_TRANSFER_TYPE_BINARY。
    //           INTERNET_FLAG_TRANSFER_ASCII:以ASCII格式传输文件。
    //           INTERNET_FLAG_TRANSFER_BINARY:将文件作为二进制文件进行传输。
    //          控制文件的缓存,使用以下值之一:
    //           INTERNET_FLAG_HYPERLINK:强制重新加载。
    //           INTERNET_FLAG_NEED_FILE:如果无法缓存文件,则会创建临时文件。
    //           INTERNET_FLAG_RELOAD:强制从源服务器下载所请求的文件、对象或目录列表,而不是从缓存中下载。
    //           INTERNET_FLAG_RESYNCHRONIZE:如果资源资上次现在依赖已被修改,则请重新加载HTTP资源。
    //       dwContext:置零。
    // 结果:成功返回一个句柄,失败返回NULL。
    
    // PS:InternetWriteFile函数:
    // 功能:将数据写入打开的互联网文件。
    // 原型:BOOL InterneetWriteFile(
    //          _In_ HINTERNET hFile,
    //          _In_ LPVOID lpBuffer,
    //          _In_ DWORD dwNumberOfBytesToWrite,
    //          _Out_ LPDWORD lpdwNumberOfBytesWrite
    //       )
    // 参数:hFile:由FtpOpenFile函数返回的互联网文件句柄。
    //       lpBuffer:缓存区,要上传文件的数据。
    //       dwNumberOfBytesToWrite:缓存区大小。
    //       lpdwNumberOfBytesWrite:接收写入的字节量。
    // 结果:成功,返回TRUE,失败,返回FALSE。
    
    // PS:InternetReadFile函数:
    // 功能:从打开互联网文件中读取数据。
    // 原型:BOOL InternetReadFile(
    //         _In_ HINTERNET hFile,
    //         _Out_ LPVOID lpBuffer,
    //         _In_ DWORD dwNumberOfBytesToRead,
    //         _Out_ LPDWORD lpdwNumberOfBytesRead
    //      )
    // 参数:hFile:由FtpOpenFile函数打开的互联网文件的句柄。
    //       lpBuffer:接收数据的缓存区。
    //       dwNumberOfBytesToRead:预读取数据的字节量。
    //       lpdwNumberOfBytesRead:读取字节量的变量。
    // 结果:成功,返回TRUE,失败返回FALSE。
    
    // FTP的URL格式:FTP://账号:密码@主机/子目录或文件。示例:ftp://admin:123456@192.168.0.1/mycode/520.zip。
    
    // PS:基于WinInet库的FTP文件上传的流程如下:
    //     1.首先,调用InternetCrackUrl函数对URL进行分解,从URL中获取后续操作需要的信息。比如用户名、密码、host等。
    //     2.调用InternetOpen初始化WinInet库,建立网络会话,获取会话句柄。
    //     3.调用INternetConnect与服务器建立连接,并设置FTP数据传输方式。
    //     4.调用FtpOpenFile函数,根据文件路径,以GENERIC_WRITE的方式创建文件,并获取服务器上的文件句柄。
    //     5.调用InternetWriteFile函数把本地数据写入到互联网文件中,实现文件上传功能。
    //     6.关闭打开的句柄,释放缓存区资源。
    
    
    // PS:示例代码:
    
    // FTP文件上传
    
    BOOL Ftp_Upload(char* pszUploadUrl, BYTE* pUploadData, DWORD dwUploadDataSize)
    {
        // 变量(略)
    
        // 分解URL
        if (FALSE == Ftp_UrlCrack(pszUploadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH))
        {
            return FALSE;
        }
    
        // 拼接文件路径
        if (0 < ::lstrlen(szExtraInfo))
        {
            ::lstrcat(szUrlPath, szExtraInfo);
        }
    
        do 
        {
            // 建立会话
            hInternet = ::InternetOpen("FTP upload v1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
            if (NULL == hInternet)
            {
                Ftp_ShowError("InternetOpen");
                break;
            }
    
            // 建立会话
            hConnect = ::InternetConnect(hInternet, szHostName, szUserName, szPassword, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
            if (NULL == hConnect)
            {
                ::InternetCloseHandle(hInternet);
                Ftp_ShowError("InternetConnect");
                break;
            }
    
            // 打开FTP文件,与本地文件操作类似
            hFile = ::FtpOpenFile(hConnect, szUrlPath, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);
            if (NULL == hFile)
            {
                ::InternetCloseHandle(hInternet);
                ::InternetCloseHandle(hConnect);
                Ftp_ShowError("FtpOpenFile");
                break;
            }
    
            // 上传数据
            bRet = ::InternetWriteFile(hFile, pUploadData, dwUploadDataSize, &dwBytesReturn);
            if (FALSE == bRet)
            {
                ::InternetCloseHandle(hInternet);
                ::InternetCloseHandle(hConnect);
                ::InternetCloseHandle(hFile);
                Ftp_ShowError("InternetWriteFile");
                break;
            }
        } while (FALSE);
    
        // 释放内存并关闭句柄(略)
    
        return bRet;
    }
    
    // PS:基于WinInet的FTP文件下载步骤如下:
    //     1.使用InternetCrackUrl分解URL,获取用于后续操作需要的信息。
    //     2.调用InternetOpen函数初始化WinInet库,建立会话,获取会话句柄。
    //     3.调用InternetOpen函数与FTP服务器建立连接,获取连接句柄。
    //     4.调用FtpOpenFile函数,打开互联网文件,获取其句柄。
    //     5.调用FtpGetFileSize函数获取文件大小,并根据文件大小申请缓存区,用于存储文件数据。
    //     6.调用InternetReadFile函数,读取互联网文件数据到缓存区中,采用循环读取的方式。
    //     7.关闭打开的句柄,进行清理工作。
    
    // PS:示例代码:
    
    // FTP文件下载
    
    BOOL Ftp_Download(char* pszDownloadUrl, BYTE** ppDownloadData, DWORD* pdwDownloadDataSize)
    {
        // 变量(略)
    
        // 分解URL
        if (FALSE == Ftp_UrlCrack(pszDownloadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH))
        {
            return FALSE;
        }
    
        // 拼接文件路径
        if (0 < ::lstrlen(szExtraInfo))
        {
            ::lstrcat(szUrlPath, szExtraInfo);
        }
    
        do
        {
            // 建立会话
            hInternet = ::InternetOpen("Ftp Download v1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
            if (NULL == hInternet)
            {
                Ftp_ShowError("InternetOpen");
                break
            }
    
            // 建立连接
            hConnect = ::InternetConnect(hInternet, szHostName, INTERNET_INVALID_PORT_NUMBER, szUserName, szPassword, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
            if (NULL == hConnect)
            {
                ::InternetCloseHandle(hInternet);
                Ftp_ShowError("InternetConnect");
                break;
            }
    
            // 打开FTP文件
            hFile = ::FtpOpenFile(hConnect, szUrlPath, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_RELOAD, NULL);
            if (NULL == hFile)
            {
                ::InternetCloseHandle(hInternet);
                ::InternetCloseHandle(hConnect);
                Ftp_ShowError("FtpOpenFile");
                break;
            }
    
            // 获取文件大小
            dwDownloadDataSize = ::FtpGetFileSize(hFile, NULL);
    
            // 申请动态空间
            pDownloadData = new BYTE[dwDownloadDataSize];
            if (NULL == pDownloadData)
            {
                break;
            }
            ::RtlZeroMemory(pDownloadData, dwDownloadDataSize);
    
            // 申请一个小空间,用于循环接收数据
            pBuf = new BYTE[dwBufSize];
            if (NULL == pBuf)
            {
                break;;
            }
    
            // 循环接收数据
            do
            {
                ::RtlZeroMemory(pBuf, dwBufSize);
                // 接收数据
                bRet = ::InternetReadFile(hFile, pBuf, dwBufSize, &dwBytesReturn);
                if (FALSE == bRet)
                {
                    Ftp_ShowError("InternetReadFile");
                    break;
                }
                // 拷贝数据
                ::RtlCopyMemory((PVOID)(pDownloadData + dwOffset), pBuf, dwBytesReturn);
    
                // 更新数据
                dwOffset += dwBytesReturn;
            } while (dwOffset < dwDownloadDataSize);
        } while (FALSE);
    
        // 返回数据
        **pDownloadData = pDownloadData;
        *pdwDownloadDataSize = dwDownloadDataSize;
    
        // 关闭句柄,释放内存(略)
    
        return bRet;
    }
    
    
    
    
    
    
    展开全文
  • 简单WinInet封装示例程序, 封装类仅完成简单的Http GET与POST方法。
  • wininet.dll

    2020-12-29 00:16:32
    wininet.dll文件下载,解决找不到wininet.dll的问题wininet.dll控件常规安装方法(仅供参考):一、如果在运行某软件或编译程序时提示缺少、找不到wininet.dll等类似提示,您可将从脚本之家下载来的wininet.dll拷贝到...

    wininet.dll文件下载,解决找不到wininet.dll的问题

    wininet.dll控件常规安装方法(仅供参考):

    一、如果在运行某软件或编译程序时提示缺少、找不到wininet.dll等类似提示,您可将从脚本之家下载来的wininet.dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或者重新添加文件引用。

    二、您从我们网站下载下来文件之后,先将其解压(一般都是rar压缩包),

    然后根据您系统的情况选择X86/X64,X86为32位电脑,X64为64位电脑。默认都是支持32位系统的, 如果您不知道是X86还是X64,您可以看这篇文章。

    三、根据软件情况选择文件版本。此步骤比较复杂,如果是Windows的dll文件,

    版本号以5.0开头的或含有 nt 一般是windows2000的文件。

    版本号以5.1开头的或含有 xp、xpsp1、xpsp2、xpsp3 信息的一般是windowsXP的文件。

    版本号以6.0开头的或含有 longhorn、vista 信息的一般是windowsVista的文件。

    版本号以6.1开头的或含有 win7 信息的一般是windows7的文件。 如果不是windows的dll文件,则需要灵活查看版本号、描述、网友提供的信息、以及相关dll的版本号去判断。

    四、直接拷贝该文件到系统目录里:

    1、Windows 95/98/Me系统,将wininet.dll复制到C:\Windows\System目录下。

    2、Windows NT/2000系统,将wininet.dll复制到C:\WINNT\System32目录下。

    3、Windows XP/WIN7/win10系统(64位系统对应64位dll文件,32位系统对应32位dll文件),将wininet.dll复制到C:\Windows\System32目录下。

    4、如果您的系统是64位的请将32位的dll文件复制到C:\Windows\SysWOW64目录,具体的方法可以参考这篇文章:win7 64位旗舰版系统运行regsvr32.exe提示版本不兼容

    五、打开"开始-运行-输入regsvr32 wininet.dll",回车即可解决。希望脚本之家为您提供的wininet.dll对您有所帮助。

    通过脚本之家下载dll的朋友,可将下面的代码保存为“注册.bat“,放到dll文件同级目录(只要在同一个文件夹里面有这两个文件即可),双击注册.bat,就会自动完成wininet.dll注册(win98不支持)。

    下面是系统与dll版本对应的注册bat文件(64位的系统对应64位dll文件,32位系统对应32位的dll文件,如果64位的系统安装32位的dll文件,请将下面的system32替换为SysWOW64即可。)

    复制代码一般情况64位系统使用32位DLL

    @echo 开始注册

    copy wininet.dll %windir%\system32\

    regsvr32 %windir%\system32\wininet.dll /s

    @echo wininet.dll注册成功

    @pause

    展开全文
  • 利用WinInet技术 ,编写的基于MFC的FTP客户端。 实现了根目录下文件的上传、下载及删除操作,目录的操作有点问题就没完全实现,拿出来给大家共享一下,同时希望给与改进意见。 (Visual Studio 2010下测试。)

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,546
精华内容 3,018
关键字:

wininet