zoukankan      html  css  js  c++  java
  • [C#]多线程下载

    发现电脑里以前编写的下载程序。。。

    做个记录,那时做的挺匆忙的,没用委托,通过公开出窗体来修改下载进度,做的比较乱... ==!!

    程序具体功能(流程):

    1.检测系统托盘图标内的进程名是否符合要求 (xp时可以,win7部分机器可以,该功能无意义)

    2.抓取页面,进行正则匹配下载的文件地址(可以改成自己想要的任何情况)

    3.开多线程下载(建立多个文件)

    4.合并文件

    5.下载完毕后,发送ipmsg

    ---下面是部分代码,个人认为有参考价值---

    1.检测系统托盘图标内的进程名

     1 #region P/Invoke
     2 
     3 [DllImport("User32.dll", EntryPoint = "FindWindow")]
     4 private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
     5 
     6 [DllImport("User32.dll", EntryPoint = "FindWindowEx")]
     7 private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
     8  string lpClassName, string lpWindowName);
     9 
    10 //[DllImport("User32.dll", EntryPoint = "GetClientRect")]
    11 //static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
    12 
    13 [DllImport("user32.dll", EntryPoint = "PostMessageA")]
    14 private static extern int PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
    15 
    16 #endregion
    17 
    18 private void btnFind_Click(object sender, EventArgs e)
    19 {
    20     SysTrayWnd.TrayItemData[] trayItems = SysTrayWnd.GetTrayWndDetail();
    21     this.dataGridView1.Columns.Clear();
    22     this.dataGridView1.Columns.Add("colTrayItemWinHandle", "窗口句柄");
    23     this.dataGridView1.Columns.Add("colTrayItemProcHandle", "进程句柄");
    24     this.dataGridView1.Columns.Add("colTrayItemPID", "进程ID");
    25     this.dataGridView1.Columns.Add("colTrayItemProcImagePath", "进程映象路径");
    26     this.dataGridView1.Columns.Add("colTrayItemIconTipText", "托盘图标提示内容");
    27     this.dataGridView1.Columns.Add("colTrayItemIconHandle", "托盘图标句柄");
    28     //this.dataGridView1.Columns.Add("colTrayItemIcon", "托盘图标");
    29     this.dataGridView1.Columns.Add(new DataGridViewImageColumn());
    30     this.dataGridView1.Columns[6].HeaderText = "托盘图标";
    31     this.dataGridView1.Columns[6].Name = "colTrayItemIcon";
    32     this.dataGridView1.Columns.Add("test", "test");
    33 
    34     this.dataGridView1.Rows.Add(trayItems.Length);
    35     int iRowIndex = 0;
    36     foreach (SysTrayWnd.TrayItemData trayItem in trayItems)
    37     {
    38     //窗口句柄  
    39     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemWinHandle"].Value = trayItem.hWnd.ToString("X").ToUpper();
    40     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemWinHandle"].ToolTipText = trayItem.hWnd.ToString();
    41     //进程句柄  
    42     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcHandle"].Value = trayItem.hProcess.ToString("X").ToUpper();
    43     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcHandle"].ToolTipText = trayItem.hProcess.ToString();
    44     //进程ID  
    45     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemPID"].Value = trayItem.dwProcessID.ToString();
    46     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemPID"].ToolTipText = trayItem.dwProcessID.ToString();
    47     //进程映象路径  
    48     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcImagePath"].Value = trayItem.lpProcImagePath;
    49     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemProcImagePath"].ToolTipText = trayItem.lpProcImagePath;
    50     //托盘图标提示内容  
    51     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconTipText"].Value = trayItem.lpTrayToolTip;
    52     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconTipText"].ToolTipText = trayItem.lpTrayToolTip;
    53     //托盘图标句柄  
    54     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconHandle"].Value = trayItem.hIcon.ToString("X").ToUpper();
    55     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconHandle"].ToolTipText = trayItem.hIcon.ToString();
    56     //托盘图标  ;
    57     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIcon"].ValueType = typeof(byte[]);
    58     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIcon"].Value = Icon.FromHandle(trayItem.hIcon);
    59     this.dataGridView1.Rows[iRowIndex].Cells["colTrayItemIconHandle"].ToolTipText = trayItem.hIcon.ToString();
    60     //test
    61     System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(trayItem.dwProcessID);
    62     this.dataGridView1.Rows[iRowIndex].Cells["test"].Value = p.ProcessName;
    63 
    64     iRowIndex++;
    65     }
    66 
    67     doAboutHostCheck(trayItems);
    68 }
    69 
    70 private void doAboutHostCheck(SysTrayWnd.TrayItemData[] trayItems)
    71 {
    72 
    73     foreach (SysTrayWnd.TrayItemData trayItem in trayItems)
    74     {
    75     System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(trayItem.dwProcessID);
    76     if (hostCheckPName.Equals(p.ProcessName))
    77     {
    78         t.Stop();
    79         setFormValue("hostCheck错误发生,开始联网查找解决方案", null, null);
    80         doDownload();
    81         break;
    82     }
    83     }
    84 }
    View Code

    2.抓取页面,进行正则匹配下载的文件地址

    3.开多线程下载(建立多个文件)

    4.合并文件

      1 // 变量定义
      2 private Thread thread1 = null;
      3 public string downFolder = @"\10.164.2.44software
    orton";
      4 public string webUrl = "http://www.symantec.com/security_response/definitions/download/detail.jsp?gid=savce";
      5 public string regPatten = "http://definitions.symantec.com/([^"]*)v([^"]*)32.exe";
      6 
      7 // 下载参数初期化
      8 private void btnStart_Click(object sender, EventArgs e)
      9 {
     10     // 多线程下载停止flg
     11     constant.stopDL = false;
     12     // 从画面读取参数
     13     webUrl = txtUrl.Text;
     14     regPatten = txtReg.Text;
     15     downFolder = txtFolder.Text.EndsWith("\") ? txtFolder.Text : txtFolder.Text+"\";
     16     gapTime = long.Parse(txtGap.Text);
     17 
     18     t1.Tick += new EventHandler(t1_Tick);
     19     t1.Interval = 10000;
     20 
     21     t.Interval = (int)gapTime;
     22     // 定义线程
     23     thread1 = new Thread(new ThreadStart(doDownLoadThread));
     24     t.Tick += new EventHandler(t_Tick);
     25     t.Start();
     26     t_Tick(null, new EventArgs());
     27     // 可以直接调用 doDownload 方法
     28 }
     29 
     30 // 下载方法入口
     31 // 使用WebBrowser控件打开页面
     32 private void doDownload()
     33 {
     34     string url = webUrl;
     35     WebBrowser wb = new WebBrowser();
     36     // 忽略js脚本错误
     37     wb.ScriptErrorsSuppressed = true;
     38     // 打开网页
     39     wb.Navigate(url);
     40     setFormValue("正在打开网页", null, null);
     41     // 页面加载完了事件绑定
     42     wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
     43 }
     44 
     45 // WebBrowser控件页面加载完了事件
     46 void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
     47 {
     48     constant.innerHtml = ((WebBrowser)sender).Document.Body.InnerHtml;
     49     thread1.Start();
     50 }
     51 
     52 // 下载主线程
     53 public void doDownLoadThread()
     54 {
     55     setFormValue("打开完成,开始查找文件地址", null, null);
     56     // 正则匹配
     57     MatchCollection mts = Regex.Matches(constant.innerHtml, regPatten, RegexOptions.Multiline | RegexOptions.IgnoreCase);
     58     // 一般一个,可以不用循环,判断一下是否有就行了
     59     foreach (Match item in mts)
     60     {
     61     setFormValue("下载文件:" + item.Value, null, null);
     62     string fileName = item.Value.Split('/')[(item.Value.Split('/').Length - 1)];
     63     // 开始多线程下载
     64     multiThreadDownLoad MTDL = new multiThreadDownLoad();
     65     MTDL.doDownLoadFile(item.Value, fileName, this);
     66     // 只下载第一个
     67     break;
     68     }
     69 }
     70 
     71 // 开始多线程下载类
     72 public class multiThreadDownLoad
     73 {
     74 // 文件总大小
     75 public static long showAllBytes = 0;
     76 // 线程个数
     77 public static int threadCount = 10;
     78 // 线程状态
     79 public static List<bool> threadSts = new List<bool>();
     80 // 线程池
     81 public static List<Thread> threadLst = new List<Thread>();
     82 private List<oneThread> oneThLst = new List<oneThread>();
     83 public static List<long[]> threadStEnLst = new List<long[]>();
     84 // 下载进度
     85 public static long currentDownloaded = 0;
     86 // 下载停止flg
     87 public static bool stopDownloadFlg = false;
     88 // 临时文件夹路径
     89 public static string tmpFolder = @"hostcheckTmp";
     90 // 最终文件路径
     91 public static string finalFile = "";
     92 
     93 public static string tempFloder = "";
     94 // winform窗体
     95 public static Form1 frm;
     96 
     97 // 多线程下载入口
     98 public bool doDownLoadFile(string url, string name, Form1 frm1)
     99 {
    100     // 初期化数据
    101     bool result = true;
    102     frm = frm1;
    103     int thCount = 1;
    104     threadCount = int.TryParse(frm.txtThreads.Text, out thCount) ? thCount : 1;
    105     finalFile = frm1.downFolder + name;
    106     string mainFolder = frm1.downFolder.EndsWith("\") ? frm1.downFolder : frm1.downFolder + "\";
    107     string tmpFolder0 = mainFolder + tmpFolder;
    108     tempFloder = tmpFolder0;
    109     try
    110     {
    111         // 获取文件总大小
    112     System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
    113     System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
    114     long totalBytes = myrp.ContentLength;
    115     Myrq.Abort();
    116     showAllBytes = totalBytes;
    117     // 判断文件是否存在,并处理
    118     if (File.Exists(frm1.downFolder + name))
    119     {
    120         frm1.setFormValue("已经存在文件", 100, 100);
    121     }
    122     else
    123     {
    124         // 文件不存在,创建临时目录
    125         if (!Directory.Exists(tmpFolder0))
    126         {
    127         Directory.CreateDirectory(tmpFolder0);
    128         }
    129         // 计算每个线程的目标下载量与下载开始位置
    130         long eachBytes = totalBytes / threadCount;
    131         long startPos = 0;
    132         for (int i = 0; i < threadCount; i++)
    133         {
    134         if (threadCount != (i + 1))
    135         {
    136             // 普通线程对象
    137             oneThLst.Add(new oneThread(eachBytes * i, eachBytes - 1, new string[] { tmpFolder0, i.ToString(), url }));
    138         }
    139         else
    140         {
    141             // 最后一个线程对象
    142             oneThLst.Add(new oneThread(eachBytes * i, eachBytes + (int)(totalBytes % threadCount) - 1, new string[] { tmpFolder0, i.ToString(), url }));
    143         }
    144         // 加入线程列表,并启动下载
    145         threadLst.Add(new Thread(new ThreadStart(oneThLst[i].doDownloadThread)));
    146         threadSts.Add(false);
    147         }
    148 
    149         for (int i = 0; i < threadLst.Count; i++)
    150         {
    151             // 后台运行
    152         threadLst[i].IsBackground = true;
    153         threadLst[i].Start();
    154         }
    155         // 开启合并线程的监控
    156         Thread combThread = new Thread(new ThreadStart(combFiles));
    157         combThread.IsBackground = true;
    158         combThread.Start();
    159     }
    160     }
    161     catch (Exception e)
    162     {
    163     result = false;
    164     }
    165     return result;
    166 }
    167 
    168 // 合并文件
    169 public void combFiles()
    170 {
    171     // 检查线程状态
    172     bool alive = false;
    173     do
    174     {
    175     alive = false;
    176     foreach (bool sts in threadSts)
    177     {
    178         if (!sts) { alive = true; }
    179     }
    180     if (!alive)
    181     {
    182         // 人为停止时
    183         if (constant.stopDL)
    184         {
    185         try
    186         {
    187             Directory.Delete(tempFloder, false);
    188         }
    189         catch (Exception) { }
    190         frm.setFormValue("已经停止", 100, 100);
    191         }
    192         // 下载结束时
    193         else
    194         {
    195         if (!File.Exists(finalFile))
    196         {
    197             frm.setFormValue("开始合并文件", 100, 100);
    198             File.Copy(tempFloder + "tmp0", finalFile);
    199             File.Delete(tempFloder + "tmp0");
    200             FileStream AddStream = new FileStream(finalFile, FileMode.Append);
    201             BinaryWriter AddWriter = new BinaryWriter(AddStream);
    202             for (int i = 1; i < threadLst.Count; i++)
    203             {
    204             FileStream TempStream = new FileStream(tempFloder + "tmp" + i.ToString(), FileMode.Open);
    205             BinaryReader TempReader = new BinaryReader(TempStream);
    206             AddWriter.Write(TempReader.ReadBytes((int)TempStream.Length));
    207             TempReader.Close();
    208             TempStream.Close();
    209             File.Delete(tempFloder + "tmp" + i.ToString());
    210             }
    211             AddWriter.Close();
    212             AddStream.Close();
    213             Directory.Delete(tempFloder, false);
    214 
    215             frm.setFormValue("下载完成", 100, 100);
    216             // 启动ipmsg发送消息
    217             Thread thIpmsg = new Thread(new ThreadStart(sendIpmsg));
    218             thIpmsg.IsBackground = true;
    219             thIpmsg.Start();
    220         }
    221         }
    222     }
    223     else
    224     {
    225         Thread.Sleep(1000);
    226     }
    227     } while (alive || constant.stopDL);
    228 }
    229 
    230 // 下载线程类
    231 
    232 class oneThread
    233 {
    234     // 需要下载的文件地址,开始位置,数据量,临时目录等
    235     public long startPosP;
    236     public long eachBytesP;
    237     //new string[]{tmpFolder0,i.ToString(),url,threadStEnLst[i][0].ToString(),threadStEnLst[i][1].ToString()
    238 
    239     public string tmpFolder0;
    240     public string i;
    241     public string url;
    242     public long allByte;
    243 
    244     // 构造函数,初期化变量
    245     public oneThread(long startPos, long eachBytes, object getList)
    246     {
    247         startPosP = startPos;
    248         allByte = eachBytes;
    249             tmpFolder0 = ((string[])getList)[0];
    250         i = ((string[])getList)[1];
    251         url = ((string[])getList)[2];
    252     }
    253 
    254     // 下载方法
    255     public void doDownloadThread()
    256     {
    257         try
    258         {
    259         if (!File.Exists(tmpFolder0 + "tmp" + i.ToString()))
    260         {
    261             // 创建文件
    262             System.IO.Stream so = new System.IO.FileStream(tmpFolder0 + "tmp" + i.ToString(), System.IO.FileMode.Create);
    263             // 创建网络链接
    264             System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
    265             // 设置数据接收开始位置,结束位置
    266             Myrq.AddRange((int)startPosP, (int)(startPosP + allByte));
    267             // 以1024byte为单位读取下载
    268             System.IO.Stream st = ((System.Net.HttpWebResponse)Myrq.GetResponse()).GetResponseStream();
    269             long totalBytes = ((System.Net.HttpWebResponse)Myrq.GetResponse()).ContentLength;
    270             long totalDownloadedByte = 0;
    271             byte[] by = new byte[1024];
    272             int osize = st.Read(by, 0, (int)by.Length);
    273             while (osize > 0 && !constant.stopDL)
    274             {
    275             totalDownloadedByte = osize + totalDownloadedByte;
    276             so.Write(by, 0, osize);
    277             osize = st.Read(by, 0, (int)by.Length);
    278             // 更新总下载进度
    279             multiThreadDownLoad.currentDownloaded += osize;
    280             multiThreadDownLoad.frm.setFormValue("下载文件:" + multiThreadDownLoad.currentDownloaded / 1024 + "/" + multiThreadDownLoad.showAllBytes / 1024, (int)(multiThreadDownLoad.currentDownloaded / 1024), (int)(multiThreadDownLoad.showAllBytes / 1024));
    281             }
    282             so.Close();
    283             st.Close();
    284             Myrq.Abort();
    285             if (constant.stopDL) {
    286             File.Delete(tmpFolder0 + "tmp" + i.ToString());
    287             }
    288             multiThreadDownLoad.threadSts[int.Parse(i)] = true;
    289         }
    290         }
    291         catch (Exception e)
    292         {
    293         multiThreadDownLoad.threadSts[int.Parse(i)] = true;
    294         }
    295     }
    296 }

    5.下载完毕后,发送ipmsg

     1 // 发送ipmsg方法入口
     2 public void sendIpmsg() {
     3     // 配置文件读取目标ip
     4     string[] ipList = ConfigurationManager.AppSettings["ipList"].Split(',');
     5     for (int i = 0; i < ipList.Length; i++)
     6     {
     7     UdpClient client = new UdpClient(1988);
     8     IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ipList[i]), 2425);
     9     byte[] bytes = Encoding.Default.GetBytes(string.Concat(new object[] { "1:", DateTime.Now.Ticks, ":", "HostCheck", ":", "HostCheck", ":", 0x20, ":", "downloadComplete[" + finalFile + "]" }));
    10     client.Send(bytes, bytes.Length, endPoint);
    11     Thread.Sleep(1000);
    12     client.Close();
    13     client = null;
    14     }
    15 
    16 }

    6.一般服务器只允许开启2个线程进行下载

    需在配置文件里使用下面配置

    1 <system.net>
    2     <connectionManagement>
    3     <add address="*" maxconnection="最大连接数"/>
    4     </connectionManagement>
    5 </system.net>

     ----

    CSND参考代码下载:

    http://download.csdn.net/detail/wangxsh42/8346859

  • 相关阅读:
    书法的艺术
    书法的艺术
    matlab gabor 滤波器
    matlab gabor 滤波器
    生活中的物理学(电学)
    生活中的物理学(电学)
    CCD 与 CMOS
    CCD 与 CMOS
    博物院与国宝
    【设计模式】学习笔记13:组合模式(Composite)
  • 原文地址:https://www.cnblogs.com/wangxinsheng/p/4214600.html
Copyright © 2011-2022 走看看