HTTP简述:
-
http 1.x
1,http/1.0 支撑POST HEAD等恳求办法,浏览器每次恳求都需求与服务器树立一个TCP衔接,恳求处理完后立即断开TCP衔接。
2,http/1.1支撑PUT、DELETE等恳求办法,采用耐久衔接,多个恳求能够共用同一个TCP衔接。
-
http2.0
1,在运用层与传输层之间,增加了一个二进制分帧层。
2,多路复用,能够完成并行发送多个恳求。http 1.x版别是长衔接,但多个恳求发送是串行。
3,能够对浏览器等候的要害的数据流设置优先级,对数据流能够采用不同的优先级战略。
4,更多细节…
-
https http的安全版,运行在安全套接字协议(SSL)或传输层安全协议(TLS)之上,树立了一个信息安全通道,所有的TCP中传输的内容都需求经过加密,保证了数据安全。衔接端口是443。TLS后文有简述。
-
tcp传输操控协议:是全双工通讯。
1,首部至少20个字节;UDP首部只要8个字节(源端口号+目的端口号+UDP长度+UDP校验和 均是16位)。
2,可靠传输(ARQ:超时自动重传恳求;滑动窗口协议,是点对点的通讯操控)
3,流量操控(根据接纳方窗口缓冲区操控发送方的发送速率)
4,拥塞操控(举例:慢开端:指数增加;拥塞防止:加法线性增加;快康复+快重传:当发现带宽网络拥塞时,将ssthresh阈值减为拥塞峰值的一半,然后进行快康复且运用加法增大传输数据包。 ps:经过wireshark抓包一个TCP衔接的数据展现如图:
-
tcp三次握手之后TLS握手:(三次握手四次挥手略,老生常谈)
1,客户端会发送一个ClientHello恳求,内容包括支撑的TLS版别、加密套件以及一个随机数。
2,服务器收到后会呼应ServerHello(会包括一个随机数)、下发服务器自己的证书(客户端可根据证书列表check服务器是否可信)和ServerKeyExchange(包括服务器随机生成的一对密钥中的公钥pubkey),然后呼应ServerHelloDone。
3,客户端进行ClientKeyChange操作,向服务器发送的内容中,包括公钥pubkey加密后的第三个随机数(预主密钥),以及Change Cipher Spec奉告服务器用商定好的算法和密钥进行加密,然后奉告服务器Encrypted Handshake message。
4,服务器收到后用私钥解密获取到预主密钥并呼应Encrypted Handshake message 。
5,根据上述通讯,客户端和服务器都具有了相同的两个随机数和预主密钥,然后经过约定好的算法生成最终的会话密钥,此后经过对称暗码进行数据传输。
-
数字证书(数字签名):私钥加密公钥解密,文章内容会经过哈希算法参加其间,因而可验证文件完整性。
数字签名的进程:
1,用户将主体信息(包括一串随机数后面作为私钥privatekey)发给CA,CA会利用主体信息生成主体文件的公钥而且进行签名,签完名的文件便是数字证书,回来给用户。 2,用户将文件经过单向散列函数生成128位的摘要,然后用privatekey私钥对此摘要进行加密。
3,当用户将文件,加密的摘要,公钥publickey发送其他用户时。他人能够对文件进行同样的单向散列函数发生的摘要h1和用publicekey对加密后的摘要解密生成的摘要h2进行比对。假如相等,则文件合法未被篡。
客户端端拿到服务器下发的证书时,会对文件信息进行hash算法得到一个数字指纹h1,以及经过用ca公钥(本地保存的)解密签名会得到一个数字指纹h2,假如h1和h2共同,则证书合法。假如是客户端拿到服务器发送的签名证书,则会向CA验证证书的合法性。一般浏览器出厂时会内置了诸多CA机构的数字证书校验办法。 拓宽:在区块链的实际运用上,币买卖时,input买方需求拿到output卖方的公钥。
客户端与服务器的交互
-
JWT:json web token
1,普通的token:服务端验证token信息要进行数据的查询操作;而JWT验证token信息并不用,在服务端运用密钥校验就能够,无需查询数据库。
2,组成:Header头部(base64后)+Playload负载(base64后)+signature签名
3,作业流程
- 跨域: 服务器呼应头设置Cors,在header中装备”Access-Control-Allow-Origin”,表明答应访问者能够跨域访问,而且指定答应的域。 客户端恳求头header中”Origin”字段,表明建议一个针对跨域资源共享的恳求。
- cookie与session :Cookie是根据客户端存储数据到本地,服务端能够回来Cookie交给客户端存储。Session是根据服务器存储数据。 客户端初次向服务端建议树立网络恳求后,服务端会树立一个Session,在呼应头中装备”SetCookie:JSESSIONID=xxx”以及domain等。客户端收到后会设置Cookie保存JSESSIONID。在Cookie有效期后,在今后的request恳求中,都会带上此JSESSIONID,服务端接纳到此恳求后,会找到之前现已树立的SESSION。
socket与WebSocket
- socket:并非协议,是根据TCP/IP网络封装的API,为了方便TCP或UDP而抽象出来的一层,是坐落运用和传输操控层之间的一组接口,socket利用TCP/IP协议树立TCP衔接,进行依靠于底层的IP协议,更深层次依靠于数据链路层。 保持长链接。
socket的树立进程如图:
代码演示:
//客户端:
public static final int PORT = 8080;
public static final String HOST = "127.0.0.1";
Socket socket = new Socket(HOST, PORT);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
os.write("向服务端写数据");
socket.shutdownOutput();
// 读取服务器发送的数据
byte[] buffer = new byte[8192];
int len;
while ((len = is.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
//服务端:
//创立ServerSocket的接口
public ServerSocket(int port) throws IOException {
this(port, 50, null);
}
ServerSocket(int port, int backlog, InetAddress bindAddr);
public InetSocketAddress(InetAddress addr, int port) {
holder = new InetSocketAddressHolder(
null,
addr == null ? InetAddress.anyLocalAddress() : addr,
checkPort(port));
}
ServerSocket server = ServerSocket(PORT);
Socket sk = server.accept();
//读写数据,代码 类上
- webSocket:HTTP、WebSocket等运用层协议,都是根据TCP协议来传输数据的。有必要依靠HTTP协议进行一次握手,握手成功后,数据就直接从TCP通讯传输,与HTTP无关了。WebSocket API是HTML5规范的一部分,完成了客户端与服务端全双工通讯,而HTTP是单向通讯。 代码演示:
//代码描摹于某大神,有逻辑改动
//server.js
//终端安装websocket库:npm install websocket
var websocket = require('websocket').server
var http = require('http')
const HOST = 'http://127.0.0.1:8080';
const PORT = 8080;
var httpServer = http.createServer().listen(PORT, function(){
console.log(HOST)
})
var wsServer = new websocket({
httpServer: httpServer,
autoAcceptConnections: false,
})
wsServer.on('request', function (request) {
var connect = request.accept()
connect.on('message', function (message) {
console.log(Date.now());
message.fromServer = 1;
console.log(message)
connect.send(message.utf8Data)
})
//监听封闭衔接操作
connection.on("close", function (code, reason) {
var message = {}
message.type = "leave"
message.data = "脱离了"
connect.send(JSON.stringify(message))
})
//过错处理
connection.on("error", function (err) {
console.log(err)
})
})
//浏览器端:经过<script>的方法运用WebSocket功用。
<script>
const hostPort = 'ws://127.0.0.1:8080'
var webSocket = new WebSocket(hostPort)
/*readyState总共四种状况
0: 链接还没有树立,正在树立链接
1:链接树立
2:链接正在封闭
3:链接现已封闭
*/
webSocket.onopen = function(){
console.log(webSocket.readyState)
}
function send(){
var text = document.getElementById('text').value
webSocket.send(text)
}
webSocket.onclose = function () {
console.log("websocket close")
}
//实时监听服务器推送到客户端的事情
webSocket.onmessage = function (msg) {
console.log(Date.now());
showMessage(msg.data, msg.type)
}
//在页面中现实谈天内容
function showMessage(str, type) {
var div = document.createElement('div')
div.innerHTML = str;
if (type == "enter") {
div.style.color = "blue";
} else if(type == "leave") {
div.style.color = "red"
} else if(type == "message") {
div.style.color = "black"
}
document.body.appendChild(div)
}
</script>
WebRTC技术是H5规范之一,它经过简单的API为浏览器和移动端运用程序供给了实时通讯的功用
- WebRTC结构
- WebRTC通话原理:
1,媒体洽谈:简而言之,便是对通讯两头能够支撑的编解码格局取交集,例如A端支撑VP8、H264,B端支撑H264,H265,那么为保证AB两头通讯正常,则选H264…。SDP(Session Description Protocol)用于描绘上述这类信息。视频通讯双方有必要先交换SDP信息,这个进程叫媒体洽谈。
2,网络洽谈:通讯两头要了解对方的网络状况,以保证找到一条彼此通讯的链路。抱负的场景是两头都是私有公网IP,能够直接peer2Peer衔接。但真实的状况,终端都是在局域网中,需求NAT(Network Address Translation:网络地址转化)。为处理WebRTC这些问题,引出了STUN和TURN。
(1)STUN(Session Traversal Utilities for NAT, NAT会话穿越运用程序)是一种网络协议,它答应坐落NAT后的客户端找出自己的公网地址,查出自己坐落哪种类型的NAT之后,以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间创立UDP通讯。这样就能给无法在公网环境下的视频通讯设备分配公网IP以树立通话衔接。简而言之:STUN是奉告我对方的公网IP地址+端口。
媒体流传输依照P2P的方法,STUN并不是每次都能成功地为需求NAT的通讯端分配IP地址,P2P地方法在多人视频通话中,更是严重依靠本地的带宽。TURN能够很好的处理这个问题。
(2)TURN(Traversal Using Relays around NAT)是STUN/RFC5389的一个拓宽。首要添加了Relay功用。假如终端在NAT之后,那么在特定的状况下,有可能使得终端无法和其对等端进行直接的通讯,这时就需求公网的服务器作为一个中继,对来往的数据进行转发,这个转发协议就被界说为TURN。这种方法的带块由服务器端处理。
(3)在WebRTC中用来描绘网络信息的术语叫candidate,也叫网络洽谈。
3,信令体系(信令服务端)
(1)信令服务端包括交互媒体信息sdp和网络信息candidate,以及房间办理和人员进出等;
(2)信令发送进程:
//信令集合
//自动加入房间
const SIGNAL_TYPE_JOIN = "join"
//奉告加入者对方是谁
const SIGNAL_TYPE_RESP_JOIN = "resp-join"
//自动脱离房间
const SIGNAL_TYPE_LEAVE = "leave"
//有人加入房间 告诉现已在房间的人
const SIGNAL_TYPE_NEW_PEER = "new-peer"
//有人脱离房间 告诉现已在房间的人
const SIGNAL_TYPE_PEER_LEAVE = "peer-leave"
//发送offer给对端peer
const SIGNAL_TYPE_OFFER = "offer"
//发送offer给对端peer
const SIGNAL_TYPE_ANSWER = "answer"
//发送candidate给对端peer
const SIGNAL_TYPE_CANDIDATE = "candidate"
// 初始化本地媒体流:
navigator.mediaDevices.getUserMedia({
audio:true,
video:true
})
// 打开本地媒体流
varlocalVideo=document.querySelector('#localVideo');
localVideo.srcObject=stream;//显现画面
localStream=stream;//保存本地流的句柄
//DoOffer:
1,创立RTCPeerConnecttion对象并设置onicecandidate监听事情。监听事情中会触发 candidate信令。见下一代码块
2,写入本地session描绘
3,发送offer信令
//handleRemoteOffer:
1,写入远端session描绘
//DoAnswer:
1,写入本地session描绘,并发送answer信令。
//HandleRemoteAnswer:
写入本地session描绘
RTCPeerConnection音视频通话的中心类
//描摹代码拿来主义(建议整个信令体系描摹一遍,细节印象更深入)
functioncreatePeerConnection(){
vardefaultConfiguration={
bundlePolicy:"max-bundle",
rtcpMuxPolicy:"require",
iceTransportPolicy:"all",//relay或许
//修正ice数组测试作用,需求进行封装
iceServers:[
{
"urls":[
"turn:![]()192.168.0.1:61313?transport=udp",
"turn:![]()192.168.0.1:61313?transport=tcp"//能够插入多个进行备选
],
"username":"kinno_CN",
"credential":"There will be more surprises here, Beyond foresight"
},
{
"urls":[
"stun:![]()192.168.0.1:61313"
]
}
]
};
pc=newRTCPeerConnection(defaultConfiguration);
pc.onicecandidate=handleIceCandidate;
pc.ontrack=handleRemoteStreamAdd;
pc.onconnectionstatechange=handleConnectionStateChange;
pc.oniceconnectionstatechange=handleIceConnectionStateChange
localStream.getTracks().forEach((track)=>pc.addTrack(track,localStream));//把本地流设置给RTCPeerConnection
}
function handleRemoteStreamAdd(event) {
remoteStream = event.streams[0]
remoteVideo.srcObject = remoteStream;
}
ps:在运用模仿服务器软件XShell(最新版)时,会提示安装过错,需求修正注册表,修正后重启会ok。