Очень много сообщений тут и в интернете о том, как установить 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; Вот и всё 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(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 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 URL, string Proxy) { easy = new Easy(); SockBuff = ""; 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_COOKIEFILE, CookieFile); easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile); easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true); 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, CURLproxyType.CURLPROXY_HTTP); } easy.Perform(); easy.Cleanup(); } catch { Console.WriteLine("Get Request Error"); } return SockBuff; } public string HTTPPost(string URL, string Content, string Proxy) { easy = new Easy(); SockBuff = ""; 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_COOKIEFILE, CookieFile); easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile); //easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER easy.SetOpt(CURLoption.CURLOPT_REFERER, referer); //easy.SetOpt(CURLoption.CURLOPT_POSTFIELDSIZE, Content.Length); easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true); //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, CURLproxyType.CURLPROXY_HTTP); } easy.Perform(); easy.Cleanup(); } catch { } return SockBuff; } public string SafeString(string data) { return Curl.Escape(data, data.Length); } public string UnSafeString(string data) { return Curl.Unescape(data, data.Length); } public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData) { // Console.Write(System.Text.Encoding.UTF8.GetString(buf)); SockBuff = SockBuff + System.Text.Encoding.UTF8.GetString(buf); return size * nmemb; } } }
Да, но нужно в коде менять тип прокси. Вот здесь: Code: if (Proxy != "") { easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy); easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, CURLproxyType.CURLPROXY_HTTP); } меняем CURLPROXY_HTTP на CURLPROXY_SOCKS4 или CURLPROXY_SOCKS5 зависит от типа сокса.
Так я же добавил, в самом начале стоит ссылка на офф.сайт курла, скачиваем библиотеки и добавляем себе в проект. + там идут исходники и можно откомпилировать только то, что тебе необходимо. ====================== отпишите, кто знает, как в потоках работать с курлом, не могу разобраться, да и мануалов нигде нет
так потоки создавать самому, как обычно. P.S в PHP с помощью curl пожно было создавать "потоки", там создавать нужно мультикурл.
Да нет, видно не всё так просто, т.к. выдаёт Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в samples ShareDemo: Retrieve two URLs in separate threads, with synchronized access to DNS and cookie data via the Share object. не пробовали?
Господа, может кто решил проблему? С доступом к памяти разобрался, но другая проблема. Тупо все перемешивается =) 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 статическая, а изменить функцию на которую ссылается делегат, я не могу. Вообще избавиться-бы тут от статичной функции и самой переменной =)) А в мануалах в основном только вывод на командную стоку... Кто что подскажет?
Ребят, кто нить нашел решение многопоточности с Курлом? Я вот вроде избавился от статичности: 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 потоке отработал, аж обрадывался что нашел наконец то что нужно, но стоило запустить в нескольких, как все пошло прахом... Может кто увидет что не так в коде, подскажите пожалуйста...
Я конечно всё понимаю, но чем не угодил обычный HttpWebRequest и HttpWebResponse? Ну да, есть минус что нельзя работать с соксами, но без них вроде правильнее это юзать
Так тем и не угодил что соксы нельзя юзать. Если бы можно было бы, то было бы вообще прекрастно, к тому же я не сторонник левых библиотек, но куда деваться если он не поддерживает всего необходимого, в данном случае сосксы.
есть еще минус в том, что не все кукисы обрабатывает куки контейнер при загрузке на нттпреквесте, приходится писать дополнительный код. А он еще не для всех ресурсов работает. + как вариант в одном из проектов нужно было что-то между методами webbrowser и httprequesta. В итоге пришлось писать все на сокетах. Как вариант можно еще переписать библиотечку менталис под свои нужды)
Это точно, если есть особенно аторедирект, то кукисы тут же теряются. Или если логиг происходит на 111.host.com то потом на просто host.com куки не будут привязаны... но в принципи с куками я решил проблему в ХТТПрекуесте, но все равно нету сокетов, а всем как на зло они нужны... А что за библиотека менталис?
http://kbyte.ru/ru/Programming/Sources.aspx?id=1083&mode=show не реклама опен сорс + длл хорошие коменты
я посмотрел менталис, он не удобный... хотелось бы все же найти что то более удобное типа курла... все таки переходил на шарп с плюсов и думал что будет все проще и быстрее и вроде бы так оно и шло пока не столкнулся с соксами...
и еще интересно все же почему курл не работает в многопотоке. ведь в одном потоке все прекрасно. почему же в нескольких такая фигня...