Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP和WebSocket #5

Open
SumyHu opened this issue Dec 11, 2018 · 1 comment
Open

HTTP和WebSocket #5

SumyHu opened this issue Dec 11, 2018 · 1 comment

Comments

@SumyHu
Copy link
Contributor

SumyHu commented Dec 11, 2018

HTTP

TCP协议

TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP协议在发送请求前会先通过三次握手协议建立可靠连接。建立连接后,才开始发送请求,每发一个请求,在超时时间内收到响应信息,则继续发送下一个请求,否则,重发。因此,TCP通信协议可以确保每一个请求都能准确送达,请求发送速度会比较慢,但可靠性高。适合于发送数据量大,对请求可靠性要求高的请求。

TCP协议的特点:

  • 面向连接
  • 可靠性高
  • 传输速度比较慢
  • 适用于发送数据量大,对请求可靠性要求高的请求

UDP协议

UDP是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。
UDP协议在发送请求前,源端和终端不建立连接,直接发送请求,一次性将所有请求发送出去,不关心是否接收到响应信息,所以对于超时无响应的请求不会重发。所有的请求只管发送,不管是否送达,可靠性低,但是发送速度快。适合于发送数据量少、对可靠性要求低的请求。

UDP协议的特点:

  • 面向非连接
  • 传输不可靠
  • 传输速度快
  • 适用于发送数据量少、对可靠性要求低的请求

HTTP请求

  • http连接=以http协议为通信协议的tcp连接
  • http短连接=以http协议为通信协议的,请求一次就断开的tcp连接
  • http长连接=以http协议为通信协议的,请求多次才断开的tcp连接(减少建立tcp连接的次数达到节省两端资源的目的)

HTTP请求通信过程

image
HTTP通信协议在发送请求前先通过“三次握手”建立可靠连接,连接建立成功后发送HTTP请求,请求发送完毕后,通过“四次挥手”断开连接。

三次握手

两个序号和三个标志位:

  1. 序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  2. 确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。
  3. 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
    • URG:紧急指针(urgent pointer)有效。
    • ACK:确认序号有效。
    • PSH:接收方应该尽快将这个报文交给应用层。
    • RST:重置连接。
    • SYN:发起一个新连接。
    • FIN:释放一个连接。
      image
  • 在第一次消息发送中,A随机选取一个序列号作为自己的初始序号发送给B;第二次消息B使用ack对A的数据包进行确认,
  • 因为已经收到了序列号为x的数据包,准备接收序列号为x+1的包,所以ack=x+1,同时B告诉A自己的初始序列号,就是seq=y;
  • 第三条消息A告诉B收到了B的确认消息并准备建立连接,A自己此条消息的序列号是x+1,所以seq=x+1,而ack=y+1是表示A正准备接收B序列号为y+1的数据包。
  • 确认方ack=发起方req+1,两端配对。

image

四次挥手

image

  • 由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,
  • 收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。
  • 首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
  1. 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  2. 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  3. 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  4. 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

HTTP1.0和HTTP1.1的区别

image
HTTP1.0为短连接,即上图左侧所示;HTTP1.1为长连接,即上图右侧所示。
长短连接的区别在于:短连接在每次发送请求前先通过“三次握手”协议建立连接,发送完一个请求后即刻断开连接,如此循环往复;长连接在发送请求前先通过“三次握手”协议建立连接,每次请求结束不断开连接,请求多次也不需要重新建立连接,直到达到超时时间也没有新的请求发送才断开tcp连接。

HTTP协议的特点

  • 一个request对应一个response
  • 服务器不能主动发信息给客户端

HTTP在双向通信中的解决方案

双向通信:客户端和服务端可以自由通信,即客户端可以主动给服务端发送数据,也可接收服务端发送的数据;同理,服务端也可以主动给客户端发送数据,也可接收客户端发送的数据。

方法一:轮询

轮询的原理非常简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

场景再现:
客户端:啦啦啦,有没有新信息(Request)
服务端:没有(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:没有。。(Response)
客户端:啦啦啦,有没有新信息(Request)
服务端:你好烦啊,没有啊。。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:好啦好啦,有啦给你。(Response)
客户端:啦啦啦,有没有新消息(Request)
服务端:。。。。。没。。。。没。。。没有(Response) ---- loop

方法二:Comet模型
  • 长轮询
    long poll 其实原理跟【轮询】差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。

场景再现
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request)
服务端:额。。 等待到有消息的时候。。来 给你(Response)
客户端:啦啦啦,有没有新信息,没有的话就等有了才返回给我吧(Request) -loop

  • The forever iframe technique
    在页面中隐藏一个iframe标签,然后将这个iframe的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。但是这种方法有一个很明显的问题,各个浏览器会一直显示页面加载没有完成,如果用户是个强迫症,他一定会分分钟关掉页面的……

WebSocket

实际上TCP长连接就是WebSocket的基础
image
使用WebSocket通信协议,可以实现客户端和服务端的双向通信。

WebSocket代码实现

  • 服务端:
    image
    image

  • 客户端:
    image

典型的WebSocket握手

  • 客户端请求信息:
    image

  • 服务器响应信息:
    image

WebSocket和HTTP

  • 相同点:
  1. 都是基于TCP的应用层协议。
  2. 都使用Request/Response模型进行连接的建立。
  3. 在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码。
  4. 都可以在网络中传输数据。
  • 不同点:
  1. WS使用HTTP来建立连接,但是定义了一系列新的header域(upgrade、Sec-WebSocket-*),这些域在HTTP中并不会使用。
  2. WS的连接不能通过中间人来转发,它必须是一个直接连接。
  3. WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据。
  4. WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息。
@Hibop
Copy link
Contributor

Hibop commented Dec 12, 2018

👍 👏👏👏👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants