cURL в C#

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

  1. geforse

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

    Joined:
    2 Mar 2008
    Messages:
    617
    Likes Received:
    290
    Reputations:
    1
    Очень много сообщений тут и в интернете о том, как установить cURL в C#.
    Немного повозившись с этой библиотекой и успешно установив её, решил написать данный мануал, в целях индексации гуглом и прочтении нуждающимися :)

    • Скачиваем саму библиотеку
    • Создаём новый проект WinForms
    • Проект->Добавить ссылку->Обзор и выбираем LibCurlNet.dll из папки bin
    • Компилируем .exe и рядом с ним кладём libcurl.dll и LibCurlShim.dll из папки bin
    • Проект->Добавить класс->HTTP.cs (он представлен ниже)
    • Создаём textBox и кнопку, на которую вешаем такой код:
      PHP:
                  HTTP http = new HTTP();
       
      http.CurlInit(); // Инициализация cURL'а
       
      string page http.HTTPGet("https://forum.antichat.ru/",""); // URL и proxy
       
      textBox1.Text page;

    Вот и всё :rolleyes:


    HTTP.cs

    PHP:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using SeasideResearch.LibCurlNet;
    using System.IO;

    namespace 
    WindowsFormsApplication1 // ТУТ ТОЛЬКО СВОЙ NAMESPACE ПРОПИШИТЕ!
    {
        class 
    HTTP
        
    {
            private static 
    Easy easy;
            private static 
    Random rand = new Random();
            private static 
    string SockBuff;
            private static 
    string CookieFile AppDomain.CurrentDomain.BaseDirectory "cookie" rand.Next(09) + rand.Next(09) + rand.Next(09) + rand.Next(09) + rand.Next(09) + rand.Next(09) + rand.Next(09) + ".txt";
            public static 
    string UserAgent "Mozilla 5.0";
            public static 
    string Proxy "";
            public 
    string referer "";

            public 
    void Dispose()
            {
                
    ClearCookies();
            }
            public 
    string getCookieFile()
            {
                return 
    CookieFile;
            }

            public 
    void CurlInit()
            {
                
    Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
            }

            public 
    void ClearCookies()
            {
                if (
    File.Exists(CookieFile))
                {
                    
    File.Delete(CookieFile);
                }

            }

            public 
    string HTTPGet(string URLstring Proxy)
            {
                
    easy = new Easy();
                
    SockBuff "";

                try
                {
                    
    Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);

                    
    easy.SetOpt(CURLoption.CURLOPT_URLURL);
                    
    easy.SetOpt(CURLoption.CURLOPT_TIMEOUT"60");
                    
    easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTIONwf);
                    
    easy.SetOpt(CURLoption.CURLOPT_USERAGENTUserAgent);
                    
    easy.SetOpt(CURLoption.CURLOPT_COOKIEFILECookieFile);
                    
    easy.SetOpt(CURLoption.CURLOPT_COOKIEJARCookieFile);
                    
    easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATIONtrue);

                    if (
    URL.Contains("https"))
                    {
                        
    easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST1);
                        
    easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER0);
                    }

                    if (
    Proxy != "")
                    {
                        
    easy.SetOpt(CURLoption.CURLOPT_PROXYProxy);
                        
    easy.SetOpt(CURLoption.CURLOPT_PROXYTYPECURLproxyType.CURLPROXY_HTTP);
                    }

                    
    easy.Perform();
                    
    easy.Cleanup();

                }
                catch
                {
                    
    Console.WriteLine("Get Request Error");
                }

                return 
    SockBuff;
            }

            public 
    string HTTPPost(string URLstring Contentstring Proxy)
            {
                
    easy = new Easy();
                
    SockBuff "";

                try
                {
                    
    Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);

                    
    easy.SetOpt(CURLoption.CURLOPT_URLURL);
                    
    easy.SetOpt(CURLoption.CURLOPT_TIMEOUT"60");
                    
    easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTIONwf);
                    
    easy.SetOpt(CURLoption.CURLOPT_USERAGENTUserAgent);
                    
    easy.SetOpt(CURLoption.CURLOPT_COOKIEFILECookieFile);
                    
    easy.SetOpt(CURLoption.CURLOPT_COOKIEJARCookieFile);
                    
    //easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER
                    
    easy.SetOpt(CURLoption.CURLOPT_REFERERreferer);
                    
    //easy.SetOpt(CURLoption.CURLOPT_POSTFIELDSIZE, Content.Length);
                    
    easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATIONtrue);

                    
    //easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, 1);

                    
    easy.SetOpt(CURLoption.CURLOPT_POSTtrue);
                    
    easy.SetOpt(CURLoption.CURLOPT_POSTFIELDSContent);


                    if (
    URL.Contains("https"))
                    {
                        
    easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST1);
                        
    easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER0);
                    }

                    if (
    Proxy != "")
                    {
                        
    easy.SetOpt(CURLoption.CURLOPT_PROXYProxy);
                        
    easy.SetOpt(CURLoption.CURLOPT_PROXYTYPECURLproxyType.CURLPROXY_HTTP);
                    }

                    
    easy.Perform();
                    
    easy.Cleanup();

                }
                catch
                {

                }
                return 
    SockBuff;

            }

            public 
    string SafeString(string data)
            {
                return 
    Curl.Escape(datadata.Length);
            }

            public 
    string UnSafeString(string data)
            {
                return 
    Curl.Unescape(datadata.Length);
            }

            public static 
    Int32 OnWriteData(Byte[] bufInt32 sizeInt32 nmembObject extraData)
            {
                
    // Console.Write(System.Text.Encoding.UTF8.GetString(buf));
                
    SockBuff SockBuff System.Text.Encoding.UTF8.GetString(buf);

                return 
    size nmemb;
            }

        }
    }

     
    #1 geforse, 17 Aug 2010
    Last edited: 17 Aug 2010
    3 people like this.
  2. AquaKlaster

    AquaKlaster Active Member

    Joined:
    9 Mar 2009
    Messages:
    0
    Likes Received:
    204
    Reputations:
    23
    Спс, искал=) +1
     
  3. zeppe1in

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

    Joined:
    12 Jul 2006
    Messages:
    343
    Likes Received:
    66
    Reputations:
    18
    а не подскажете он с носками работает? socks4/5.
     
  4. .ATK

    .ATK Active Member

    Joined:
    20 Feb 2009
    Messages:
    143
    Likes Received:
    111
    Reputations:
    9
    ссылки на библиотеки было бы не плохо добавить ;)
     
  5. AquaKlaster

    AquaKlaster Active Member

    Joined:
    9 Mar 2009
    Messages:
    0
    Likes Received:
    204
    Reputations:
    23
    Да, но нужно в коде менять тип прокси.
    Вот здесь:
    Code:
    if (Proxy != "") 
                    { 
                        easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy); 
                        easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, CURLproxyType.CURLPROXY_HTTP); 
                    }
    меняем CURLPROXY_HTTP на CURLPROXY_SOCKS4 или CURLPROXY_SOCKS5 зависит от типа сокса.
     
  6. geforse

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

    Joined:
    2 Mar 2008
    Messages:
    617
    Likes Received:
    290
    Reputations:
    1
    Так я же добавил, в самом начале стоит ссылка на офф.сайт курла, скачиваем библиотеки и добавляем себе в проект.
    + там идут исходники и можно откомпилировать только то, что тебе необходимо.
    ======================

    отпишите, кто знает, как в потоках работать с курлом, не могу разобраться, да и мануалов нигде нет :(
     
  7. IgrikX

    IgrikX New Member

    Joined:
    13 Aug 2009
    Messages:
    114
    Likes Received:
    1
    Reputations:
    -3
    так потоки создавать самому, как обычно.
    P.S в PHP с помощью curl пожно было создавать "потоки", там создавать нужно мультикурл.
     
  8. geforse

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

    Joined:
    2 Mar 2008
    Messages:
    617
    Likes Received:
    290
    Reputations:
    1
    Да нет, видно не всё так просто, т.к. выдаёт Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
     
  9. IgrikX

    IgrikX New Member

    Joined:
    13 Aug 2009
    Messages:
    114
    Likes Received:
    1
    Reputations:
    -3
    тогда я пас, но самому стало интересно.
     
  10. zeppe1in

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

    Joined:
    12 Jul 2006
    Messages:
    343
    Likes Received:
    66
    Reputations:
    18
    в samples
    ShareDemo: Retrieve two URLs in separate threads, with synchronized
    access to DNS and cookie data via the Share object.
    не пробовали?
     
  11. geforse

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

    Joined:
    2 Mar 2008
    Messages:
    617
    Likes Received:
    290
    Reputations:
    1
    Да, вроде оно, буду разбираться, спасибо :)
     
  12. D4mp

    D4mp Banned

    Joined:
    28 Jul 2010
    Messages:
    12
    Likes Received:
    0
    Reputations:
    0
    Господа, может кто решил проблему? С доступом к памяти разобрался, но другая проблема. Тупо все перемешивается =)
    Code:
    
    public class EasyThread
    {
        private static Easy.WriteFunction wf;
    
        private static string Buff;
        private static int thr_num;
    
        public static string UserAgent = "Mozilla 5.0";
    
        // static class constructor to create static delegate
        static EasyThread()
        {
            Console.WriteLine("EasyThread class constructor");
            wf = new Easy.WriteFunction(OnWriteData);
        }
    
        // instance constructor for url
        public EasyThread(int thr)
        {
            thr_num = thr;
    
            if (File.Exists(thr_num + "_cookie.txt"))
            {
                File.Delete(thr_num + "_cookie.txt");
            }
    
        }
    
    
        public string EasyGet(string url)
        {
            string CookieFile = thr_num + "_cookie.txt";
            Easy easy = new Easy();
            easy.SetOpt(CURLoption.CURLOPT_URL, url);
            easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
            easy.SetOpt(CURLoption.CURLOPT_WRITEDATA, url);
            easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile);
            easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile);
            easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent);
            easy.Perform();
            easy.Cleanup();
            return Buff;
    
        }
    
        public string EasyPost(string url, string Content, string Proxy)
        {
            Buff = "";
            string CookieFile = thr_num + "_cookie.txt";
            Easy easy = new Easy();
            easy.SetOpt(CURLoption.CURLOPT_URL, url);
            easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
            easy.SetOpt(CURLoption.CURLOPT_WRITEDATA, url);
            easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile);
            easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile);
            easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent);
            easy.SetOpt(CURLoption.CURLOPT_REFERER, "");
            easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
            easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, "60");
    
            easy.SetOpt(CURLoption.CURLOPT_POST, true);
            easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS, Content);
    
            if (url.Contains("https"))
            {
                easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1);
                easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0);
            }
    
            easy.Perform();
            easy.Cleanup();
            return Buff;
    
        }
    
        public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb,
            Object extraData)
        {
            Buff = Buff + System.Text.Encoding.UTF8.GetString(buf);
    
            return size * nmemb;
        }
    
    Проблема в том, что переменная Buff статическая, а изменить функцию на которую ссылается делегат, я не могу. Вообще избавиться-бы тут от статичной функции и самой переменной =)) А в мануалах в основном только вывод на командную стоку... Кто что подскажет?
     
  13. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    Ребят, кто нить нашел решение многопоточности с Курлом?

    Я вот вроде избавился от статичности:


    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using SeasideResearch.LibCurlNet;
    using System.IO;
    using System.Threading;
    
    namespace MyWindow
    {
        class Network
        {
            Random rand = new Random();
            private String buffer;
            private string CookieFile;
            private string UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0";
            private string referer = "";
            private string encoding = "UTF-8";
            private bool followLocation = false;
            public static CURLproxyType type = CURLproxyType.CURLPROXY_HTTP;
    
            public Network()
            {
                Thread.Sleep(rand.Next(1000));
                CookieFile = AppDomain.CurrentDomain.BaseDirectory + "cookie" + rand.Next(0, 9) + rand.Next(0, 9) + rand.Next(0, 9) + rand.Next(0, 9) + rand.Next(0, 9) + rand.Next(0, 9) + rand.Next(0, 9) + ".txt";
            }
    
            public static void SetProxyTypeHTTP()
            {
                type = CURLproxyType.CURLPROXY_HTTP;
            }
    
            public static void SetProxyTypeSocks4()
            {
                type = CURLproxyType.CURLPROXY_SOCKS4;
            }
    
            public static void SetProxyTypeSocks5()
            {
                type = CURLproxyType.CURLPROXY_SOCKS5;
            }
    
            public void SetEncoding(bool UTF8)
            {
                if (UTF8)
                    encoding = "UTF-8";
                else
                    encoding = "windows-1251";
            }
    
            public string getCookieFile()
            {
                return CookieFile;
            }
    
            public void CurlInit()
            {
                Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
            }
    
            public void ClearCookies()
            {
                if (File.Exists(CookieFile))
                {
                    File.Delete(CookieFile);
                }
    
            }
    
            public Network FollowLocation()
            {
                followLocation = true;
                return this;
            }
    
            public string HTTPGet(string URL, string Proxy)
            {
                Easy easy = new Easy();
                buffer = "";
    
                try
                {
                    Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
    
                    easy.SetOpt(CURLoption.CURLOPT_URL, URL);
                    //easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, 60);
                    easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent);
                    easy.SetOpt(CURLoption.CURLOPT_COOKIE, true);
                    easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile);
                    easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile);
                    easy.SetOpt(CURLoption.CURLOPT_AUTOREFERER, 1);
                    easy.SetOpt(CURLoption.CURLOPT_HTTPGET, true);
                    easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, 1);
                    easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
                    
                    if (followLocation)
                    {
                        easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, 1);
                        followLocation = false;
                    }
    
                    //easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, 1); 
    
                    if (URL.Contains("https"))
                    {
                        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1);
                        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0);
                    }
    
                    if (Proxy != "")
                    {
                        easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy);
                        easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, type);
                    }
    
                    easy.Perform();
                    easy.Cleanup();
                    
    
                }
                catch
                {
                    Console.WriteLine("Get Request Error");
                }
    
                return buffer.ToString();
            }
    
            public string HTTPPost(string URL, string Content, string Proxy)
            {
                Easy easy = new Easy();
                buffer = "";
    
                try
                {
                    Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
    
                    easy.SetOpt(CURLoption.CURLOPT_URL, URL);
                    //easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, 60);
                    easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
                    easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent);
                    easy.SetOpt(CURLoption.CURLOPT_COOKIE, true);
                    easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile);
                    easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile);
                    easy.SetOpt(CURLoption.CURLOPT_REFERER, referer);
                    easy.SetOpt(CURLoption.CURLOPT_AUTOREFERER, 1);
    
                    if (followLocation)
                    {
                        easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, 1);
                        followLocation = false;
                    }
    
                    //easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, 1); 
    
                    easy.SetOpt(CURLoption.CURLOPT_POST, true);
                    easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS, Content);
    
    
                    if (URL.Contains("https"))
                    {
                        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1);
                        easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0);
                    }
    
                    if (Proxy != "")
                    {
                        easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy);
                        easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, type);
                    }
    
                    easy.Perform();
                    easy.Cleanup();
    
                }
                catch
                {
    
                }
    
                return buffer.ToString();
            }
    
            public string SafeString(string data)
            {
                return Curl.Escape(data, data.Length);
            }
    
            public string UnSafeString(string data)
            {
                return Curl.Unescape(data, data.Length);
            }
    
            public Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
            {
                buffer += System.Text.Encoding.GetEncoding(encoding).GetString(buf);
                return size * nmemb;
            }
    
        }
    }
    
    
    но проблемы остались. В одном потоке работает прекрасно, как только несколько потоков запускаешь, так буфер с ответом вечно пустой. Такое ощущение что у него еще где то что то статичное осталось. По идее в коде у меня я сделал статичными только тип проксей, но это никак не будет влиять на работу программы.
    Использовал стандартный HTTPRequest, но он не поддерживает Socks5, а они очень нужны. Потом пробовал у викингов VKEngine, но он глючный сильно. Для Вконтакте еще более менее работает, для остальных сайтов не стабильно очень... то не хочет урл нормально брать если он очень длинный, то неизвестный хост ошибку выдает, то как будто обрезает урл, в общем не дело.
    Решил вот Курл попробовать, он так хорошо в 1 потоке отработал, аж обрадывался что нашел наконец то что нужно, но стоило запустить в нескольких, как все пошло прахом... Может кто увидет что не так в коде, подскажите пожалуйста...
     
    #13 eldar85, 20 Aug 2011
    Last edited: 20 Aug 2011
  14. FireFenix

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

    Joined:
    3 Jun 2009
    Messages:
    390
    Likes Received:
    115
    Reputations:
    23
    Я конечно всё понимаю, но чем не угодил обычный HttpWebRequest и HttpWebResponse?
    Ну да, есть минус что нельзя работать с соксами, но без них вроде правильнее это юзать :)
     
    1 person likes this.
  15. eldar85

    eldar85 New Member

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

    inCode Member

    Joined:
    20 Jun 2011
    Messages:
    141
    Likes Received:
    22
    Reputations:
    5
    есть еще минус в том, что не все кукисы обрабатывает куки контейнер при загрузке на нттпреквесте, приходится писать дополнительный код. А он еще не для всех ресурсов работает. + как вариант в одном из проектов нужно было что-то между методами webbrowser и httprequesta. В итоге пришлось писать все на сокетах.
    Как вариант можно еще переписать библиотечку менталис под свои нужды)
     
  17. eldar85

    eldar85 New Member

    Joined:
    27 Aug 2009
    Messages:
    126
    Likes Received:
    1
    Reputations:
    0
    Это точно, если есть особенно аторедирект, то кукисы тут же теряются. Или если логиг происходит на 111.host.com то потом на просто host.com куки не будут привязаны... но в принципи с куками я решил проблему в ХТТПрекуесте, но все равно нету сокетов, а всем как на зло они нужны...
    А что за библиотека менталис?
     
  18. inCode

    inCode Member

    Joined:
    20 Jun 2011
    Messages:
    141
    Likes Received:
    22
    Reputations:
    5
    http://kbyte.ru/ru/Programming/Sources.aspx?id=1083&mode=show не реклама
    опен сорс + длл хорошие коменты
     
  19. eldar85

    eldar85 New Member

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

    eldar85 New Member

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