我爱编程

Unity高级-HTTP

2018-05-23  本文已影响306人  passiony

什么是HTTP

HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”。

什么是TCP

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

它们叫什么名字,其实并不重要。只需要知道,互联网分成若干层就可以了。
每一层都是为了完成一种功能。为了实现这些功能,就需要大家都遵守共同的规则。
大家都遵守的规则,就叫做"协议"(protocol)。


Get和Post请求

Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。

上面大概说了一下HTTP规范中GET和POST的一些原理性的问题。但在实际的做的时候,很多人却没有按照HTTP规范去做,导致这个问题的原因有很多。
比如说:
1.很多人贪方便,更新资源时用了GET,因为用POST必须要FORM(表单),这样会麻烦一点。
2.对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不需要用到PUT和DELETE。

Get和Post区别

HTTP请求方式

1.WWW

WWW是Unity给我们提供的网络访问类,它实现了ftp://http://https://三种协议,可以满足我们再Unity的一些基本的网络请求,并且使用了协程,用户使用更加方便。

unity www 类同样对应两种提交数据的方式,常用的两个构造函数为:
static function WWW (url : String) : WWW
static function WWW (url : String, form : WWWForm) : WWW
第一个函数是通过get方法向服务器发送数据,第二个是用post提交数据,其中WWWForm有个方法叫:AddField(agr : string, value : string),来添加参数。

get例子:

privatevar url : String = "127.0.0.1/login.php?user=test&pwd=123";  
function Start () {  
     WWW www= WWW(url);  
     yield return www;       
     if(www.error != null) {  
          Debug.Log(www.error);  
     }   else {  
          Debug.Log(www.text);  
     }  
}  
post例子:

privatevar url : String = "127.0.0.1/login.php";  
function Start () {  
     WWWForm form = new WWWForm();  
     form.AddField("user", "test");  
     form.AddField("pwd", "123");  

     WWW www= WWW(url, form);  
     yield return www;  
     if(www.error != null) {  
          Debug.Log(www.error);  
     }   else {  
          Debug.Log(www.text);  
     }  
}  

2.HttpWebRequest

HttpWebRequest类是C#为我们提供的一个类,主要利用HTTP 协议和服务器交互,通常是通过 GET 和 POST 两种方式来对数据进行获取和提交。下面对这两种方式进行一下说明:

GET 方式:
GET 方式通过在网络地址附加参数来完成数据的提交,比如在地址 http://www.jb51.net/?name=test 中,前面部分 http://www.jb51.net表示数据提交的网址,后面部分 name=test 表示附加的参数,其中 name 表示一个键(key), test 表示这个键对应的值(value)。

程序代码如下:

string url="http://www.jb51.net?hl=zh-CN";
HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( url );
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
    //对接收到的内容进行处理
    Stream respStream = wr.GetResponseStream();  
    StreamReader reader = new StreamReader(respStream, Encoding.UTF8);  
    string result = reader.ReadToEnd();  
}

POST 方式:
POST 方式通过在页面内容中填写参数的方法来完成数据的提交,参数的格式和 GET 方式一样,是类似于 "username=test&password=123456" 这样的结构。

程序代码如下:

HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.jb51.net/" );
req.Method = "POST";

//拼接Form表单里的信息
string requestForm = "username=test&password=123456";     
byte[] bs = Encoding.ASCII.GetBytes(requestForm);
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{  
   //往请求流中写入表单
   reqStream.Write(bs, 0, bs.Length);
}

using (WebResponse wr = req.GetResponse())
{
    //对接收到的内容进行处理
    Stream respStream = wr.GetResponseStream();  
    StreamReader reader = new StreamReader(respStream, Encoding.UTF8);  
    string result = reader.ReadToEnd();  
}

异步读取方式

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class TestHttpAsyc : MonoBehaviour
{
    public Image img;
    bool success;
    byte[] buffer = new byte[1024];

    FileStream fileStream;
    HttpWebRequest request;
    HttpWebResponse response;
    Stream stream;
    int readCount;

    void Start()
    {
        fileStream = new FileStream("D:/abc.png", FileMode.Create);
        string url = "http://pic4.nipic.com/20091121/3764872_215617048242_2.jpg";
        request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "GET";
        request.BeginGetResponse(new AsyncCallback(delegate (IAsyncResult result)
        {
            response = (HttpWebResponse)request.EndGetResponse(result);
            stream = response.GetResponseStream();
            stream.BeginRead(buffer, 0, 1024, new AsyncCallback(ReadCallBack), request);
        }), request);
    }
    
    void ReadCallBack(IAsyncResult result)
    {
        int read = stream.EndRead(result);
        readCount += read;

        if (read>0)
        {
            fileStream.Write(buffer, 0, 1024);
            fileStream.Flush();

            buffer = new byte[1024];
            stream.BeginRead(buffer, 0, 1024, new AsyncCallback(ReadCallBack), request);
        }
        if(readCount>= response.ContentLength)
        {
            fileStream.Close();
            response.Close();
            stream.Close();
            success=true;
        }
    }

    void Update()
    {
        if (success)
        {
            success = false;
            Texture2D t2d = new Texture2D(512, 512);
            t2d.LoadImage(buffer);

            Rect rect = new Rect(0, 0, t2d.width, t2d.height);
            Sprite sp = Sprite.Create(t2d, rect, Vector2.one * 0.5f);
            img.sprite = sp;
        }
    }
}

3.WebClient

WebClient提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法, WebClient 类提供向 URI 标识的任何本地、Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法。
\WebClient 类使用 WebRequest 类提供对资源的访问。WebClient 实例可以通过任何已向 WebRequest.RegisterPrefix 方法注册的 WebRequest 子代访问数据。默认情况下,WebClient 实例不发送可选的 HTTP 报头。
如果您的请求需要可选报头,必须将该报头添加到 Headers 集合。例如,要在响应中保留查询,必须添加用户代理报头。此外,如果用户代理标头丢失,服务器可能返回 500(内部服务器错误)。
在 WebClient 实例中,AllowAutoRedirect 设置为 true。

查看MSND上对webclient的解释,有上传与下载方法:

using System.Net;
using System;
using System.IO;
public class TestWebClient : MonoBehaviour {

        string url = "http://e.hiphotos.baidu.com/zhidao/pic/item/a2cc7cd98d1001e98debe2acbc0e7bec55e797ba.jpg";
    void Start () {
        WebClient client = new WebClient();
        client.DownloadDataCompleted += DownloadDataCallback;
        client.DownloadProgressChanged += Client_DownloadProgressChanged;

        
        Uri uri = new Uri(url);
        client.DownloadDataAsync(uri);
    }
    //下载进度
    private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Debug.Log(e.BytesReceived * 100 / e.TotalBytesToReceive  + "%");
    }
    //下载完成
    void DownloadDataCallback(object sender, DownloadDataCompletedEventArgs data)
    {
        try{
            if (data.Result.Length > 0 && data.Error == null && data.Cancelled == false)
            {
                using (MemoryStream ms = new MemoryStream(data.Result))
                {
                    byte[] buffer = ms.ToArray();
                    string path = @"D:\Unity-Teacher\Teach_TCP\Assets/iamge.png";
                    File.WriteAllBytes(path, buffer);
                    Debug.Log("下载完成");
                }
            }
        } catch (Exception exception){
            throw exception;
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读