【问题标题】:Libcurl via threadsLibcurl 通过线程
【发布时间】:2011-10-13 09:31:02
【问题描述】:

我正在使用 c# 编写程序(C# 和面向对象的编程新手) 我正在尝试在多个线程中下载页面。仅运行 1 个线程时没有问题。当我运行多个时,问题就开始了。

似乎所有线程都将下载的信息保存在同一个变量 SockBuff 中,但我不知道如何解决这个问题。

建议?

这里是代码

当我点击按钮时程序启动。

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        void TestaThread_1()
        {
            Random RandomNumber = new Random();
            int rand = RandomNumber.Next(99);

            HTTP cURL = new HTTP();
            cURL.CurlInit();
            String data = cURL.HTTPGet("http://google.com", "", "fails" + rand.ToString() + ".html");
            HTTP.save_file("fails" + rand.ToString()+ ".html", data);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Thread thread1 = new Thread(new ThreadStart(TestaThread_1));
            thread1.Start();

            Thread thread2 = new Thread(new ThreadStart(TestaThread_1));
            thread2.Start();

            Thread thread3 = new Thread(new ThreadStart(TestaThread_1));
            thread3.Start();

            Thread thread4 = new Thread(new ThreadStart(TestaThread_1));
            thread4.Start();

            Thread thread5 = new Thread(new ThreadStart(TestaThread_1));
            thread5.Start();
        }
    }

    class HTTP
    {
        public Easy easy;        
        public static string SockBuff;
        public string CookieFile = AppDomain.CurrentDomain.BaseDirectory + "cookie.txt";
        public string UserAgent = "Mozilla 5.0";
        public string Proxy = "";


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


        public string HTTPGet(string URL, string Proxy, String FailaNosaukums)
        {
            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 static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
        {
            Random rand = new Random();
            int RandomNumber = rand.Next(1000);

            SockBuff = SockBuff + System.Text.Encoding.UTF8.GetString(buf);

            return size * nmemb;
        }

        static public void save_file(string file_name, string text_to_write)
        {
            StreamWriter MyStream = null;
            string MyString = text_to_write;

            try
            {
                MyStream = File.CreateText(file_name);
                MyStream.Write(MyString);
            }
            catch (IOException e)
            {
                Console.WriteLine(e);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                if (MyStream != null)
                    MyStream.Close();
            }
        }
    }
}

我还有一个问题。

为什么我不能正确使用 save_file 函数保存图像文件? buff中有编码问题吗?

【问题讨论】:

    标签: c# libcurl


    【解决方案1】:

    问题在于您的SockBuffstatic,因此该变量只有一个实例被HTTP 类的所有实例共享。您可以通过删除static 来解决问题。

    如果您这样做,您还必须使您的 OnWriteData 方法成为实例方法(即不是静态的)。

    您也可以考虑使用 System.Net.WebClient 和/或 System.Net.HttpWebRequest 类来代替 Libcurl。

    【讨论】:

    • 工作得很好!谢谢。为什么 System.Net 比 libcurl 更好?
    • 我很高兴我的回答很有帮助。这并不是说 System.Net 类比 Libcurl 更好。老实说,我对 .NET 上的 Libcurl 了解得不够多,无法说出哪个更好。但根据我的经验,尽可能使用 .NET 库是有意义的,因为它简化了事情(不必包含其他库),它们通常运行良好,并且它们将被更广泛地使用和理解(这意味着我可以更多如果我需要,可以轻松获得他们的帮助)。
    • @user444434 你能分享一下你是如何用线程解决上述问题的吗?
    • @user44434:解决方案是让 SockBuff 成为实例变量,以便每个线程都有自己的缓冲区。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多