计算机网络
计算机网络体系
OSI七层模型
OSI定义了一个网络框架,它从概念上将计算机网络结构从按照逻辑顺序分为了7层,由上而下依次为:
- 应用层:给应用程序提供交互服务(DNS、HTTP、SMTP)
- 表示层:数据格式的转换,如加密解密、转换翻译、压缩解压缩等
- 会话层:在网络的两节点间建立、维持和中止通信
- 传输层:为应用进程之间提供通用的数据传输服务(端到端的服务)
- 网络层:选择合适的路由和交换节点,确保数据及时传送(IP)
- 数据链路层:将网络层传下来的IP数据包组装成帧,在相邻节点的链路上进行传送
- 物理层:利用物理传输介质实现节点间比特流的透明传输
TCP五层模型
TCP五层模型将OSI模型的应用层、表示层、会话层合并为一层应用层,其余不变
TCP相关
TCP/IP协议是什么
TCP/IP协议是一个协议族,包含了应用层,传输层,网络层的多种协议。
之所以命名为TCP/IP协议,是因为TCP、IP协议是其中两个很重要的协议,就以此为代表进行了命名。TCP与UDP都只是其中一种,不要被名字混淆了。
面向有连接型和面向无连接型
- 面向有连接型传输包含了创建连接、数据传输和释放连接三个过程,除此之外还有一系列用于保证传输可靠性与有序性的措施,如超时重传、流量控制等,典型的面向有连接传输有TCP。
- 面向无连接型只提供基本的数据传输功能,不能保证接收数据的顺序与发送数据的顺序一致,典型的面向无连接型传输有UDP、IP。
TCP和UDP
- TCP(Transformation Control Protocals,传输控制协议)是一种面向连接性传输协议,只能进行一对一的通信。它将应用层传下来的报文看作字节流,将字节流拆分成数据块并添加了TCP首部。此外TCP还采取了多种措施保障传输的准确性和有序性,适用于要求可靠传输的应用,例如文件传输
- UDP(User Data Protocol,用户数据报协议)是一种非连接型协议,不需要维护连接状态,因此可以进行一对多、多对多的传输。它对应用层传下来的报文即不拆分也不合并,仅添加UDP首部,因此它是面向报文的,UDP首部信息也很短,只有8字节,相对于TCP的20个字节信息包的额外开销很小。UDP是尽最大努力交付,而不保证可靠交付,适用于实时应用,如IP电话、视频会议、直播等
TCP与UDP的区别总结
- TCP是面向有连接型,UDP是面向无连接型;
- TCP是一对一传输,UDP支持一对一、一对多和多对多的传输;
- TCP能保证的数据的正确和有序性,UDP可能会出现丢包、乱序;
- TCP是面向字节流,UDP是面向报文;
- TCP的首部最小20字节,最大60字节,UDP对首部开销仅8字节;
- TCP的传输速度慢,UDP的传输速度快;
基于TCP和UDP的应用层协议有哪些
TCP对应的典型的应用层协议:
协议 | 全称 | 端口 |
---|
HTTP | Hyper Text Transfer Protocol(超文本传输协议) | 80 | FTP | File Transfer Protocol(文件传输协议) | 20发送,21接收 | SMTP | Simple Mail Transfer Protocol(简单邮件传输协议) | 25 | POP3 | Post Office Protocol 3(邮局协议) | 110 | SSH | Security Shell(远程登录协议) | 22 | TELNET | Teletype Network(远程登录协议) | 23 |
【注】SSH与TELNET都可称为远程登录协议,区别暂不讨论;SMTP用于发送邮件,POP3用于接收邮件
UDP对应的典型的应用层协议:
协议 | 全称 | 端口 |
---|
DNS | Domain Name Service(域名服务) | 53 | TFTP | Trivial File Transfer Protocol(简单文件传输协议) | 69 | SNMP | Simple Network Management Protocol(简单网络管理协议) | 通过UDP端口161接收 只有Trap信息用UDP端口162。 | NTP | Network Time Protocol(网络时间协议) | 123 | OICQ | OpenICQ(I seek you谐音…) | 4000 |
【注】Trivial 是琐碎的意思,在此翻译为简单;OpenICQ是一款国产聊天软件,QQ的前身
TCP三次握手
三次握手的目的
TCP的三次握手就是在发送数据前通过“三次握手”的方式建立起通信连接,目的是让源端和目的端确认一下双方的发送报文能力和接收报文能力是正常的
三次握手具体过程
-
第一次握手 客户端请求建立连接,向服务端发送一个同步报文(SYN=1),同时选择一个随机数作为初始序列号seq=x。随后客户端进入SYN_SENT状态,等待服务端的确认 -
第二次握手 服务端在收到客户端的请求后,如果同意建立连接,则像客户端发送一个同步确认报文(SYN=1,ACK=1),确认号为ack=x+1,并初始化序列号seq=y。随后服务端进入SYN_RECV状态 -
第三次握手 客户端收到服务端的确认后,像服务端发送一个确认报文(ACK=1),确认号为ack=y+1,序列号为seq=x+1。随后客户端和服务端都进入ESTBLISHED状态
理想情况下,TCP连接一旦建立,则在通信双方任何一方主动关闭连接之前,TCP连接都将一直保持下去
为什么要三次握手,不是两次?
- 只有经过三次握手才能让双方均确认自己和对方的发送和接受功能都正常
- 第一次握手,服务端确认“自己收,客户端发”功能正常
- 第二次握手,客户端确认“自己发,自己收,服务端发,服务端收”功能正常
- 第三次握手,服务端确认“自己发,服务端收”功能正常
- 防止已过期的连接请求突然又传到服务器,因此产生错误和资源浪费
- 告知对方自己的初始序列号,同时确认收到对方的初始序列号
为什么要三次握手,不是四次?
因为经历了三次握手之后双方已经可以确认彼此的收发能力都正常,而且也完成了对双方初始序列号的确认,因此就不需要第四次握手了
如果在第三次握手中ACK包丢失会发生什么?
- 服务端:此时服务端的状态是SYN_RECV,根据TCP的超时重传机制,会等3秒、6秒、12秒后重新发送SYN+ACK包,以便客户端重新发送ACK包;如果重发一定时间后仍然没有应答,则服务端将自动关闭这个连接
- 客户端:客户端认为连接已建立,如果向服务端发送数据,服务端将以RST包(Reset,复位标志,用于异常的关闭连接)进行响应,此时客户端将知道第三次握手失败
TCP四次挥手
四次挥手的目的
四次挥手的目的是断开TCP连接,即客户端和服务端总共要收发4个包才能确定断开连接。
四次挥手的具体过程
-
第一次挥手:客户端向服务器发送关闭连接请求 客户端向服务端发送连接释放报文(FIN=1),序列号seq=u(客户端上次发送报文的最后一个字节的序号+1)。此时客户端已经主动关闭连接,停止发送数据,进入FIN_WAIT_1(终止等待1)状态,等待服务端的确认 -
第二次挥手:服务器收到请求后,回复一个确认收到的消息 服务端接收到连接释放报文后,立即发出确认报文(ACK=1),确认号ack=u+1,序列号seq=v(服务端上次发送报文的最后一个字节的序号+1)。服务端进入CLOSE_WAIT(关闭等待)状态,客户端进入FIN_WAIT_2(终止等待2)状态 注意,此时TCP连接处于半关闭状态,即客户端到服务端的连接已经被释放了,但是服务端到客户端的还没有。这表示客户端已经没有数据发送了,但是服务端可能还要给客户端发送消息 -
第三次挥手:客户端确定不再给客户端发送消息后,发送关闭连接请求 服务端向客户端发送连接释放报文(FIN=1,ACK=1),序列号seq=w(服务端上次发送报文的最后一个字节的序号+1),确认号ack=u+1(与第二次挥手时相同,因为这期间客户端没有发送数据)。此时服务端已经主动关闭连接,停止发送数据,进入LAST_ACK(最后确认)状态,等待客户端的确认 -
第四次挥手:客户端收到请求后,回复确认收到的消息 客户端接收到连接释放报文后,立即发出确认报文(ACK=1),确认号ack=w+1,序列号seq=u+1(在第一次挥手基础上递增1)。服务端收到确认消息后进入CLOSED状态,客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态
为什么建立连接是三次握手,关闭的时候却是四次(CLOSE_WAIT状态的意义是什么)?
服务器的确认报文ACK和请求释放报文FIN一般都是分开发送的,从而导致多了一次挥手
在服务端收到客户端的连接释放请求时,可能还有一些数据没有发完,不能马上关闭连接。因此要先回复ACK,表示收到了客户端的请求(第二次挥手),等到数据发送完成之后再像客户端发送FIN报文,表示数据发送已完成,请求关闭连接(第三次挥手)
为什么客户端必须等待2MSL,而不是直接进入CLOSED状态(TIME_WAIT状态的意义是什么)?
-
确保ACK报文能够到达服务端,从而使服务端能够正常关闭连接 第四次挥手时,客户端发送的ACK报文有可能再传输途中由于丢失等原因,服务端并没有收到,此时服务端会超时重传FIN/ACK报文,此时如果客户端已经断开了连接,那么就无法响应服务端的二次请求,服务端迟迟收不到确认,也就不能正常关闭连接 MSL(Maximum Segment Lifetime)是指任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。客户端等待2MSL的时间,即“客户端ACK超时1MSL + 服务端FIN传输 1MSL”,即能够收到服务端重传的FIN报文,然后客户端再返回ACK报文,重新启动2MSL计时器,如此便能保证服务端正常关闭 如果服务端重发的FIN没有成功在2MSL时间里传给客户端,服务端将会继续超时重传直到断开连接 -
让本链接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文
TIME_WAIT是服务器的状态还是客户端的状态?
TIME_WAIT是主动断开连接的一方会进入的状态,而一般情况下都是客户端主动关闭连接
如果已经建立了连接,但客户端出现了故障怎么办?
或者说“如果在三次握手、四次挥手”阶段的包丢失了怎么办?例如“服务端重发FIN丢失”的问题
TCP会通过“定时器+超时重传”机制,尝试获取确认,直到最后会自动断开连接
具体而言,TCP设有一个保活计时器,用来防止在TCP连接出现长时期的空闲。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,如果服务器过了2小时还没有收到客户的信息,它就每相隔75秒发送一个探测报文段,若发送了10个探测报文段还没有响应,就认定客户出了故障,终止该连接。
TCP可靠传输
TCP协议如何保证可靠传输
TCP提供了数据包检验、应答机制、排序与去重、超时重传、流量控制、拥塞控制等方法实现了可靠性传输
-
数据包校验:通过检验和的方式,接收端可以检测出数据是否有差错和异常,如果有差错就会立即丢弃数据段,进行重传。 -
应答机制:接收方每次收到数据后,都会对发送方进行确认应答,也就是发送ACK报文,报文中包含对应的确认序列号来告诉发送方接收到了哪些数据。 -
排序与去重:序列号不仅起到应答的作用,嗨可以根据序列号将失序数据包重新进行排序,并且丢弃重复序列号的数据。 -
停止等待:每发完一个分组后必须等待对方确认,在收到确认后再发下一个分组。 -
超时重传:当发出数据包到接收到确认包之间的时间超出限制时,则认为产生了丢包并进行重传,这个最大超时时间是动态计算的。 -
流量控制:TCP连接的每一方都有固定大小的缓冲空间,接收端通过告知发送端自己接收缓冲区的大小,来控制发送端发送的数据量,TCP使用的流量控制协议是可变大小的滑动窗口协议。 如果发送端一直在向接收端发送数据,而不考虑接收端的接受能力,则可能会导致接受端的缓冲区满了而无法再接收数据,从而导致大量的数据丢包。而在超时重传的过程中,如果接收端的情况仍未好转,则会浪费大量的时间在重传上,因此有必要引入流量控制。 -
拥塞控制: 当网络拥堵时,TCP会减少数据的发送。
ARQ协议
**ARQ(Automatic Repeat-reQuest)自动重传请求协议是OSI模型中数据链路层和传输层的错误纠正协议之一,它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的数据传输。**ARQ包括停止等待ARQ协议和连续ARQ协议。
-
停止等待ARQ协议 基本原理就是每发完一个分组就停止发送并等待对方确认(回复ACK)。如果超过一段时间(超时时间后)还是没有收到确认报文,就说明没有发送成功,需要重新发送,以保证对方可以收到完整的消息 优点是简单,缺点是通信信道的利用率很低,传输时延大 停止等待ARQ协议也可以看做是一比特滑动窗口协议,发送窗口与接收窗口都等于 1 -
连续ARQ协议 结合了滑动窗口协议,在发送方维持着一个一定大小的发送窗口,位于窗口内的所有分组都可连续发送出去而不需要等待对方的确认。而发送方每收到一个确认就把发送窗口向前滑动一个分组的位置。 例:窗口大小为4,发送时第1、2、4号分组均成功发送,3号分组发送失败,接收端会给发送端发送2号分组的确认回执,然后发送端会把2号分组之后的数据(3号分组和4号分组)重新再发送一遍,即使4号分组是发送成功的。
TCP的滑动窗口
在进行数据传输时,需要将较大的数据拆分成多个数据包进行发送,而TCP需要对数据包进行确认应答后才能继续发送下一个包,这就导致在等待确认包环节浪费大量的时间。因此TCP引入了滑动窗口机制,窗口大小即是指不需要等待确认包就能够进行发送的数据包的最大值。
当前滑动窗口的大小决定了TCP发送包的速率,而窗口大小取决于拥塞控制窗口与流量控制窗口中的最小值
TCP的流量控制
流量控制是指通过限制发送端发送数据的速率,来保证接收端接收报文的成功率,避免大量触发超时重传机制导致网络流量的浪费
具体做法是:接收端告知发送端自己接收缓冲区的大小,于是发送端将不会发送超过这个大小的数据包。这一大小在TCP首部有一个专门的字段表示,值越大意味着让网络的吞吐量越高
TCP的拥塞控制
拥塞控制是指发送方维持一个拥塞窗口cwnd(congestion window),来防止过多的数据注入网络,造成网络中的路由器或者链路拥堵,窗口的大小取决于网络的拥塞程度,是动态变化的
- 慢开始:最开始发送方的cwnd大小为1,每经过一个往返时间就将cwnd大小加倍
- 拥塞避免:当cwnd大小超过慢开始门限时,每经过一个往返时间将大小增加1而不再是加倍;在慢开始和拥塞避免的过程中,一旦发现网络拥塞就把慢开始门限设置为当前值的一半,并将cwnd重新设置为1
- 快重传:接收方只要收到一个失序报文就立即发出重复确认,发送方只要收到三个确认重复就立即重传,而不必等待重传计时器到期
- 快恢复:主要是配合快重传,当发送方收到三个重复确认后就将慢开始门限减半,并将当前窗口大小设置为慢开始门限,而不是从1开始(当采用快开始时,慢开始只在建立连接时使用)
TCP粘包
什么是TCP粘包?
TCP粘包是指发送方发送的若干包数据到接收方接收时,后一包数据的头紧接着前一包数据尾的情况
粘包是如何产生的?
- 发送方:要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次性发送出去,产生沾包
- 接收方:接收端的应用层没有及时读取缓冲区中的数据,产生沾包
为什么只有TCP会出现沾包,UDP没有?
- TCP 是基于字节流的,虽然应用层和 TCP 传输层之间的数据交互是大小不等的数据块,但是 TCP 把这些数据块仅仅看成一连串无结构的字节流,没有边界;而UDP有消息保护边界
- 在 TCP 的首部没有表示数据长度的字段
如何避免粘包?
对应于TCP产生沾包的两个原因,可以通过以下两个措施避免沾包:
- 在每个包的末尾添加特殊字符以区分连续的两个包
- 在报文首部添加包的长度
HTTP相关
client-server模型
端系统间的通信方式有两大类:客户-服务器方式(client-server)和对等方式(P2P),互联网中最常用的是client-server模式
client和server是运行在主机上的进程,一般client运行的主机称为客户机,server运行的主机称为服务器。client端在构造好http请求后,经过域名-IP地址解析,将请求发送到对应的服务端,服务端处理完请求后,把处理结果返回给client端。
什么是HTTP协议
HTTP协议就是在客户端与服务端之间传输文字、图片、视频、音频等“超文本”数据的约定与规范
HTTP无状态协议
什么是HTTP协议无状态协议?
HTTP协议是一种无状态协议,协议本身不会请求与响应之间的通信状态进行保存,即对事务的处理没有记忆能力
怎么解决HTTP协议无状态协议?
- Cookies
- 通过Session会话保存
什么是Cookies
Cookie是服务器发送到浏览器并保存在本地的一小块文件(key-value格式),其中包含了用户信息,当浏览器下次向同一浏览器发出请求时将被携带发送到服务器上,服务器可以通过cookie中的数据来区分不同的用户
Cookie使无状态的HTTP协议记录稳定的状态信息成为了可能
主要应用:
- 会话状态管理(如用户状态登录、购物车、游戏分数等需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
什么是Session
Session是另一种记录客户状态的机制,当客户端浏览器访问服务器时,服务器将使用Session对象来存储客户端信息,Session中的变量将在整个会话中一直存在下去。
Cookie和Session的区别
- 存储位置:Cookie保存在客户端(浏览器);Session保存在服务器端
- 安全:Cookie安全性较差;Session安全性相对较高
- 大小限制:单个Cookie保存的数据不能超过4K;Session无限制
- 服务器资源消耗:Session保存在服务器上一段时间才会消失,当访问增多时对服务器性能有影响
- 实现机制:Session的实现依赖于Cookie传回SessionID
HTTP请求报文与响应报文的格式
HTTP报文实际上就是客户端与服务器通信时根据HTTP协议,将传输的信息以文本的形式呈现
http报文分为请求报文和消息报文,这两类报文有着相同的结构组成
-
请求行 / 状态行 请求行:包括请求方法、URI、HTTP版本协议版本,反映这次请求要对什么资源进行什么操作 状态行:包括HTTP协议版本、状态码、状态码原因短语,呈现服务端对这次请求的额处理结果 -
请求首部 / 响应首部 首部字段相当于HTTP报文的元数据,记录了本次请求的具体描述信息,比如时间、服务端域名等 -
空行 用来区分首部字段和报文主体 -
报文主体 报文主体并不是每个报文都有的,要看具体的报文是要做什么
HTTP常见状态码
| 类别 | 原因 |
---|
1xx | 信息性状态码(Informational) | 请求正在处理 | 2xx | 成功状态码(Success) | 请求正常处理完毕 | 3xx | 重定向状态码(Redirection) | 需要额外操作完成请求 | 4xx | 客户端错误状态码(Client Error) | 服务器无法处理请求 | 5xx | 服务器错误状态码(Server Error) | 服务器处理请求出错 |
- 200:请求被正常处理
- 301:永久重定向(旧资源地址已被永久移除)
- 302:临时重定向(旧资源仍可访问)
- 400:请求报文文法错误,服务器无法解析
- 403:请求资源被禁止访问
- 404:服务器无法找到请求资源
- 500:服务器内部错误
- 503:服务器正忙
常用的HTTP方法有哪些
- GET:请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器
- POST:用于传输信息给服务器
- PUT:上传文件,报文主体中包含文件内容,保存到指定URI位置
- DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件
- HEAD:获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效
- OPTIONS:查询指定URI支持的HTTP方法
可以将理解为客户端对服务端的“增删查改”
GET与POST请求的区别
GET与POST请求的本质区别在于GET请求是幂等的,即多次执行相同的操作,返回的结果都相同
- 功能:GET请求用来从服务器获取资源;POST用来更新资源
- 安全性:GET请求是不安全的,因为GET请求提交的数据会明文显示在URL上,可能会泄露隐私信息;POST请求参数会包装在请求体里,相对安全
- 数据量:GET传输的数据量小,因为受URL长度限制,但是效率较高;POST可以传输大量数据,所以上传文件时只能用POST方式
HTTP版本对比
HTTP1.0版本特性
HTTP1.0是一种无状态、无连接的应用层协议(短连接)
无状态是指服务器不会跟踪每个客户端也不会记录过去的请求
无连接是指协议规定浏览器的每次请求都要与服务器建立一个TCP连接,服务器处理完成立即断开连接
HTTP1.1版本特性
HTTP1.1支持长连接和消息的流水线处理,允许在一次TCP连接上传送多个HTTP请求与响应,减少了建立连接与断开连接的消耗与延迟
HTTP2.0版本特性
- 二进制分帧:采用二进制编码的形式进行封装
- 首部压缩:设置首部压缩算法HPACK减少重复报文的发送
- 多路复用:允许在共享TCP连接的基础上发送请求与响应
- 服务端推送:除了对客户端发出请求作出响应外,服务器还可以向客户端推送额外的资源,而不需要明确的请求
HTTP与HTTPS的区别
https = http + 加密 + 认证 + 完整性保护
- HTTP的端口号是80;HTTPS的端口号是443
- HTTP信息是明文传输,安全性较差;HTTPS有加密机制,安全性较高
- HTTP资源消耗少;HTTPS由于加密处理,资源消耗多
- HTTP无需证书;HTTPS需要向CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的
- HTTP运行在TCP协议之上;HTTPS运行在SSL协议上,SSL又运行在TCP协议之上
HTTPS的优缺点
优点:
- 安全性:HTTPS具有认证、加密、完整性保护机制,大大增加了中间人攻击的成本
- SEO方面:根据谷歌搜索引擎算法,采用HTTPS的网站在搜索结果中的排名更高
缺点:
- HTTPS需要的响应时间和耗电量都比HTTP要高
- HTTPS的安全范围是有限的,在黑客攻击、服务器劫持等情况下几乎不起作用
- 现有的证书机制下,中间人攻击仍有可能发生
- HTTPS需要更多的服务器资源,成本更高
HTTPS工作原理
- 客户端请求HTTPS网址,连接到服务器的443端口
- 使用HTTPS协议的服务器必须具有数字CA证书,在颁发证书的同时会生成一个公钥和一个私钥。其中私钥保存在服务器中,不可泄漏,公钥则是附带在证书信息中,证书本身也附带一个电子签名,用来验证证书的完整性和真实性
- 服务器响应请求,将包含公钥和大量其他信息的证书内容传递给客户端
- 客户端解析证书内容,验证其合法性,如果出现异常将会向访问者发出警告,由其选择是否还要继续通信。如果没有问题的话就取出公钥,同时生成一个随机码KEY,用公钥对其加密
- 客户端将加密后的KEY发送给服务器
- 服务器使用私钥进行解密获得KEY,至此客户端和服务器建立了安全连接,可以使用对称加密进行通信了
- 服务器使用密钥KEY加密数据并发送给客户端,客户端使用相同的密钥解密数据
总体流程:证书验证 -> 非对称加密 -> 对称加密
输入网址到获取页面的过程
-
域名解析 浏览器先搜索自己的DNS缓存(维护一张域名与IP地址的映射表) -> 搜索操作系统的DNS缓存 -> 搜索操作系统的hosts文件 -> 查询本地DNS服务器 -
浏览器以一个随机端口向服务器的80端口发起请求,建立TCP连接 -
TCP连接建立后发起HTTP请求 -
服务器响应HTTP请求,客户端得到html代码 -
浏览器解析html代码,请求html中的资源 -
浏览器渲染页面,呈现给用户
|