c++ для antigate.com

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by eldar85, 6 Aug 2010.

  1. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    такая проблемка, хотел сделать многопоточную программку для работы с антикапчей, но код который предлогается на офсайте antigate.com полное г...
    функции используются глабольные, переменные все глобальные и получается если прога работает в один поток то еще более менее, но если в несколько то полная лажа.


    вот код имеющегося класса антикапчи

    PHP:
      #include <QtGui>
     #include <c++/iostream>
     #include <c++/string
    #include <curl/curl.h> 
    #include <c++/fstream> 
       
    using namespace std;
      
    string contents;
      
    string ackey;  
     
    size_t handle_data(void *ptrsize_t sizesize_t nmembvoid *stream
    {     
     
    contents.clear();
         
    int numbytes size*nmemb;    
     
    char lastchar = *((char *) ptr numbytes 1);  
       *((
    char *) ptr numbytes 1) = '\0';     contents.append((char *)ptr);     contents.append(1,lastchar);  
       *((
    char *) ptr numbytes 1) = lastchar
          return 
    size*nmemb
     }
     
    bool myCheckIn(stringHTMLint *posstring strbool reg)
     { 
      if(
    HTML.size() < *pos str.size()) return false;  for(unsigned int i 0str.size(); i++)
      { 
      if(
    str[i] != HTML[+ *pos])
     return 
    false
     }
      *
    pos += str.size() - 1;  
     return 
    true;
     }
     
    int strpos(stringhaystack, const char needle)
     {      
      
    string tmp;  
       
    tmp=needle
        
    unsigned int hsize haystack.size(); 
        for (
    unsigned int i=0;i<hsize;i++)  
       {      
       if (
    myCheckIn(haystack, (int *) &i,tmp,true))
     return (
    i-tmp.size()+1);  
       }    
      return -
    1
    }
     
    string substr(stringstrint posint offset)
     {    
      
    int i
        
    string res
        for (
    i=pos;i<(pos+offset);i++)  
       {      
       
    res += str[i];   
      }     
     return 
    res
    }  
    void file_put_contents(char *namestring res
    {    
      
    ofstream fout(name); 
        
    fout << res
        
    fout.close(); 
     } 
     class 
    Captcha
     
    {
     public:  
       
    string tempstr;  
        
    QString unfuck(QString captchafile);
       }; 
      
    QString Captcha::unfuck(QString captchafile
    {
      
    QString captcha
      
    int captcha_id=0;
     
    CURL *hCurl NULLCURLcode cc;
     
    QString text;
     
    char error_buffer[1024];
     
    char tmp_char[256];  
      if (!
    hCurl)  
      { 
         
    cc curl_global_init(CURL_GLOBAL_ALL); 
          
    hCurl curl_easy_init();  
      }   
      if (
    hCurl)   
     {     
        
    text "Sending captcha...";   
        
    char *url "http://antigate.com/in.php"
          
    struct curl_httppost *post=NULL;  
       
    struct curl_httppost *last=NULL;     curl_easy_setopt(hCurlCURLOPT_WRITEFUNCTIONhandle_data);  
       
    curl_easy_setopt(hCurlCURLOPT_URLurl); 
        
    curl_easy_setopt(hCurlCURLOPT_ERRORBUFFER, &error_buffer);   
      
    curl_formadd(&post, &last,   CURLFORM_COPYNAME"method",   CURLFORM_COPYCONTENTS"post"CURLFORM_END); 
        
    curl_formadd(&post, &last,   CURLFORM_COPYNAME"key",   CURLFORM_COPYCONTENTSackey.c_str(), CURLFORM_END);   
      
    curl_formadd(&post, &last,   CURLFORM_COPYNAME"file",   CURLFORM_FILEcaptchafile.toStdString().c_str(), CURLFORM_CONTENTTYPE"image/jpeg"CURLFORM_END); 
            
    curl_easy_setopt(hCurlCURLOPT_HTTPPOSTpost); 
           
      
    curl_easy_perform(hCurl);  
           
    curl_formfree(post);
         
    curl_easy_cleanup(hCurl);   
      
    curl_global_cleanup(); 
           
       if (
    strpos(contents,"ERROR")!=-1)
         {     
        
    qDebug() << "ERROR!";   
          return 
    "1"
        }        
       
    QString gg contents.c_str(); 
        
    qDebug() << gg
        
    qDebug() << contents.c_str(); 
        
    tempstr=substr(contents,3,10); 
        
    qDebug() << tempstr.c_str();  
       
    captcha_id=atoi(tempstr.c_str());
         if(!
    captcha_id)  
       {       
      
    qDebug() << "captcha not load!!";  
          return 
    "1";  
       }     
      
    contents="";    
         
    sprintf(tmp_char,"http://antigate.com/res.php?key=%s&action=get&id=%d",ackey.c_str(),captcha_id);   
          
      
    qDebug() << "Starting recognize..."
         while(
    1)   
      {      
        
    Sleep(2000);   
                
    hCurl curl_easy_init();   
              
    curl_easy_setopt(hCurlCURLOPT_WRITEFUNCTIONhandle_data);  
               
    curl_easy_setopt(hCurlCURLOPT_URLtmp_char);       
          
    curl_easy_setopt(hCurlCURLOPT_ERRORBUFFER, &error_buffer);
                 
    curl_easy_perform(hCurl);             curl_easy_cleanup(hCurl); 
                
    curl_global_cleanup(); 
                if (
    strpos(contents,"ERROR")!=-1)   
              {       
               return 
    "1";     
            }         
        if (
    strpos(contents,"OK")!=-1)   
              {        
              
                 
    tempstr=substr(contents,3,30);   
                   
    qDebug() << "Recognized captcha: "
                     
    qDebug() << tempstr.c_str();     
               
    captcha tempstr.c_str();  
                    break;        
         }           
       
    contents="";   
       }   
        }
     else   
     {     }  
     return 
    captcha;
     }

    Хотелось бы убрать все эти глобальные функции и переменные, чтобы все было внутри класса, но попробовав сделать эти глобальные функции членнами класса, получается что курл их потом не видит в этой строке

    PHP:
    curl_easy_setopt(hCurlCURLOPT_WRITEFUNCTIONhandle_data);
    я так и не понял как функцию этого же члена класса определить в этой строке, как только не пробывал...
    понимаю что делаю не так, но прям никак недопрет что именно.
    кто нить сталкивался с подобной проблемой? или может большой знаток плюсов, посоветуйте как решить проблему плиз...
     
    #1 eldar85, 6 Aug 2010
    Last edited: 6 Aug 2010
  2. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    Пробовал сделать так, но как раз вот здесь и начинается проблема
     
  3. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    компилятор выдает
    error: invalid use of member (did you forget the '&' ?)

    на эти строки
    curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, handle_data);
     
  4. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    лучше конечно заново написать этот класс, единственное я не пойму какую функцию вот сюда нужно ставить
    curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, ???);
    что именно это строка вообще выполняет???
     
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, ???);
    этим ты задаешь калбек функцию которая будет каждый раз вызываться при приходе данных с сети.
    Лично я делал всё не на классах а на по обычному, с учетом того что при ините создавал спец структуру по которой мог определять в келбек функции для какого именно коннекта пришлы данные
     
  6. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    удалось переделать)) нужно было эту функцию статично создать))
    вот рабочий вариант, еще немного подправить для красоты кода, но уже все рабочее и единственная глобальная переменная это ключь антикапчи, но он и так для всех потоков одинаков так что тут даже лучше что он глобален))

     
  7. Lee_fx

    Lee_fx Elder - Старейшина

    Joined:
    27 Sep 2008
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    std::string нервно покуривает глазея на методы QString'a =)
    Раз программа на Qt, мне кажется использование родных для этой библиотеки классов было бы правильней, да и удобней они)
     
  8. keen6

    keen6 New Member

    Joined:
    7 Apr 2010
    Messages:
    46
    Likes Received:
    4
    Reputations:
    0
    Вот именно. Чем не устраивает QNetworkAccessManager ?
     
  9. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    да уж, чет рано я обрадывался)) совсем забыл что статические члены не прокатят для многопоточки))
    дело просто в тос что я более менее знаю курл, но совсем не знаю как пользоваться QNetworkAccessManager, поэтому и до сих пор вожусь с курлом. и вы думаете QNetworkAccessManager имеет такую же функциональность как курл? мне где то на форуме кто то ляпнул что он далеко не так мощен как курл...
    просто интересно мнение тех кто его уже использовал, на сколько он удобен...
     
  10. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    а использование курла и в правду очень затрудняет жизнь... если QNetworkAccessManager можно использовать так же хорошо как и курл то думаю конечно будет лучше осваивать его)) но опять же хотелось бы услышать совет от людей знающих побольше меня)
     
  11. keen6

    keen6 New Member

    Joined:
    7 Apr 2010
    Messages:
    46
    Likes Received:
    4
    Reputations:
    0
    QNetworkAccessManager думаю имеет все, что умеет curl. Однако его использование куда приятнее. Libcurl хорош тем ,что его можно воткнуть практически в любой язык. Соответственно, интеграция с самим языком (и средой) никакая.
     
  12. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    да но только хороший программист заточит Libcurl под свое окружение (напишет пачку врапперов) в любом языке и ему будет удобно а с QNetworkAccessManager где сядеш там и слезеш
     
  13. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    понятно, спасибо за советы, попробую пока поиспользовать оба варианта, QNetworkAccessManager как новшество для себя ну и курл, то к чему привык и посмотрю разницу) хотя в принципе я всегда собираюсь программировать именно на Qt так как мне он очень нравится, все удобно и развивается достаточно хорошо)
    попробую переписать класс для разгадки капчи на QNetworkAccessManager, посмотрю что получится... и самое хорошо что документация для QNetworkAccessManager еаписана на русском на кросплатформе, это уже плюс, потому что хоть я и знаю английский, но все же когда читаю на нем то усваиваю далеко не так как если бы читал на русском))
     
  14. keen6

    keen6 New Member

    Joined:
    7 Apr 2010
    Messages:
    46
    Likes Received:
    4
    Reputations:
    0
    Если писать с Qt, зачем юзать сторонние либы? Когда в нем и так все предусмотрено. Вот я к чему. Мне показалось, либо ты упомянул занятие велопроизводством? =D
     
  15. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    а все же как сделать функцию

    локальной, но не статической, чтобы на нее компилятор не ругался в строке

     
  16. keen6

    keen6 New Member

    Joined:
    7 Apr 2010
    Messages:
    46
    Likes Received:
    4
    Reputations:
    0
    У меня вот так:

    Code:
      static int write_proc(char *, size_t , size_t , std::string*);
     
  17. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,582
    Likes Received:
    1,310
    Reputations:
    1,557
    Файл:
    PHP:
    //---------------------------------------------------------------------------
    struct CaptchaFile
    {
        const 
    char *filename;
        
    FILE *stream;
    };
    //---------------------------------------------------------------------------
    static size_t CaptchaWrite(void *buffersize_t sizesize_t nmembvoid *stream)
    {
        
    struct CaptchaFile *out=(struct CaptchaFile *)stream;
        if(
    out && !out->stream)
        {
            
    out->stream=fopen(out->filename"wb");
            if(!
    out->stream)
                return -
    1;
        }
        return 
    fwrite(buffersizenmembout->stream);
    }
    //---------------------------------------------------------------------------
    PHP:
    struct curl_httppost *post=NULL;
    struct curl_httppost *last=NULL;

    curl_formadd(&post, &last,   CURLFORM_COPYNAME"method",   CURLFORM_COPYCONTENTS"post"CURLFORM_END);
    curl_formadd(&post, &last,   CURLFORM_COPYNAME"soft_id",   CURLFORM_COPYCONTENTS"5"CURLFORM_END);
    curl_formadd(&post, &last,   CURLFORM_COPYNAME"key",   CURLFORM_COPYCONTENTSapikey.c_str(), CURLFORM_END);
    curl_formadd(&post, &last,   CURLFORM_COPYNAME"file",   CURLFORM_FILEfilename.c_str(), CURLFORM_CONTENTTYPE"image/jpeg"CURLFORM_END);

    curl_easy_setopt(curlCURLOPT_URL"http://antigate.com/in.php");
    curl_easy_setopt(curlCURLOPT_HTTPPOSTpost);
    curl_easy_perform(curl);

    Память:
    PHP:
    //---------------------------------------------------------------------------
    static void *cap_realloc(void *ptrsize_t size)
    {
        return 
    ptr realloc(ptrsize) : malloc(size);
    }
    //---------------------------------------------------------------------------
    struct CaptchaBuffer
    {
        
    charmemory;
        
    size_t size;
    };
    //---------------------------------------------------------------------------
    static size_t CaptchaWrite(void *datasize_t sizesize_t nmembvoid *buffer)
    {
        
    size_t realsize size nmemb;
        
    struct CaptchaBuffer *mem = (struct CaptchaBuffer *)buffer;
        
    mem->memory = (char*)cap_realloc(mem->memorymem->size realsize 1);
        if(
    mem->memory)
        {
            
    memcpy(&(mem->memory[mem->size]), datarealsize);
            
    mem->size += realsize;
            
    mem->memory[mem->size] = 0;
        }
        return 
    realsize;
    }
    //---------------------------------------------------------------------------
    PHP:
    String VK::AntigateCheckCaptcha()
    {
        
    setopt(curlCURLOPT_HEADER 0);
        
    setopt(curlCURLOPT_PROXY "");
        
    setopt(curlCURLOPT_PROXYTYPE HTTP);

        
    struct curl_httppost *post NULL;
        
    struct curl_httppost *last NULL;
        
    formadd(&post, &last,   CURLFORM_COPYNAME"method",   CURLFORM_COPYCONTENTS"post"CURLFORM_END);
        
    formadd(&post, &last,   CURLFORM_COPYNAME"soft_id",   CURLFORM_COPYCONTENTS"5"CURLFORM_END);
        
    formadd(&post, &last,   CURLFORM_COPYNAME"key",   CURLFORM_COPYCONTENTSsAntigateKeyCURLFORM_END);
        
    formadd(&post, &last,   CURLFORM_COPYNAME"file",    CURLFORM_BUFFER"captcha.jpg"
                                
    CURLFORM_BUFFERPTRbufCaptcha.memoryCURLFORM_BUFFERLENGTHbufCaptcha.size,  
                                
    CURLFORM_CONTENTTYPE"image/jpeg"CURLFORM_END);

                        
        
    String sId "";
        
        
    sUrl "http://antigate.com/in.php";
        
    sPage "";
        
    setopt(curlCURLOPT_URLsUrl);
        
    setopt(curlCURLOPT_HTTPPOSTpost);
        
    perform(curl);
        
    setopt(curlCURLOPT_POST0);
        
    formfree(post);

        if(
    sPage.Pos("\r"))
            
    sPage.SetLength(sPage.Pos("\r") - 1);
                
        if(
    sPage.IsEmpty())
            return 
    "ERROR_REPLY_IN";
        else if(
    sPage.Pos("ERROR_"))
            return 
    sPage;
        else if(
    sPage.Pos("OK"))
            
    sId sPage.SubString(sPage.Pos("|") + 1sPage.Length() - sPage.Pos("|"));

        if(
    sId.IsEmpty())
            return 
    "ERROR_BAD_CAPTCHA_ID";
            
        for(
    int i 012; ++i)
        {
            
    Sleep(5000);

            
    sUrl =     "http://antigate.com/res.php?key=" +
                    
    sAntigateKey +
                    
    "&action=get&id=" +
                    
    sId;
            
    sPage "";
            
    setopt(curlCURLOPT_URLsUrl);
            
    perform(curl);

            if(
    sPage.Pos("\r"))
                
    sPage.SetLength(sPage.Pos("\r") - 1);
                
            if(
    sPage.IsEmpty())
                return 
    "ERROR_REPLY_GET";
            else if(
    sPage.Pos("ERROR_"))
                return 
    sPage;
            else if(
    sPage.Pos("OK"))
            {
                
    sPage.Delete(1sPage.Pos("|"));
                return 
    sPage;
            }
        }
        
        return 
    "ERROR_TIMEOUT";
    }
     
  18. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    спасибо большое. пробую сделать класс для работы на QNetworkAccessManager но нифига не пойму одного, вот сделал такой код:

    net.h

    net.cpp

    и вот вызов

     
  19. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    по идее exec() должен вернуть buffer с данными, он он гад ничего не возращает, причем в слоте
    загрузка производится, но exec() завершается до того как произойдет вывод reply в buffer. В чем же проблема???
     
  20. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    хотел спросить у M_script, ты такой код в многопоточных программах используешь? мне просто интересно у тебя капча в один и тот же файл сохраняется, а как быть если к примеру 10 потоков обратятся к разгадке капчи, получается они перезапишут файл captcha.jpg и разгадка будет неверной или я ошибаюсь?