2023年12月8日发(作者:)

Unity游戏开发-客户端Http下载

本篇主要分享基于.Net实现一个客户端Http下载模块。

Http下载这块和服务器也有一定的联系,关于服务器Http下载模块的实现后面有时间再贴出来吧,主要是和客户端约定一下HttpPost参数

的解析方式。

Http下载这块主要还是基于.Net库里面的HttpWebRequest类去实现的。

这里主要是封装了一些数据结构用于支持下载的显示,封装了多线程的处理避免Http请求造成线程的阻塞,封装了文件流的下载保存和

md5校验。

一个分为两个部分:

HttpDownLoad-开启线程,创建下载任务,更新下载状态

HttpDownPack-Http下载任务的数据结构定义

HttpDownPack

public class HttpDownPack

{

// 网络错误重试次数

public int tryNum;

// 服务器http地址

public string url;

// post请求参数

public byte[] param;

// 下载后本地文件保存路径

public string localFile;

// 文件的md5

public string md5;

// 请求超时时间

public int timeOut = 5000;

// 下载状态

public HttpDownState state;

// 当前下载的大小

public int downSize;

}

public enum HttpDownState

{

Ready = 0,

DownLoading = 1,

Complete = 2,

Md5Failed = 3,

Error = 4

}

其中param是我们post请求需要构建的参数。

整体的设计师param的前四个字节构成一个int类型,其代表的是我们给服务器推送的协议号来表示我们需要做什么样的业务。

这里将2表示为请求下载文件。

param的后续字节为当前请求类型约定的数据结构。

这里下载约定的数据结构为

// 下载任务数据结构

public class DatHttpDown

{

// 下载路径

public string path;

// 当前下载的字节数

public long startByte;

}

最终我们将协议类型2、下载数据结构转换为json字符串再转换为二进制一起写入param中构成一条完整的请求参数。

using (MemoryStream ms = new MemoryStream())

{

using (BinaryWriter bw = new BinaryWriter(ms))

{

//......

//请求下载

(2);

//构建下载参数

DatHttpDown datHttpDown = new DatHttpDown();

= "xxxx/xxx";

yte = 0;

(es((datHttpDown)));

= y();

_pReq(downPack);

}

}

HttpDownLoad

首先定义了一个下载队列,里面存放的就是HttpDownPack。

提供一个AddHttpReq的方法,外部调用该方法将构建好的HttpDownPack存入队列中。

开启一个线程不停的从队列中获取HttpDownPack并执行下载任务。

下载的过程中不断的更新HttpDownPack中的数据,以便业务层可以获取到下载的进度。

public class HttpDownLoad

{

private Thread mSendTask;

private bool mAlive;

private string HTTP_DOWN_PATH;

private BlockQueue mDownList = new BlockQueue(50);

public void Init()

{

mSendTask = new Thread(DownTask);

ground = true;

();

mAlive = true;

HTTP_DOWN_PATH = pPath;

if (!(HTTP_DOWN_PATH))

{

Directory(HTTP_DOWN_PATH);

}

}

public void AddHttpReq(HttpDownPack pack)

{

e(pack);

}

private void DownTask()

{

while (mAlive)

{

var downPack = e();

Down(downPack);

}

}

private void Down(HttpDownPack pack)

{

HttpWebRequest req;

HttpWebResponse res = null;

req = (HttpWebRequest)(new Uri());

= "POST";

t = t;

try

{

if ( != null)

{

Stream stream = uestStream();

(, 0, );

();

}

res = (HttpWebResponse)ponse();

string tmpFilePath = HTTP_DOWN_PATH + "/" + 5;

File(tmpFilePath);

using (FileStream fs = new FileStream(tmpFilePath, Create))

{

using (Stream resStream = ponseStream())

{

byte[] buffer = new byte[1024];

// 下载中

= ading;

int size = (buffer, 0, 1024);

while (size > 0)

{

(buffer, 0, size);

ze += size;

size = (buffer, 0, 1024);

}

();

();

}

}

File(ile);

(tmpFilePath, ile);

if (5FromFile(ile).Equals(5))

{

= te;

("文件下载成功!"+ ile);

}

else

{

= 5Failed;

= 5Failed;

("文件md5校验失败" + ile);

}

}

catch (WebException ex)

{

("文件下载出错!" + ile);

();

// 下载错误

= ;

(e);

}

finally

{

if (res != null)

{

();

}

}

}

}