На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Все статьи должны быть оформлены согласно Правил оформления статей.
2. Любые обсуждения должны происходить в специальной теме, обсуждение в любых других темах раздела запрещены.
3. Запрещается писать статьи о создании и распространении вирусов, троянов и других вредоносных программ!
4. За грамотно написанные и правильно оформленные статьи авторы награждаются DigiMoney.

Дополнительные ссылки:
Желаю творческих успехов! ;)
Модераторы: Jin X
  
    > Загрузка Интернет страницы, через прокси-сервер, используя, библиотеку wininet. , Windows, MASM, Сеть
       
      Загрузка Интернет страницы, через прокси-сервер, используя, библиотеку wininet.

      Если пользоваться библиотекой winsock Интернет-страницу загрузить можно, но сделать это гораздо, сложнее ;), поэтому, я покажу - способ загрузки страницы по средствам библиотеки wininet. Плюс этот функционал будет работать, через прокси-сервер используя функцию UrlMkSetSessionOption из библиотеки urlmon.

      Функции WinInet API

      Разберём все функции по порядку и рассмотрим только те параметры, которые нам будут необходимы.

      InternetOpen

      Эта функция инициализирует WinInet и возвращает дескриптор, который необходим для вызова других функций WinInet. В случае неудачи возвращается NULL. Более подробную информацию об ошибке можно получить, вызвав функцию GetLastError.

      ExpandedWrap disabled
        HINTERNET WINAPI InternetOpen(
            LPCTSTR lpszAgent,
            DWORD dwAccessType,
            LPCTSTR lpszProxyName,
            LPCTSTR lpszProxyBypass,
            DWORD dwFlags
        );

      Параметры:
      ПараметрОписание
      lpszAgentЗадаёт имя приложения, которое используется как агент в HTTP протоколе. Сервер может определять агента с помощью переменной сервера HTTP_USER_AGENT. Если ваша программа собирается выдавать себя за MS Internet Explorer, передайте в этот параметр строчку "Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.0; .NET CLR 1.0.2914) "
      dwAccessTypeЗадаёт необходимый тип доступа (прямой или через прокси). Мы будем использовать значение INTERNET_OPEN_TYPE_PRECONFIG, которое устанавливает тип доступа в соответствии с установками в реестре.


      InternetConnect

      Эта функция открывает FTP, HTTP или Gopher сессию для заданного сайта.

      ExpandedWrap disabled
        HINTERNET InternetConnect(
            HINTERNET hInternet,
            LPCTSTR lpszServerName,
            INTERNET_PORT nServerPort,
            LPCTSTR lpszUsername,
            LPCTSTR lpszPassword,
            DWORD dwService,
            DWORD dwFlags,
            DWORD_PTR dwContext
        );

      Параметры:
      ПараметрОписание
      hInternetДескриптор, полученный вызовом предыдущей функции.
      lpszServerNameЗадаёт имя сервера. Это может быть обычное имя, например www.rsdn.ru, или адрес IP.
      nServerPortНомер TCP/IP порта к которому мы собираемся подсоединиться. Мы будем использовать значене INTERNET_DEFAULT_HTTP_PORT для обычных соединений, либо INTERNET_DEFAULT_HTTPS_PORT для SSL соединений.
      dwServiceТип сервиса - FTP, HTTP или Gopher. Мы будем использовать INTERNET_SERVICE_HTTP.


      InternetOpenUrl

      Функция принимает полный URL файла и возвращает указатель на него.

      ExpandedWrap disabled
        function InternetOpenUrl(hInet: HINTERNET;
                                lpszUrl: PChar;
                                lpszHeaders: PChar;
                                dwHeadersLength: DWORD;
                                dwFlags: DWORD;
                                dwContext: DWORD): HINTERNET; stdcall;

      Параметры:
      ПараметрОписание
      HInetуказатель, полученный после вызова InternetOpen.
      LpszUrURL , до которого нужно получить доступ. Обязательно должен начинаться с указания протокола, по которому будет происходить соединение. Поддерживаются следующие протоколы - ftp:, gopher:, http:, https:.
      LpszHeaders содержит заголовок HTTP запроса.
      DwHeadersLengthдлина заголовка. Если заголовок nil, то можно установить значение –1, и длина будет вычислена автоматически.
      DwFlagsфлаг, задающий дополнительные параметры перед выполнением функции. Вот некоторые его значения: INTERNET_ FLAG_EXISTING_CONNECT, INTERNET_FLAG_HYPERLINK, INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP, INTERNET_FLAG_NO_AUTO_REDIRECT, INTERNET_FLAG_NO_CACH E_WRITE, INTERNET_FLAG_NO_COOKIES.
      Возвращается значение TRUE, если соединение успешно, или FALSE - в противном случае.

      InternetReadFile

      Функция позволяет считывать данные, используя указатель, полученный в результате вызова InternetOpenUrl. Так же, как и все остальные функции, возвращает TRUE или FALSE. После завершения работы функции нужно освободить указатель Hfile, вызвав InternetCloseHandle(hUrlFile) .

      ExpandedWrap disabled
        function InternetReadFile(hFile: HINTERNET;
                                 lpBuffer: Pointer;
                                 dwNumberOfBytesToRead: DWORD;
                                 var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;

      Параметры:
      ПараметрОписание
      HFileуказатель на файл, полученный после вызова функции InternetOpenUrl
      LpBufferуказатель на буфер, куда будут заноситься данные.
      DwNumberOfBytesToReadчисло байт, которое нужно причитать
      lpdwNumberOfBytesReadсодержит количество прочитанных байтов. Устанавливается в 0 перед проверкой ошибок.

      Вот, в принципе, и все об самых основных функциях, которые я пользовала в данной статье они находятся в библе wininet . ;) Структура INTERNET_PROXY_INFO для использования в функции UrlMkSetSessionOption загрузки страницы через проксю, включает в себя следующие параметры:

      ExpandedWrap disabled
        typedef struct {
           DWORD dwAccessType;
           LPCTSTR lpszProxy;
           LPCTSTR lpszProxyBypass;
        }
      где dwAccessType – тип прокси для открытия страницы; lpszProxy – собственно сам адрес и порт(прокси-адрес); lpszProxyBypass – использование прокси -сервера имеющего пароль на загрузку страниц через него в данном случае нам это не требуется ;)

      Функция:
      ExpandedWrap disabled
        procedure UrlMkSetSessionOption (dwOption : Integer;
             var pBuffer : Pointer;
             dwBufferLength : Integer;
             dwReserved : Integer);
             stdcall; external 'URLMON' name 'UrlMkSetSessionOption'
      где dwOption - опции прокси; pBuffer – сама структура INTERNET_PROXY_INFO; dwBufferLength – размер структуры, ну и конечно флаги направления…

      Ну и наконец сам код, который загружает код страницы в поле :)

      ExpandedWrap disabled
        ; pwi.asm
        .386
        .model flat,stdcall
        option casemap:none
         
        include \masm32\include\windows.inc
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\wininet.inc
        include \masm32\include\urlmon.inc
         
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\urlmon.lib
        includelib \masm32\lib\wininet.lib
         
            _T macro p1, p2 ;макрос обработки строк
              local l
                ifb <p2>; Строка без имени
                    .data
                        l   db p1, 0
                    .code
                    exitm   <addr l>
                else    ; Строка с именем
                    .data
                        p1  db p2, 0
                    .code
                    exitm   <addr p1>
                endif
            endm
         
            IDC_INPUTDATA   equ 1000 ;окно приёма данных
            IDC_GETHOST     equ 1001 ;edit для хоста
            IDC_PROXI       equ 1002 ;edit для прокси
            IDC_LOAD        equ 1003 ;кнопка загрузить
            IDC_EXIT        equ 1004 ;выход
         
        ;=================
        ; Local prototypes
        ;=================
            WndProc     PROTO :DWORD,:DWORD,:DWORD,:DWORD
         
        .data
         ;прокси - адрес и порт  "218.7.13.186:80" < - пригодится ;)
          hInstance     dd 0
          AgetUser      db '}{}{}{',0;ЮзерАгент - название программы, которое будет отображатся на сервере
        ;дескрипторы wininet - функций
          hInternet     dd 0
          hOpenUrl      dd 0
          hConnect      dd 0
         
          ProxyHP       db 20 dup (?);буфер для прокси адреса
          
         .data?
          ByteWRite     dd ?;сколько байт записано
          StrokaIz      db 1024 dup (?) ;буфер для хоста
          iBuffer       dw 24000 dup (?);для получения данных
          busize        = $-iBuffer;размер буфера
          PiProxy       INTERNET_PROXY_INFO <>;структура для Proxy соединения
         
        .code
            start:
         
        ; #########################################################################
            invoke  GetModuleHandle, NULL
            mov     hInstance, eax
            invoke  DialogBoxParam,hInstance,_T("MAINDIALOG"),0,ADDR WndProc,0
            invoke  ExitProcess,eax
         
        ; #########################################################################
         
        WndProc proc hWin   :DWORD,
                     uMsg   :DWORD,
                     wParam :DWORD,
                     lParam :DWORD
         
            .if uMsg == WM_INITDIALOG
                invoke  SendMessage,hWin,WM_SETTEXT,0, _T("HtmlProxyGet")
         
            .elseif uMsg==WM_COMMAND
                mov     eax, wParam
                mov     edx, eax
                shr     edx, 16
                .if edx == BN_CLICKED
                    .if ax == IDC_LOAD;берём адрес и порт прокси - сервера из Edit-control
                        invoke  GetDlgItemText,hWin,IDC_PROXI,addr ProxyHP,-1
                        ;опции прокси сервера
                        mov     PiProxy.dwAccessType, INTERNET_OPEN_TYPE_PROXY
                        ;адрес и порт
                        mov     PiProxy.lpszProxy,offset ProxyHP
                        ;функция создания Proxy сессии   опции прокси   параметры структуры   размер структуры
                        invoke  UrlMkSetSessionOption,INTERNET_OPTION_PROXY,addr PiProxy, SizeOf(INTERNET_PROXY_INFO),0
                        ;хост из Edit- control
                        invoke  GetDlgItemText,hWin,IDC_GETHOST,addr StrokaIz,-1
                        ;инициализация WinInet и возвращает дескриптора, который
                        ;необходим для вызова других функций WinInet
                        invoke  InternetOpen,addr AgetUser,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
                        mov      hInternet,eax
                        ;открывает  HTTP  сессию для заданного сайта
                        invoke  InternetConnect, [hInternet],\;Дескриптор, полученный вызовом предыдущей функции.
                                                addr StrokaIz,\;хост
                                                INTERNET_DEFAULT_HTTP_PORT,\; для обычных соединений
                                                NULL,NULL,\
                                                INTERNET_SERVICE_HTTP,\;Тип сервиса
                                                0,\
                                                1
                        mov     [hConnect],eax
                        ;принимает полный URL файла и возвращает указатель на него.
                        invoke  InternetOpenUrl,[hInternet],\;указатель, полученный после вызова InternetOpen.
                          addr StrokaIz,\
                        0, 0,\
                        INTERNET_FLAG_RELOAD,\;флаг, задающий дополнительные параметры перед выполнением функции
                        0
                        mov     [hOpenUrl],eax
                        ;позволяет считывать данные, используя указатель,
                        ; полученный в результате вызова InternetOpenUrl.
                        ;Так же, как и все остальные функции, возвращает TRUE или FALSE
                        invoke  InternetReadFile, [hOpenUrl],\; указатель на файл, полученный после вызова функции InternetOpenUrl
                         addr (iBuffer),\;указатель на буфер, куда будут заноситься данные
                         busize ,\;число байт, которое нужно причитать
                          addr ByteWRite;содержит количество прочитанных байтов. Устанавливается в 0 перед проверкой ошибок.
                        ;выводим html - код
                        invoke  SetDlgItemText,hWin,IDC_INPUTDATA,  addr iBuffer
                        ;  закрытие дескрипторов вызванных wininet - функциями
                        invoke  InternetCloseHandle,hOpenUrl
                        invoke  InternetCloseHandle,hConnect
                        invoke  InternetCloseHandle,hInternet
                    .elseif ax == IDC_EXIT
                        invoke  SendMessage, hWin, WM_CLOSE, 0, 0
                    .endif
                .endif
         
            .elseif uMsg == WM_CLOSE
                invoke  EndDialog,hWin,0
         
            .else
                mov     eax, FALSE
                ret
            .endif
                mov     eax, TRUE
                ret
         
        WndProc endp
         
        ; ########################################################################
         
        end start

      Диалог:

      ExpandedWrap disabled
        // wi.rc
        #define DS_MODALFRAME   0x80L
         
        #define WS_POPUP        0x80000000L
        #define WS_CHILD        0x40000000L
        #define WS_VISIBLE      0x10000000L
        #define WS_CAPTION      0x00C00000L
        #define WS_BORDER       0x00800000L
        #define WS_SYSMENU      0x00080000L
        #define WS_GROUP        0x00020000L
        #define WS_TABSTOP      0x00010000L
         
        #define ES_LEFT         0x00000000L
        #define ES_MULTILINE    0x00000004L
        #define ES_AUTOVSCROLL  0x00000040L
        #define ES_AUTOHSCROLL  0x00000080L
         
        #define IDC_INPUTDATA   1000
        #define IDC_GETHOST     1001
        #define IDC_PROXI       1002
        #define IDC_LOAD        1003
        #define IDC_EXIT        1004
         
        MAINDIALOG DIALOG 10, 15, 282, 199
        STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
        CAPTION "MAINDIALOG"
        FONT 8, "MS Sans Serif"
        BEGIN
                CONTROL "", IDC_INPUTDATA, "EDIT", ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 8, 17, 264, 92
                CTEXT "Код страницы", -1, 8, 4, 264, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
                CTEXT "Нужный хост", -1, 8, 117, 264, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
                EDITTEXT IDC_GETHOST, 8, 128, 264, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
                CTEXT "Прокси", -1, 8, 148, 264, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
                EDITTEXT IDC_PROXI, 8, 160, 264, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
                DEFPUSHBUTTON "Загрузить", IDC_LOAD, 8, 180, 48, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
                PUSHBUTTON "Выход", IDC_EXIT, 224, 180, 48, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
        END

      Компилируется:

      ExpandedWrap disabled
        E:\masm32\bin\rc wi.rc
        E:\masm32\bin\ml /c /coff /nologo pwi.asm
        E:\masm32\bin\Link /SUBSYSTEM:WINDOWS pwi.obj wi.res
        Pause

      Вот и всего то. ;) Конечно, нужно не забывать про обработку ошибок, здесь – это специально не сделано, чтобы нагляднее показать работу wininet функций. Для загрузки огромных сайтов нужно увеличить размер буфера. Также не забываем про указание префикса http протокола - «http://». Ну и конечно, всё зависит от прокси-сервера; приведённый в коде адрес 218.7.13.186:80 , самый быстродейственный на данный момент.

      Удачи в компиляции. :rolleyes:
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0282 ]   [ 16 queries used ]   [ Generated: 19.03.24, 11:19 GMT ]