HTTP 请求

1、完整HTTP请求与响应包含的必要元素
2、HTTP不同版本之间的差异
3、HTTP、Socket、TCP的区别(易混)

一、HTTP 协议
HTTP本质上是一种协议,全称是Hypertext Transfer Protocol,即超文本传输协议。从名字上可以看出该协议用于规定客户端与服务端之间的传输规则,所传输的内容不局限于文本(其实可以传输任意类型的数据)。

二、HTTP请求与响应的内容
看一个POST请求的示例图


以上示例图中其实已经包含了一个HTTP请求所必备的几大要素:请求行、请求头(headerField)、请求体(body);同理,响应也有状态行、响应头、实体内容。接下来我们逐个展开。
1、请求行
请求行包含请求方法(Method)、请求统一资源标识符(URI)、HTTP版本号;

1请求方法就是我们所熟悉的POST、GET、HEAD、PUT等;
2)URI就是URL中排除掉Host剩下的部分,也就是资源在服务器本地上的路径
3)HTTP版本号,目前主流的版本是1.1(1999年开始采用),最新的版本是2.0(2015年5月发布)。不同版本之间差异下面会再展开
2、请求头
请求头主要存放对客户端想给服务端的附加信息,下图框框的部分就是请求头


HTTP请求在iOS中用NSURLRequest与NSMutableRequest表示;HTTP响应用NSHTTPURLResponse表示。

Host: test.dabaidoctor.com
Content-Type: application/x-www-form-urlencoded
Accept: */*
Connection: keep-alive
Cookie: Hm_lvt_f674b880b5ccff4b49dea707ae6d0a59=1458724181
User-Agent: dabaimama/1.9.1 (iPhone; iOS 9.1; Scale/2.00)
Accept-Language: zh-Hans-CN;q=1
Accept-Encoding: gzip, deflate
Content-Length: 263

Host: 目标服务器的网络地址
Accept: 让服务端知道客户端所能接收的数据类型,如text/html */*
Content-Type: body中的数据类型,如application/json; charset=UTF-8
Accept-Language: 客户端的语言环境,如zh-cn
Accept-Encoding: 客户端支持的数据压缩格式,如gzip
User-Agent: 客户端的软件环境,我们可以更改该字段为自己客户端的名字,dabaimama/1.9.1 (iPhone; iOS 9.1; Scale/2.00)
Connection: keep-alive,该字段是从HTTP 1.1才开始有的,用来告诉服务端这是一个持久连接,“请服务端不要在发出响应后立即断开TCP连接”。关于该字段的更多解释将在后面的HTTP版本简介中展开
Content-Length: body的长度,如果body为空则该字段值为0。该字段一般在POST请求中才会有。
Cookie: 记录者用户信息的保存在本地的用户数据,如果有会被自动附上

3、请求体
真正需要发给服务端的数据,在使用POST-multipart上传请求中请求体就是上传文件的二进制NSData类型数据;在GET请求中请求体为空;在普通的POST请求中请求体就是一些表单数据。在iOS中一般用NSURLRequest与NSMutableURLRequest的HTTPBody属性表示,添加body用-[NSMutableURLRequest setHTTPBody:]。


Response

HTTP/1.1 200 OK
Date: Wed, 30 Mar 2016 09:52:48 GMT
Server: Apache/2.2.15 (CentOS)
Content-Length: 770
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/json;charset=UTF-8


{"result":[{"msg":"","commstar":"","productId":"0","nickName":"","sex":"0","stars":"0","askerId":"2195","babyAge":"0","recordId":"119405","realName":"","ageStr":"","doctorId":"0","createT":"03-29 18:36","doctors":"","babySex":"0","babyLogo":"","evalutionmsg":"","logo":"","babyName":"","lastmsg":"{\"body\":\"匿名向您咨询\",\"feedbackstatus\":\"0\",\"from\":\"huser2195\",\"kbubblecolor\":\"0\",\"msgId\":\"1459247810.789\",\"nickName\":\"\",\"recordid\":\"119405\",\"to\":\"huser315\",\"type\":\"notice\",\"userLogo\":\"\"}","finshT":"","age":"0","babyAgeStr":"","status":"0"}],"msg":"success","comm":{"userId":"315","phoneType":"","phoneToken":"13984b70f5705d9e44f61d004d7ad563ff31577139e0dadd90d674555b664a5d","clientVersion":"2.0.1"},"code":"200","status":"1"}

4、响应状态行

状态行是服务端返回给客户端的状态信息,包含HTTP版本号、状态码、状态码对应的英文名称。

以下就是典型的正确状态行:

HTTP/1.1 200 OK

这个部分需要讲的是错误码。事实上HTTP请求错误码可以根据错误码从左往右第一个数字大致分为以下几类:


1XX:信息提示。不代表成功或者失败,表示临时响应,比如100表示继续,101表示切换协议

2XX: 成功

3XX: 重定向

4XX:客户端错误,很有可能是客户端发生问题,如亲切可爱的404表示未找到文件,说明你的URI是有问题的,服务器机子上该目录是没有该文件的;414URI太长

5XX: 服务器错误,比如504网关超时


错误码是不用去记的,出错了再查对应的错误码含义就行。但是知道上面的分类有助于第一时间做出大体的判断,起码你能清楚是服务端还是客户端的原因。


5、响应头和响应实体

这部分与请求部分差异不大,响应头的字field会有稍许不同,响应头中的header field同样移步请求头响应头列表。

三、HTTP版本简介

这里我把HTTP版本简单分为三类:1.1之前,1.1,2.0,针对这三类做个主要差异的介绍:


HTTP 1.1之前


  • 不支持持久连接。一旦服务器对客户端发出响应就立即断开TCP连接

  • 无请求头跟响应头

  • 客户端的前后请求是同步的。下一个请求必须等上一个请求从服务端拿到响应后才能发出,有点类似多线程的同步机制。


HTTP 1.1(主流版本)


与1.1之前的版本相比,做了以下性能上的提升


  • 增加请求头跟响应头

  • 支持持久连接。客户端通过请求头中指定Connection为keep-alive告知服务端不要在完成响应后立即释放连接。HTTP是基于TCP的,在HTTP 1.1中一次TCP连接可以处理多次HTTP请求

  • 客户端不同请求之间是异步的。下一个请求不必等到上一个请求回来后再发出,而可以连续发出请求,有点类似多线程的异步处理。


HTTP 2.0


本着向下兼容的原则,1.1版本有的特性2.0都具备,也使用相同的API。但是2.0将只用于https网址。由于2.0的普及还需要比较长的一段时间,这里不展开,更多新特性请参考这篇文章


我们重点关注一下当前1.1版本所做几点改变。支持持久连接有什么好处呢?HTTP是基于TCP连接的,如果连接被频繁地启动然后断开就会花费很多资源在TCP三次握手以及四次挥手上,效率低下。以请求一个网页为例,我们知道,一个html网页上的图片资源并不是直接嵌入在网页上,而只是提供url,图片仍需要额外发HTTP 请求去下载。一个网页从请求到最终加载到本地往往需要经过过个HTTP请求。在1.1版本之前请求一个网页就需要发生多次"握手-挥手"的过程,每次连接之间相互独立;而1.1及之后的版本最少只需要一次就够。


HTTP是应用层的协议,更靠近用户端;TCP是传输层的协议;而socket是从传输层上抽象出来的一个抽象层,本质是接口。所以本质上三种还是很好区分的。尽管如此,有时候你可能会懵逼,HTTP连接、TCP连接、socket连接有什么区别?好吧,如果上面的图解释的还是不够清楚的话,我们继续往下看。


1、TCP连接与HTTP连接的区别


上文提过,HTTP是基于TCP的,客户端往服务端发送一个HTTP请求时第一步就是要建立与服务端的TCP连接,也就是先三次握手,“你好,你好,你好”。从HTTP 1.1开始支持持久连接,也就是一次TCP连接可以发送多次的HTTP请求。


小总结:HTTP基于TCP


2、TCP连接与Socket连接的区别


在图4.1中我们提到,socket层只是在TCP/UDP传输层上做的一个抽象接口层,因此一个socket连接可以基于连接,也有可能基于UDP。基于TCP协议的socket连接同样需要通过三次握手建立连接,是可靠的;基于UDP协议的socket连接不需要建立连接的过程,不过对方能不能收到都会发送过去,是不可靠的,大多数的即时通讯IM都是后者。


小总结:Socket也基于TCP


3、HTTP连接与Socket连接的区别


区分这两个概念是比较有意义的,毕竟TCP看不见摸不着,HTTP与Socket是实实在在能用到的。


  • HTTP是短连接,Socket(基于TCP协议的)是长连接。尽管HTTP1.1开始支持持久连接,但仍无法保证始终连接。而Socket连接一旦建立TCP三次握手,除非一方主动断开,否则连接状态一直保持。

  • HTTP连接服务端无法主动发消息,Socket连接双方请求的发送先后限制。这点就比较重要了,因为它将决定二者分别适合应用在什么场景下。HTTP采用“请求-响应”机制,在客户端还没发送消息给服务端前,服务端无法推送消息给客户端。必须满足客户端发送消息在前,服务端回复在后。Socket连接双方类似peer2peer的关系,一方随时可以向另一方喊话。


4、问题来了:什么时候该用HTTP,什么时候该用socket


这个问题的提出是很自然而然的。当你接到一个与另一方的网络通讯需求,自然会考虑用HTTP还是用Socket。


  • 用HTTP的情况:双方不需要时刻保持连接在线,比如客户端资源的获取、文件上传等。

  • 用Socket的情况:大部分即时通讯应用(QQ、微信)、聊天室、苹果APNs等


在iOS中,发HTTP请求一般用原生的NSURLConnection、NSURLSession或者开源的AFNetWorking(推荐)、ASIHttpRequest(已停止更新)。连接Socket连接我用的比较多是robbiehanson大神的CocoaAsyncSocket(XMPPFramework也是出自他手)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值