基于Sockets下载,支持 断点续传多线程下载

下载程序主要类

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Threading;
using System.Collections;

namespace myIIS
{
  
    public class HttpDownload
    {
        private string linkUrl="";//链接的url
        private HttpProxy proxy = null;
        private long contentLength = 0;//下载文件长度
        private string fileName="";//下载文件名
        private string method = "GET";//HTTP方法
        private string sendMessage="";//用POST方法象HTTP服务器发送的信息
        private int itemCount = 10;//文件下载的块数量
        private HttpDownloadItem[] items;
       
        private IPAddress connectIP = null;
        private IPEndPoint connectEndPoint = null;
     
        private string modeString = "";//代理连接字符串
        private string hostString = "";//主机字符串
           
        public HttpDownload(string linkUrl)
        {
            this.linkUrl = linkUrl;
        }
        /// <summary>
        /// 获取下载文件头信息
        /// </summary>
        public void GetHttpHeadInfo()
        {
           
            string receiveString = "";//收到http服务器返回的字符串


            //获取主机字符串
            hostString = linkUrl;
            int l = hostString.IndexOf("://") + ("://").Length;
            if (l != -1)
            {
                hostString = hostString.Substring(l);
            }
            l = hostString.IndexOf("/");
            if (l != -1)
            {
                hostString = hostString.Substring(0, l);
            }


            Socket httpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

           
            //根据是否使用代理服务器确定帮定远程计算机的IP
            if (proxy != null)
            {
                //使用代理服务器
                connectIP = proxy.IP;
                connectEndPoint = new IPEndPoint(connectIP, proxy.Port);
                modeString = "Proxy-Connection: Keep-Alive";
            }
            else
            {
                //主机中没有端口,使用默认的80端口
                if (hostString.IndexOf(":") == -1)
                {
                    connectIP = IPAddress.Parse(hostString);
                    connectEndPoint = new IPEndPoint(connectIP, 80);
                }
                else
                {
                    l = hostString.IndexOf(":");
                    connectIP = IPAddress.Parse(hostString.Substring(0,l));
                    connectEndPoint = new IPEndPoint(connectIP, int.Parse(hostString.Substring(l+1, hostString.Length-l-1)));
                }
                modeString = "Connection: Keep-Alive";
            }

 

            string formatString = "{0} {1} HTTP/1.1/r/nContent-Type: application/x-www-form-urlencoded/r/nContent-Length: {2}/r/nExpect: 100-continue/r/n{3}/r/nHost: {4}/r/n/r/n{5}";
            string sendString = string.Format(formatString, "HEAD", linkUrl, Encoding.Default.GetByteCount(sendMessage), modeString, hostString, sendMessage);
           
            byte[] sendBuffer = System.Text.Encoding.Default.GetBytes(sendString);

            try
            {
                httpSocket.Connect(connectEndPoint);
                httpSocket.Send(sendBuffer);

                int block = 10240;//定义网络缓冲区大小
                byte[] receiveBuffer = new byte[block];//定义网络缓冲区
                block = httpSocket.Receive(receiveBuffer);
                receiveString = System.Text.Encoding.Default.GetString(receiveBuffer, 0, block);
                //是否收到下载文件名和文件长度信息
                while ((receiveString.IndexOf("filename=") == -1 || receiveString.IndexOf("Content-Length: ") == -1) && block > 0)
                {
                    block = httpSocket.Receive(receiveBuffer);
                    receiveString = string.Concat(receiveString, System.Text.Encoding.Default.GetString(receiveBuffer, 0, block));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                httpSocket.Close();
            }
            int begin = receiveString.IndexOf("filename=")+("filename=").Length;
            int end = receiveString.IndexOf("/r/n", begin);
            this.fileName = receiveString.Substring(begin, end - begin);
            begin = receiveString.IndexOf("Content-Length: ") + ("Content-Length: ").Length;
            end = receiveString.IndexOf("/r/n", begin);
            this.contentLength = int.Parse(receiveString.Substring(begin, end - begin));
            SetItems();
        }

        void SetItems()
        {
            items = new HttpDownloadItem[itemCount];
            for (int i = 0; i < itemCount; i++)
            {
                items[i] = new HttpDownloadItem(this);
                int itemLength=(int)this.contentLength / this.itemCount;

               
                items[i].BeginRange = i * itemLength;
                items[i].EndRange = (i + 1) * itemLength;
                items[i].Id = i;  
            }
            items[itemCount - 1].EndRange = (int)this.contentLength;
        }
        public void Download()
        {
            foreach (HttpDownloadItem Item in items)
            {
                Thread downlaodThread = new Thread(new ThreadStart(Item.Download));
                downlaodThread.Start();
                //Item.Download();

              
            }
        }

        public HttpDownloadItem[] Items
        {
            get
            {
                return items;
            }
        }
        public string Url
        {
            get
            {
                return linkUrl;
            }
            set
            {
                linkUrl = value;
            }
        }

        public HttpProxy Proxy
        {
            set
            {
                proxy = value;
            }
        }
        public string Method
        {
            set
            {
                method = value;
            }
        }
        public string SendMessage
        {
            set
            {
                sendMessage = value;
            }
            get
            {
                return sendMessage;
            }
        }
        public int ItemCount
        {
            set
            {
                itemCount = value;
            }
        }
        internal string ModeString
        {
            get
            {
                return modeString;
            }
        }
      
        internal string HostString
        {
            get
            {
                return hostString;
            }
        }
        internal IPEndPoint ConnectEndPoint
        {
            get
            {
                return connectEndPoint;
            }
        }
        internal string FileName
        {
            get
            {
                return this.fileName;
            }
        }
    }
}

每一个下载进程类

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace myIIS
{
    public class HttpDownloadItem : System.IDisposable
    {
        public delegate void StateChangeEventHandler(HttpDownloadItem sender, StateEventArgs e);
        public event StateChangeEventHandler StateChange; //状态改变事件
        private StateEventArgs eState;

        public delegate void DataReceiveEventHandler(HttpDownloadItem sender, DataReceiveEventArgs e);
        public event DataReceiveEventHandler DataReceiveChange; //数据接受事件
        private DataReceiveEventArgs eDataReceive;

        private int beginRange = 0;
        private int endRange = 0;
        private int id = 0;
        private HttpDownload parent;


        internal HttpDownloadItem(HttpDownload parent)
        {
            eState = new StateEventArgs();
            eDataReceive = new DataReceiveEventArgs();
            this.parent = parent;
        }
       
        public int BeginRange
        {
            set
            {
                beginRange = value;
            }
            get
            {
                return beginRange;
            }
        }
        public int EndRange
        {
            set
            {
                endRange = value;
            }
            get
            {
                return endRange;
            }
        }
        protected virtual void OnStateChanged(StateEventArgs e)
        {
            if (StateChange != null)
                StateChange(this, e);
        }
        protected virtual void OnDataReceiveChange(DataReceiveEventArgs e)
        {
            if (DataReceiveChange != null)
                DataReceiveChange(this, e);
        }
        public int Id
        {
            get
            {
                return id;
            }
            set
            {
                id = value;
            }
        }
    
        public void Download()
        {
            Socket httpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            string formatString = "{0} {1} HTTP/1.1/r/nContent-Type: application/x-www-form-urlencoded/r/nContent-Length: {2}/r/nExpect: 100-continue/r/n{3}/r/nRange:{4}-{5}/r/nHost: {6}/r/n/r/n{7}";
            string sendString = string.Format(formatString, "POST", parent.Url, Encoding.Default.GetByteCount(parent.SendMessage), parent.ModeString, this.beginRange,this.endRange, parent.HostString, parent.SendMessage);
            byte[] sendBuffer = System.Text.Encoding.Default.GetBytes(sendString);
           
            FileStream fleStm = null;
            try
            {
                eState.ItemState=DownloadItemState.Connect;
                OnStateChanged(eState);
                httpSocket.Connect(parent.ConnectEndPoint);
                httpSocket.Send(sendBuffer);

                int block = 10240;//定义网络缓冲区大小
                byte[] receiveBuffer = new byte[block];//定义网络缓冲区
               
               
               
                block = httpSocket.Receive(receiveBuffer);
                string receiveString = System.Text.Encoding.Default.GetString(receiveBuffer, 0, block);
               
               
                //获取http字头长度
                int l = receiveString.LastIndexOf("/r/n/r/n") + ("/r/n/r/n").Length;

                byte[] newBuffer = new byte[block - l];
                for (int i = 0; i < block - l; i++)
                {
                    newBuffer[i] = new byte();
                    newBuffer[i] = receiveBuffer[i + l];
                }
               
               
                //设置事件参数
                eDataReceive.FileName = parent.FileName;
                eDataReceive.Position = this.beginRange;
                eDataReceive.ReceiveBuffer = newBuffer;
                eDataReceive.Block = newBuffer.Length;

                eState.ItemState = DownloadItemState.Download;
                OnStateChanged(eState);
                OnDataReceiveChange(eDataReceive);

                eDataReceive.Position = eDataReceive.Position + eDataReceive.Block;
                while (block > 0 && eDataReceive.Position<this.endRange )
                {
                    block = httpSocket.Receive(receiveBuffer);
                   
                    eDataReceive.ReceiveBuffer = receiveBuffer;
                    eDataReceive.Block = block;
                    OnDataReceiveChange(eDataReceive);

                    eDataReceive.Position = eDataReceive.Position + block;
                }
                eState.ItemState = DownloadItemState.Complete;
                OnStateChanged(eState);
            }
            catch (ApplicationException ex)
            {
                eState.ItemState = DownloadItemState.Exception;
                eState.Message = ex.Message;
                OnStateChanged(eState);
            }
            catch (Exception ex)
            {
                eState.ItemState = DownloadItemState.Exception;
                eState.Message = ex.Message;
                OnStateChanged(eState);
            }
            finally
            {
                httpSocket.Close();
                if (fleStm != null)
                {
                    fleStm.Close();
                }
                System.Threading.Thread.CurrentThread.Abort();
            }

        }
        public virtual void Dispose()
        {
            eState = null;
        }
       
    }
}

using System;
using System.Collections.Generic;
using System.Text;

namespace myIIS
{
    public class DataReceiveEventArgs : System.EventArgs
    {
        private byte[] receiveBuffer = null;
        private int block = 0;
        private int position = 0;
        private string fileName = "";
        public byte[] ReceiveBuffer
        {
            set
            {
                receiveBuffer = value;
            }
            get
            {
                return receiveBuffer;
            }
        }
        public int Position
        {
            set
            {
                position = value;
            }
            get
            {
                return position;
            }
        }
        public string FileName
        {
            get
            {
                return this.fileName;
            }
            set
            {
                this.fileName=value;
            }
        }
        public int Block
        {
            set
            {
                this.block = value;
            }
            get
            {
                return this.block;
            }
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace myIIS
{
    #region 下载文件块类
    public class DownloadBlock
    {
        public DownloadBlock()
        {

        }
    }
    #endregion
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace myIIS
{
    public enum DownloadItemState
    {
        None=0,
        Stop = 1,
        Connect = 2,
        Download = 3,
        Exception = 4,
        Complete=5,
    }

}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace myIIS
{
    #region Http代理类
    public class HttpProxy
    {
        private System.Net.IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
        private int port = 0;

        public System.Net.IPAddress IP
        {
            set
            {
                ip = value;
            }
            get
            {
                return ip;
            }
        }
        public int Port
        {
            set
            {
                port = value;
            }
            get
            {
                return port;
            }
        }
        public HttpProxy(IPAddress ip, int port)
        {
            this.ip = ip;
            this.port = port;
        }
    }
    #endregion
}

 

using System;
using System.Collections.Generic;
using System.Text;

namespace myIIS
{
    public class StateEventArgs:System.EventArgs
    {
        private DownloadItemState itemState = DownloadItemState.Stop;
        private string message = "";
        public DownloadItemState ItemState
        {
            get
            {
                return itemState;
            }
            set
            {
                itemState = value;
            }
        }
        public string Message
        {
            set
            {
                this.message = value;
            }
            get
            {
                return this.message;
            }
        }
    }
}
 

原文地址:http://blog.donews.com/cmic/archive/2005/05/25/398027.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值