一直搞不明白SocketWebSocketWebRTC的关系,最近有时间,就来研究一下。

HTTP


HTTP1.O 和 HTTP1.1

开发中,最常用的协议就是HTTPHTTP是应用层中的协议,基于TCP来实现传输数据。客户端请求一次数据会通过TCP的三次握手建立连接,连接建立以后,服务器发送数据到客户端,之后断开连接,如此循环。这就造成了一些性能和资源的浪费。例如,一个包含许多图像网页文件中并没有包含真正的图像数据,只是指明了图像的URL地址,客户端需要建立好多连接来请求图片信息,这样会非常的耗时以及浪费资源。所以在Http1.1时,添加了支持持久连接的特性,在一个TCP连接上可以发送多个请求和响应,减少了建立和关闭连接的消耗和延迟。

Polling

但是HTTP还有一个缺点,就是只能客户端主动去拉取数据,假如服务端有数据想主动推给客户端,那么HTTP则无能为力。但是可以通过Polling轮训的方式模拟实时数据。例如,客户端可以开启定时器,每1秒发送一次HTTP请求,如果服务端有数据则返回。这种方式下,会消耗大量的流量以及资源。是最不适合做APP端的,因为APP端的流量,电量等都是比较稀缺的资源。


image
Long polling

长轮训是对轮训的改进版,客户端发送HTTP给服务器之后,如果服务器这时没有新消息,就一直等待,当有新消息的时候,才会返回给客户端。当然,某种程度上减少了流量和CPU的消耗。但是这种方式还是有一种弊端,假如服务端的数据更新很快,但是只有当客户端再次询问时才能返回。而且每次发HTTP请求都会携带很重的数据头,有时候这些数据并不是必须的,这就造成了网络资源的浪费。


image

iOS端比较常用的HTTP协议封装框架为AFNetWorking

TCP 三次握手以及四次挥手


三次握手

TCP/IP协议中,TCP协议提供可靠的传输服务,采用三次握手建立一个连接:

  1. 第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认
  2. 第二次握手:服务器B收到SYN包以后,必须确定客户端A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态
  3. 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。
    完成三次握手,客户端与服务器开始传输数据。

    image
四次挥手
  1. 客户端发送一个FIN,用来关闭客户端A到服务器B的数据传输
  2. 服务器B收到这个FIN,它发回一个ACK,确定序号为收到的序号加1,和SYN一样
  3. 服务器B关闭与客户端A的连接,发送一个FIN给客户端A
  4. 客户端A发回ACK报文确定,并将确定序号设置为收到序号加1

image

WebSocket


现在急需的需求是服务端有数据能主动发送到客户端。需要一种双向通信的协议,而且不需要大量的请求头,于是,在HTML5中发布了一种新的应用层协议WebSocket

WebSocket protocol是HTML5一种新协议,它实现了浏览器与服务器的全双工通信,开始的握手需要借助HTTP请求完成 –百度百科

既然WebSocket是依赖于HTTP的,那么,通过抓包工具来看看WebSocket到底是如何建立连接以及通信的。

先来看一下抓取的数据包:


image

上图可以看出,WebSocket建立连接的过程为:通过TCP的三次握手建立HTTP连接->HTTP携带标识WebSocket的请求头字段去请求服务器建立WebSocket连接->服务器返回数据,建立连接成功。

客户端请求头:

Hypertext Transfer Protocol
GET / HTTP/1.1
Host: 52.187.19.168:8081
Sec-WebSocket-Key: 1eHauGgbrITvMLq1edcIHQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
Origin: http://52.187.19.168:8081
Authorization: Basic KG51bGwpOihudWxsKQ==
Connection: Upgrade

可以看到,HTTP请求头中多了标识WebSocket的字段。Sec-WebSocket-Key是客户端使用Base64编码的密文,要求服务端必须返回一个对应加密的Sec-WebSocket-Accept应答,否则客户端会校验错误,并关闭连接。Upgrade标识客户端需要的是WebSocket协议进行通信。

服务端响应头:

Hypertext Transfer Protocol
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: oa7vt9HSY2VFOfM+Jmuoc1p4wfY=

Sec-WebSocket-Accept的值是服务端采用和客户端一致的秘钥计算出来后返回给客户端的,HTTP/1.1 101 Switching Protocols表示服务器接受WebSocket协议的客户端连接,经过这样的请求-响应处理后,客户端服务端的WebSocket连接握手成功,之后通过TCP连接,客户端和服务端都能主动向对方推送数据。

iOS端常用的WebSocket协议封装框架为SocketRocket,它是基于NSInputStreamNSOutputStream进行数据传输。

Socket


首先,Socket其实并不是一个协议,它工作在OSI模型会话层,是为了方便大家直接使用更底层协议(一般是TCPUDP)而存在的一个抽象层。Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口。


image

Socket通常也称作套接字,用于描述IP地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定。应用程序通常通过套接字向网络发生请求或者应答网络请求。

WebRTC


WebRTC名称源自网页实时通信(Web Real-Time Communication)的缩写,简而言之它是一个支持网页浏览器进行实时语音对话或视频对话的技术。

传统的客户端与客户端进行通信是这样的:首先需要客户端A和服务器,客户端B和服务器建立信道,A给B发送消息时,A先将消息发送到服务器上,服务器对A的消息进行中转,发送到B处,反过来也是一样。这样A和B之间的一次消息要通过两段信道,通信的效率同时受制于这两段信道的带宽,那为什么不让A和B直接通信呢?WebRTC应运而生。WebRTC是一种点对点技术,通过已系列的信令,在客户端A和客户端B之间建立一个信道,这样客户端A和客户端B就可以直接发送数据而不经过服务器。WebRTC为我们提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:Windows、Linux、Mac、android、iOS。

WebRTC的服务与信令

首先要明确一点,WebRTC虽然是基于P2P的音视频通信技术,但是,WebRTC仍然需要服务器来进行信令的中转,只是音视频数据不再通过服务器中转。


image

另外,由于WebRTC主要用来解决实时通信的问题,可靠性并不是很重要,因此,WebRTC使用UDP作为传输层协议。当然,WebRTC还需要解决NAT的问题。关于WebRTC更详细的资料,有兴趣的可以查询相关文档。