什么是网络
- 网络概念
代码语言:javascript复制网络应用 = 良好的UI 良好的用户体验 实时更新的数据(弱联网、强联网) 新闻:网易新闻、新浪新闻、搜狐新闻、腾讯新闻 视频:优酷土豆、腾讯视频、搜狐视频、爱奇艺视频 音乐:QQ音乐、百度音乐、酷狗音乐、酷我音乐 LBS:百度地图、高德地图、大众点评、墨迹天气、滴滴打车 电商:淘宝、京东商城、天猫、蘑菇街、凡客诚品、美丽说 社交:QQ、微信、微博、陌陌、比邻 游戏:王者荣耀,天天飞车,刀塔传奇,梦幻西游,大唐 通过网络跟外界进行数据交互、数据更新,应用才能保持新鲜、活力
客户端(Client):应用(iOS、android,windows等应用)
服务器(Server):为客户端提供服务、提供数据、提供资源的机器
请求(Request):客户端向服务器索取数据的一种行为
响应(Response):服务器对客户端的请求做出的反应,一般指返回数据给客户端
- 什么是服务器 按照客户端开发阶段来分,服务器可以大致分为2种
远程服务器 别名:外网服务器、正式服务器 使用阶段:应用上线后使用的服务器 使用人群:供全体用户使用 速度:取决于服务器的性能、用户的网速 本地服务器 别名:内网服务器、测试服务器 使用阶段:应用处于开发、测试阶段使用的服务器 使用人群:仅供公司内部的开发人员、测试人员使用 速度:由于是局域网,所以速度飞快,有助于提高开发测试效率 如何定位服务器
通过URL(网站地址)来定位服务器 、
- 什么是URL
URL的全称是Uniform Resource Locator(统一资源定位符) 通过1个URL,能找到互联网上唯一的1个资源 URL就是资源的地址、位置,互联网上的每个资源都有一个唯一的URL URL的基本格式 = 协议://主机地址/路径 http://www.jianshu.com/user/74372cf48f59/latest_articles http://upload-images.jianshu.io/upload_images/642887-5dad9dda442b8e8b.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240
- 什么是协议 协议:不同的协议,代表着不同的资源查找方式、资源传输方式 主机地址:存放资源的主机(服务器)的IP地址(域名)
URL中常见的协议: HTTP 超文本传输协议,访问的是远程的网络资源,格式是http:// https:// http协议是在网络开发中最常用的协议 file 访问的是本地计算机上的资源,格式是file://(不用加主机地址) mailto 访问的是电子邮件地址,格式是mailto: FTP 访问的是共享主机的文件资源,格式是ftp:// 飞秋
- HTTP/1.1协议
HTTP/1.1协议中,定义了8种发送http请求的方法 GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH 根据HTTP协议的设计初衷,不同的方法对资源有不同的操作方式 PUT :增 DELETE :删 POST:改 GET:查 最常用的是GET和POST(实际上GET和POST都能办到增删改查) 要想使用GET和POST请求跟服务器进行交互,得先了解一个概念 参数 就是传递给服务器的具体数据,比如登录时的帐号、密码
- Post与Get请求区别
Get 在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开,比如 http://www.test.com/login?username=leichao&id=888&type=JSON 由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB Post 发给服务器的参数全部放在请求体中 理论上,POST传递的数据量没有限制(具体还得看服务器的处理能力) 选择GET和POST的建议 如果要传递大量数据,比如文件上传,只能用POST请求 GET的安全性比POST要差些,如果包含机密敏感信息,建议用POST 如果仅仅是索取数据(数据查询),建议使用GET 如果是增加、修改、删除数据,建议使用POST
- 响应头与相应体
客户端向服务器发送请求,服务器应当做出响应,即返回数据给客户端 HTTP协议规定:1个完整的HTTP响应中包含以下内容 响应头:包含了对服务器的描述、对返回数据的描述
HTTP/1.1 200 OK // 包含了HTTP协议版本、状态码、状态英文名称 Server: Apache-Coyote/1.1 // 服务器的类型 Content-Type: image/jpeg // 返回数据的类型 Content-Length: 56811 // 返回数据的长度 Date: Mon, 23 Jun 2014 12:54:52 GMT // 响应的时间 响应体:服务器返回给客户端的具体数据,比如文件数据
- 网络状态码
常用的,其他的请自行查询
Unity中的WWW
WWW用于下载资源和打开一个Web网站,包含:Get/Post请求,本地资源文件下载,服务器资源下载。关于使用www方式加载AssetBundle资源,可以关注文章AssetBundle使用
- Get 1.一个链接中,参数是包括在链接中的,链接中的?后面都是参数; 2.服务器不会自动分配空间,传输的内容会比较小。
- Post 1.参数在表单里面。 2.服务器在底层检测到是Post请求,则会自动分配一个大的空间 3.例如声音,视频等比较大的数据
- WWW的使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LoginWWW : MonoBehaviour {
string url;
public Image img;
//public InputField put;
void Start () {
url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1540877217182&di=9d56ef557a007c78b543278db41cbb28&imgtype=0&src=http://b.hiphotos.baidu.com/imagehttps://img.yuanmabao.com/zijie/pic/item/d6ca7bcb0a46f21fd757a52ffb246b600c33ae6f.jpg";
// Get
StartCoroutine(GetLoadBg(url));
// Post 请求头,请求体
//Dictionary<string, string> dic = new Dictionary<string, string>();
//dic.Add("uEmail", "136087399@qq.com");
//dic.Add("uPwd", "1314521");
//StartCoroutine(PostLoadLogin(url,dic));
}
// Get
IEnumerator GetLoadBg(string url)
{
WWW w = new WWW(url);
yield return w;
// 返回字节数的长度
//Debug.Log(w.size);
// 打印响应头
//foreach (var item in w.responseHeaders)
//{
// Debug.Log(item);
//}
// 错误为空 ||下载完毕 || 图片下载完毕
if (w.error == null || w.isDone == true || w.progress == 1)
{
img.sprite = Sprite.Create(w.texture, new Rect(0, 0, Screen.width, Screen.height), new Vector2(0.5f, 0.5f));
}
else
{
Debug.Log(w.error);
}
}
// Post
IEnumerator PostLoadLogin(string url, Dictionary<string, string> dic)
{
WWWForm f = new WWWForm();
foreach (KeyValuePair<string,string> item in dic)
{
f.AddField(item.Key, item.Value);
}
WWW w = new WWW(url,f);
yield return w;
if (w.isDone)
{
if (w.error == null)
{
Debug.Log("加载成功");
}
else
{
Debug.Log(w.error);
}
}
else
{
Debug.Log("正在下载");
}
}
}
网络-UnityWebRequest
- Unity中使用WWW和C#中的HttpWebRequest方式进行下载。上面我们讲过WWW方式,这里我们不讲解HttpWebRequest,但是记住如果使用HttpWebRequest方式进行下载,要注意: 在Unity中,使用system.net中的HttpWebRequest获取返回信息,如果数据较大,会卡顿,主要由于unity单线程,httpwebrequest不能异步执行; 5.2版本后,Unity采用了UnityWebRequest 类,利用HTTP 协议和服务器交互,通常是通过 GET 和 POST 两种方式来对数据进行获取和提交。 UnityWebRequest 由三个元素组成。 ◾UploadHandler 处理数据 将数据发送到服务器 的对象 ◾DownloadHandler 从服务器接收数据 的对象 ◾UnityWebRequest 负责 HTTP 通信流量控制来管理上面两个对象的对象。
代码语言:javascript复制GET:
public class LoginWebRequist : MonoBehaviour {
string url;
public RawImage img;
void Start () {
url = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1540877217182&di=9d56ef557a007c78b543278db41cbb28&imgtype=0&src=http://b.hiphotos.baidu.com/imagehttps://img.yuanmabao.com/zijie/pic/item/d6ca7bcb0a46f21fd757a52ffb246b600c33ae6f.jpg";
StartCoroutine(LoadImage(url));
}
IEnumerator LoadImage(string url)
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
// DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
yield return www.SendWebRequest();
Debug.Log(www.downloadHandler.data.Length);
if (www.isHttpError)
{
}
else
{
if (www.responseCode == 200)
{
Debug.Log("连接成功");
//byte[] result = www.downloadHandler.data;
//int width = 0, height = 0;
//Texture2D t = new Texture2D(width,height);
//t.LoadImage(result);
//img.texture = t;
img.texture = DownloadHandlerTexture.GetContent(www);
}
else {
Debug.Log("连接不成功");
// 请检查网络,或者重新刷新
}
}
}
}
代码语言:javascript复制POST:
void Start() {
StartCoroutine( PostUrl(url, postData));
}
public IEnumerator PostUrl(string url, string postData)
{
using (UnityWebRequest www = new UnityWebRequest(url,"POST"))
{
// 上传请求头,byte[]数组
byte[] postBytes = System.Text.Encoding.UTF8.GetBytes(postData);
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(postBytes);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
// 请求头可以不写
// www.SetRequestHeader("Content-Type", "application/json");
yield return www.Send();
if (www.isError)
{
Debug.Log(www.error);
}
else
{
// Show results as text
if (www.responseCode == 200)
{
Debug.Log(www.downloadHandler.text);
}
}
}
}
- 服务器返回数据解析案例(Get)
Json解析
展示模板
代码语言:javascript复制using LitJson;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class JsonRead : MonoBehaviour {
public People[] p;
public People p1,p2,p3;
public Text[] nameA;
public Text[] ageA;
public RawImage[] imgA;
void Start () {
p = new People[] {
p1 = new People(),
p2 = new People(),
p3 = new People()
};
// 内容获取到了
ReadJson();
ShowPeople(0);
ShowPeople(1);
ShowPeople(2);
}
public void ShowPeople(int id)
{
nameA[id].text = p[id].name;
ageA[id].text = p[id].age.ToString();
StartCoroutine(LoadImage(p[id].imgUrl, id));
}
public void ReadJson()
{
string path = "Assets/Resources/TextFile.txt";
string textOne = File.ReadAllText(path);
JsonData data = JsonMapper.ToObject(File.ReadAllText(path));
for (int i = 0; i < data.Count; i )
{
JsonData idValue = data[i]["id"];
p[i].id = int.Parse(idValue.ToString());
JsonData AgeValue = data[i]["age"];
p[i].age = int.Parse(AgeValue.ToString());
JsonData nameValue = data[i]["name"];
p[i].name = nameValue.ToString();
JsonData imgUrlValue = data[i]["img"];
p[i].imgUrl = imgUrlValue.ToString();
Debug.Log("imgUrl :" imgUrlValue.ToString());
}
}
IEnumerator LoadImage(string url,int id)
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
yield return www.SendWebRequest();
if (www.isHttpError) {
Debug.Log("连接错误");
}
else{
if (www.responseCode == 200)
{
Debug.Log("连接成功");
imgA[id].texture = DownloadHandlerTexture.GetContent(www);
}else {
Debug.Log("连接不成功");
// 请检查网络,或者重新刷新
}
}
}
}
public class People
{
public int id;
public string name;
public int age;
public string imgUrl;
public People()
{
}
public People(int ID,string Name,int Age,string ImgUrl, Texture2D Img)
{
id = ID;
name = Name;
age = Age;
imgUrl = ImgUrl;
img = Img;
}
}
- Json数据文本TextFile
[
{"id" : 1,"name" : "jame","age":20,"img":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1541066018995&di=98ec0d44536d82fa03ac7a2580990afc&imgtype=0&src=http://img4.duitang.com/uploads/item/201602/06/20160206025901_JtzEC.thumb.700_0.jpeg"},
{"id" : 2,"name" : "Sume","age":22,"img":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1541068738551&di=d2a0b0fa09fecbb87926dd7f64e5851f&imgtype=0&src=http://img5q.duitang.com/uploads/blog/201311/30/20131130235032_tBLEJ.thumb.700_0.jpeg"},
{"id" : 3,"name" : "Baye","age":25,"img":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1541066038599&di=74d1aaf46dd716863a187b7952fe1072&imgtype=0&src=http://imgsrc.baidu.com/imgadhttps://img.yuanmabao.com/zijie/pic/item/7c1ed21b0ef41bd52a1399d25bda81cb39db3d57.jpg"}
]
- 斗鱼API请求实战Get
加载出来斗鱼首页的房间
代码语言:javascript复制http://capi.douyucdn.cn/api/v1/live?limit=20&offset=0
using LitJson;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Root
{
/// <summary>
///
/// </summary>
public int error { get; set; }
/// <summary>
///
/// </summary>
public List<DataItem> data { get; set; }
public Root()
{
data = new List<DataItem>();
}
}
public class DataItem
{
/// <summary>
///
/// </summary>
public string room_id { get; set; }
/// <summary>
///
/// </summary>
public string room_src { get; set; }
/// <summary>
///
/// </summary>
public string vertical_src { get; set; }
/// <summary>
///
/// </summary>
public int isVertical { get; set; }
/// <summary>
///
/// </summary>
public int cate_id { get; set; }
/// <summary>
/// 明天15:00总决赛 IGvsFNC
/// </summary>
public string room_name { get; set; }
/// <summary>
///
/// </summary>
public string show_status { get; set; }
/// <summary>
///
/// </summary>
public string subject { get; set; }
/// <summary>
///
/// </summary>
public string show_time { get; set; }
/// <summary>
///
/// </summary>
public string owner_uid { get; set; }
/// <summary>
///
/// </summary>
public string specific_catalog { get; set; }
/// <summary>
///
/// </summary>
public string specific_status { get; set; }
/// <summary>
///
/// </summary>
public string vod_quality { get; set; }
/// <summary>
/// 英雄联盟官方赛事
/// </summary>
public string nickname { get; set; }
/// <summary>
///
/// </summary>
public int online { get; set; }
/// <summary>
///
/// </summary>
public int hn { get; set; }
/// <summary>
///
/// </summary>
public string url { get; set; }
/// <summary>
///
/// </summary>
public string game_url { get; set; }
/// <summary>
/// 英雄联盟
/// </summary>
public string game_name { get; set; }
/// <summary>
///
/// </summary>
public int child_id { get; set; }
/// <summary>
///
/// </summary>
public string avatar { get; set; }
/// <summary>
///
/// </summary>
public string avatar_mid { get; set; }
/// <summary>
///
/// </summary>
public string avatar_small { get; set; }
/// <summary>
///
/// </summary>
public string jumpUrl { get; set; }
/// <summary>
///
/// </summary>
public string fans { get; set; }
/// <summary>
///
/// </summary>
public int ranktype { get; set; }
/// <summary>
///
/// </summary>
public int is_noble_rec { get; set; }
/// <summary>
///
/// </summary>
public string anchor_city { get; set; }
}
public class LoadData : MonoBehaviour {
// https://rpic.douyucdn.cn/asrpic/181102/1863767_1328_66.jpg/dy1
// https://rpic.douyucdn.cn/asrpic/181102/1863767_1328_66.jpg/dy1
public Root rt;
public DataItem item;
public Text roomName;
public Text gameName;
public Text manName;
public Text onlineCount;
void Start() {
rt = new Root();
string url = "http://capi.douyucdn.cn/api/v1/live?limit=2&offset=0";
StartCoroutine(GetLoadRoom(url,0));
}
public void ShowRoomMessage(int RoomID)
{
DataItem item = rt.data[RoomID];
Debug.Log(item.room_name);
roomName.text = item.room_name;
gameName.text = item.game_name;
onlineCount.text = item.online.ToString();
manName.text = item.nickname;
}
IEnumerator GetLoadRoom(string url,int RoomID)
{
UnityWebRequest q = UnityWebRequest.Get(url);
yield return q.SendWebRequest();
if (q.isNetworkError)
{
}
else
{
string str = System.Text.Encoding.Default.GetString(q.downloadHandler.data);
JsonData dataJson = JsonMapper.ToObject(str);
// 获取 data数组内容
for (int i = 0; i < dataJson.Count; i )
{
JsonData errorValue = dataJson["error"];
//赋值给rt.error
rt.error = int.Parse(errorValue.ToString());
JsonData dataList = dataJson["data"][i];
Debug.Log(dataList.Count);
rt.data.Add(JsonMapper.ToObject<DataItem>(dataList.ToJson()));
}
//roomName.text = rt.data[RoomID].room_name;
//gameName.text = rt.data[RoomID].game_name;
//onlineCount.text = rt.data[RoomID].online.ToString();
//manName.text = rt.data[RoomID].nickname;
ShowRoomMessage(RoomID);
}
}
}
Post请求实战
接口类似下面这种,那么我们如何传递参数。如何传递他要求的必填参数,这就需要沟通服务器人员,我传递的参数是什么类型,怎么添加,具体可以看下面的例子,粒子中的代码你直接拿去用,是不可以的,因为参数我去掉了,参数是服务器给的如:appid,device_id,涉及公司机密。
Post接口
代码语言:javascript复制代码教会你如何发送Post请求(携带请求体),至于回来的数据你要自己处理,不要想着抄袭,一点用没有!可以将请求回来的数据保存到模型中,也可以进行Json本地存储。
void Start () {
// 请求数据
string url = "http://life.jeckjian.top/index/szvideo_api/get_scenes.html";
// 请求体
WWWForm requestData = new WWWForm();
// 请求体参数
form.AddField("appid", "8888888");
// 请求体参数
form.AddField("device_id", "9999999");
// 请求体中的请求类型
form.AddField("class_type", "immersive");
// 发送
StartCoroutine(GetLoadData(url, requestData));
}
IEnumerator GetLoadData(string url, WWWForm requestData )
{
UnityWebRequest q = UnityWebRequest.Post(url, requestData );
yield return q.SendWebRequest();
if (q.isNetworkError)
{
Debug.Log(q.error);
}
else
{
// 成功后的数据如何获取,并转换出来
string str = System.Text.Encoding.Default.GetString(q.downloadHandler.data);
JsonData dataJson = JsonMapper.ToObject(str);
JsonData statusValue = dataJson["status"];
JsonData codeValue = dataJson["code"];
JsonData msgValue = dataJson["msg"];
JsonData info = dataJson["info"];
for (int j = 0; j < info.Count; j )
{
JsonData list = info["list"];
// 保存元素个数
count = list.Count;
// 遍历当前的场景
for (int k = 0; k < list.Count; k )
{
JsonData listItem = list[k];
// 遍历场景下的数据
for (int i = 0; i < listItem.Count; i )
{
JsonData videoIDValue = listItem["szvideo_id"];
JsonData packageValue = listItem["package"];
JsonData snValue = listItem["sn"];
JsonData priceValue = listItem["price"];
JsonData titleValue = listItem["title"];
JsonData descriptValue = listItem["descript"];
// Debug.Log(descriptValue.ToString());
JsonData imageValue = listItem["image"];
JsonData videoValue = listItem["video"];
JsonData _statusValue = listItem["status"];
JsonData class_idValue = listItem["class_id"];
JsonData pidValue = listItem["pid"];
JsonData nameValue = listItem["name"];
JsonData class_typeValue = listItem["class_type"];
JsonData package_nameValue = listItem["package_name"];
}
}
}
// 在这里数据已经全部加载完毕
可以存储,也可以给控件展示了。
}
}
另一种传递参数的写法
IEnumerator PostLoadData(string url, Dictionary<string, string> dic)
{
WWWForm f = new WWWForm();
foreach (KeyValuePair<string,string> item in dic)
{
f.AddField(item.Key, item.Value);
}
UnityWebRequest q = UnityWebRequest.Post(url, f);
yield return q.SendWebRequest();
}
- XML解析
代码语言:javascript复制全称是Extensible Markup Language,译作“可扩展标记语言” 跟JSON一样,也是常用的一种用于交互的数据格式 一般也叫XML文档(XML Document)
<photos>
<photo name="全家福 第01张" height="80" />
<photo name="全家福 第02张" hright="90" />
<photo name="全家福 第03张" hright="60" />
</photos>
- 什么是XML,详细见文章XML介绍
- XML的解析方式有2种 DOM:一次性将整个XML文档加载进内存,比较适合解析小文件 SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件
XmlDocument
- CreatElement() : //创建一个元素
- AppendChild(): //往节点下追加根节点
- Save() //保存XML文件
XmlDeclaration
- CreatXMLDeclaration() // 创建XML的声明节点
XmlElement
-GetElementsByTagName() // 根据节点名称获取下面的该节点名称的子节点元素
-setAttribute() // 设置元素的属性
-GetAttribute() // 获得元素的属性
- InnetText
-InnerXML
XmlNode(XmlElement的基类)
XmlNodeList
- XML数据
<Persones>
<Person>
<id> 1 </id>
<name lang = “En”> jim</name>
<damage> 100</damage>
</Person>
...
</Persones>
- C#解析
calss Person
{
public int ID {get;set;}
public string Name{get;set;}
public string Lang{get;set;}
public int Damage{get; set;}
public override string ToString()
{
rerturn string.Format(“id:{0},Name:{1},Lang:{2},Damage:{3}”,ID,Name,Lang,Damage);
}
}