什么是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层不提供这样的流机制,而是提供不可靠的包交换。
-
互联网的5层协议
Protocols.png
它们叫什么名字,其实并不重要。只需要知道,互联网分成若干层就可以了。
每一层都是为了完成一种功能。为了实现这些功能,就需要大家都遵守共同的规则。
大家都遵守的规则,就叫做"协议"(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区别
-
1.请求数据:
GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,多个参数用&连接;例 如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST提交:把提交的数据放置在是HTTP包的包体中。上文示例中斜体字就是实际的传输数据,因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变。 -
2.传输数据的大小:
首先声明:HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。
而在实际开发中存在的限制主要有:
GET:特定浏览器和服务器对URL长度有限制,例如 IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系 统的支持。因此对于GET提交时,传输数据就会受到URL长度的 限制。
POST:由于不是通过URL传值,理论上数据不受 限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。 -
3.安全性:
POST的安全性要比GET的安全性高。比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存, (2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击。
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的解释,有上传与下载方法:
-
WebClient提供一些上传方法:
image -
WebClient提供一些下载方法:
image -
WebClient与其他网络相关类的区别
WebClient和HttpWebRequst是用来获取数据的2种方式,一般而言,WebClient更倾向于“按需下载”,事实上掌握它也是相对容易的,而HttpWebRequst则允许你设置请求头或者对内容需要更多的控制,
后者有点类似于form中的submit。虽然两者都是异步请求事件,但是WebClient是基于事件的异步,而HttpWebRequst是基于代理的异步编程。 -
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;
}
}
}
网友评论