网路模型
OSI七层模型采用了分层的结构化技术,共分七层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
TCP/IP协议将七层网络模型改为了四层,分别是:应用层、传输层、网络层、链路层。
常见协议
TCP
TCP 是面向连接的、可靠的流协议,通过三次握手建立连接,通讯完成时通过四次分手来拆除连接。
由于TCP是面向连接的所以只能用于端到端的通讯。
TCP/IP中的数据包
在每个分层中,都会对所发送的数据附加一个首部,在这个首部中包含了该层必要的信息,如发送的目标地址以及协议相关信息。通常,为协议提供的信息为包首部,所要发送的内容为数据。在下一层的角度看,从上一层收到的包全部都被认为是本层的数据。
三次握手
三次握手是指建立一个TCP连接时需要客户端和服务器总共发送三个包,过程如下:
类似聊天场景:
A -> B:在吗?
B -> A:在,你还在吗?
A - > B:在。
- 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
- 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
- 第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
四次分手
四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开,过程如下:
谈恋爱场景:
- 女:生气了说,我们分手...
- 男:分手就分手...
- 男(冷静下来了):你确定要分手...
- 女(生气中):就是要分...
然后男方就认为真的分了,女方还在等男的来找,结果男的一直不来女方就死心了。
客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCP后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
可靠传输
使用ack
和序列号机制来保证数据传输的可靠性,在第一时间内没有收到ack
就认为包丢失,然后进行重发,当接收方判断序号是处理过的时候会直接丢弃,然后进行ack
,如图:
流量限制
TCP使用滑动窗口的方式来进行流量控制。窗口实际表示的是接收能力,用以限制发送方的发送速度。
UDP
UDP是面向无连接的通讯协议,UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象。
UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。
UDP一般用来传输音频视频等。
HTTP
HTTP是一个运行在TCP协议之上的应用层协议,主要是应用于WEB端内容获取。
数据包的传输过程
HTTP数据包的传输过程,和TCP/IP协议的数据包传输过程是一致的,都是发送端每层都会对数据包加上首部,然后接收端每层在去掉首部,最后获取到原始数据,如图:
HTTP的请求过程
HTTP是基于客户/服务器模式,且面向连接的,一次完整的请求过程分为如下几步:
- 建立 TCP 连接(之前可能还有一次DNS域名解析)。
- 客户端向服务器发送请求命令。
- 客户端发送请求头信息。
- 服务服务器应答器。
- 返回响应头信息。
- 服务器向客户端发送数据。
- 服务器关闭 TCP 连接。
HTTP报文格式
HTTP的报文主要分为请求报文和响应报文。请求报文是从客户机到服务器的请求报文,响应报文是从服务器到客户机的响应报文。
请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,下面给出了请求报文的一般格式,如图:
1. 请求行
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
2. 请求头
请求头部由键值对组成,每行一对,键和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,如:
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Content-Length: 0
Cookie: AnonymousUserId=bef08e4a-cb38-4571-bcb2-445dcf91cb86; Hm_lvt_49947a1d063f6bf11c7fc356ad0ae63e=1591272374,1592016822; __RequestVerificationToken=68UleNJ4mrJT_tESEbP9a7_iAkwlKGdiVkT-lHakIRrVDjfJd8ep5mdMV4ycVXDY6uIJcQhhmuZjgf1fNpvXwkL98ozZLe50jBPe633SLJg1; Hm_lpvt_49947a1d063f6bf11c7fc356ad0ae63e=1592019818
Host: www.broadview.com.cn
Origin: http://www.broadview.com.cn
Referer: http://www.broadview.com.cn/book/5790
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
X-Requested-With: XMLHttpRequest
3.空行
这里的空行表示通知服务器,请求头到此结束,其实就是请求头的结束符。
4. 请求数据
请求数据应用在POST类型的请求中,适用于需要客户填写表单的场景。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
响应报文
HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文。响应报文和请求报文唯一的区别在于第一行中用状态信息代替了请求行,通过命令curl -I https://proxy.mimvp.com
查看响应报文头信息:
HTTP/2 200
server: nginx
date: Sat, 13 Jun 2020 07:20:04 GMT
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
set-cookie: MIMVPSESSID=o7n3uah9585t7ht6abb46f76g8; path=/
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache
vary: proxys-zjk1
状态行(status line)的主要作用是通过提供一个状态码来说明所请求的资源情况。其格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
-
HTTP-Version
:表示服务器HTTP协议的版本; -
Status-Code
:表示服务器发回的响应状态代码; -
Reason-Phrase
:表示状态代码的文本描述。
状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
-
1xx
:指示信息--表示请求已接收,继续处理。 -
2xx
:成功--表示请求已被成功接收、理解、接受。 -
3xx
:重定向--要完成请求必须进行更进一步的操作。 -
4xx
:客户端错误--请求有语法错误或请求无法实现。 -
5xx
:服务器端错误--服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下:
-
200 OK
:客户端请求成功。 -
400 Bad Request
:客户端请求有语法错误,不能被服务器所理解。 -
401 Unauthorized
:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。 -
403 Forbidden
:服务器收到请求,但是拒绝提供服务。 -
404 Not Found
:请求资源不存在,举个例子:输入了错误的URL。 -
500 Internal Server Error
:服务器发生不可预期的错误。 -
503 Server Unavailable
:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
HTTP和HTTPS的区别
简单来说 HTTPS
是 HTTP
的安全版,HTTPS是使用了 TLS/SSL
加密的 HTTP
协议。
HTTPS 和 HTTP 的区别主要为以下几点:
- https 协议需要到 ca 申请证书。
- http 是超文本传输协议,信息是明文传输,https 则是通过ssl加密后进行传输的协议。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
套接字(Socket)
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面。
主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机,然后通过端口来找到主机上对应的应用程序。其实一个Socket = IP + : + 端口
,例如,如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是210.37.145.1:23
。
短连接和长连接
短连接
短链接是指每个连接传输完数据就立马关闭,流程如下:建立socket连接 -> 传输数据 -> 断开连接。在HTTP/1.0中默认使用短连接。
长连接
长连接是指建立Socket连接后不管是否使用都保持连接,但安全性较差。建立连接 -> 传输数据 -> 保持连接 -> 传输数据-> ... -> 关闭连接。而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
TCP的keep alive是检查当前TCP连接是否活着;HTTP的Keep-alive是要让一个TCP连接活久点。
长短连接的优缺点
每次建立TCP连接都需进行三次握手,而三次握手也是需要耗费时间和资源的。使用长连接的好处就是不用每次请求都建立连接,节省了三次握手的时间和资源消耗。
由于服务器资源是有限的,所以服务器所能建立的连接数也是有限的,这就限制了长连接的个数,如果一个长连接长久不实用,并且又不释放的话就会造成服务器资源的浪费,这时候短链接的优势就展现了出来,短链接每次使用完成后就释放连接,不会造成服务器资源的浪费。
长短连接的应用场景
长连接多用于操作频繁的点对点的通讯,而且连接数不能太多。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源。所以并发量大,但每个用户无需频繁操作情况下需用短连好。