下载程序主要类
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
本文介绍了一种基于C#的多线程HTTP下载技术实现方法,通过自定义类完成下载任务分配、状态管理和异常处理等功能。该方案支持断点续传、多线程并发下载及代理服务器配置。
281

被折叠的 条评论
为什么被折叠?



