计算机网络-基础
OSI 七层网络模型
基础印象
七层网络模型以两端为应用层,中间为物理层,相当于是关于物理层对称的!
数据输出到网络需要走 应用->表示->会话->传输->网络->链路->物理
数据从网络到应用需要物理->链路->网络->传输->会话->表示->应用
第七层 应用层
这一层可以说是格式层了,要完成的任务就是在应用程序之间规定消息的格式,应用程序读取消息
例如:
- 规定一个固定长度的消息头,消息头必须满足某种格式
- 消息头中记录消息体的长度等信息(TCP没有制定消息边界)
应用层旨在方便应用从网络中接收数据
应用层的协议有:
HTTP之类的,定义了消息的格式
第六层 表示层
负责将语言进行转换,例如linux发送的数据一定是linux格式的,windows就不能理解,所以表示层要解决不同系统之间的通信语法问题,在表示层数据按照网络能理解的方案进行格式化,格式化因为所使用的网络而有所不同
所以数据需要经过表示层才能变成当前应用程序能够理解的数据
常见的协议有
- ASCII
- SSL/TLS
第五层 会话层
主要的工作是
建立连接和断开连接
常见的协议有
- ADSP
- RPC
第四层 传输层
主要解决两个主机之间如何传输的问题,大量的数据如何保证不丢包,快速传输,
不同的协议有不同解决方式,tcp协议多次确认来保证,而UDP一次性发送不能保证
常见的协议有
- TCP
- UDP
第三层 网络层
将网络地址转换为具体的物理地址,然后决定如何从发送方路由到接收方.
网络层通过综合考虑发送优先权、网络拥塞程度、服务质量以及可选路由的花费来决定从一个网络中节点A到另一个网络中节点B的最佳路径。
这个层次的协议有
- IP协议
- ICMP协议
网络层主要负责寻址和路由选择
网络层将数据从发送端的主机发送到接收端的主机,两台主机间可能会存在很多数据链路,但网络层就是负责找出一条相对顺畅的通路将数据传递过去。传输的地址使用的是IP地址。IP地址通过不断转发到更近的IP地址,最终可以到达目标地址
第二层 数据链路层
主责两个物理地址主机之间的数据传递,这两个主机通过网络直接连在一起
所以这一层是最基础的,保证如何格式化数据进行传输
数据链路层就是产生bit流的过程,但是产生bit流有一些问题
- 错传
- 数据不完整
这些问题,数据链路层要解决
一般提供错误检测,纠正,保证数据传输准确定
常见的协议有
- HDLC
- PPP
- SLIP
数据链路层会将0,1序列划分成具有意义的数据帧发送给对端.
数据帧包含了一些固定的字段(如目的地址、源地址、控制信息等)以及数据部分,用于在网络中传输和交换数据。每个数据帧都有自己的起始和结束标识,以及错误检测和纠正的机制,以确保数据的可靠传输。
第一层 物理层
网卡工作在这一层,将bit流转换成电流强弱传输,到达目的端在转换为bit流,即常说的数模转化和模数转换。
物理层主要定义了物理设备的标准,如网线的类型,光纤的接口类型,各种传输介质的传输速率。
物理层解决了,信息如何到达对端的问题
总结
四层传输层数据被称作段(Segments);
三层网络层数据被称做包(Packages);
二层数据链路层时数据被称为帧(Frames);
一层物理层时数据被称为比特流(Bits)。
TCP和IP模型
tcp/ip模型相比于osi模型更为注重具体应用
这个模型只划分了五层
- 应用层
- 传输层
- 网络层
- 数据链路层
- 物理层
没错就是少了表示层和会话层
网络设备
交换机
每个主机的网卡有自己的物理地址,叫做MAC作为设备的唯一标识,电脑发送设备的时候数据头部会包含网卡的MAC地址
交换机通过识别不同的MAC地址来区分不同的电脑,那些数据来自那些电脑
交换机还要找到,对应电脑在连接在交换机的哪一个端口上,找到对应的端口才能发送数据到指定的电脑上
所以交换机维护了一张Port-MAC表,通过MAC地址找到端口是哪一个
交换机有一个自学习机制,某个端口收到数据之后,就检查这个端口来的MAC是不是在表中,不在就自动更新
这个就叫做自学机制
路由器
路由器是交换机的升级,交换机的目的是花更少的端口和线,将更多的终端连接起来
但是交换机不能维护过多的设备,内部的转发表过大,交换机也难以容纳,以及难以管理
所以我们设计一个结构,让交换机能够连接交换机,并且能从其他交换机哪里获取想要的MAC地址
缺少的是什么呢?我们需要路由功能,就是找到一条路径能够到达目标MAC地址
这个就是路由器,带路由功能的交换机!
我们一般使用三级路由就可以找到我们要找到的MAC
局域网中的设备可以使用交换机连接
不同区域的局域网可以互连就需要使用路由器
路由器有多个端口,每个端口连接不同的网络区域,不同的网络区域的IP地址的网络号不同
路由器通过识别目的IP的地址的网络号,在根据路由表进行数据转发
如果路由表中没有特定IP地址的网络号信息,路由器会按照以下步骤处理数据包:
- 默认路由:路由器会查看是否有配置默认路由(也称为“网关的网关”)。默认路由是一条特殊的路由规则,用于处理路由表中没有明确条目的目的地地址。如果存在默认路由,路由器会将数据包转发到配置的默认路由指向的下一跳地址。
- 路由聚合:在某些情况下,路由器的路由表可能通过路由聚合(也称为路由总结)简化了路由信息。如果数据包的目标地址与某个已聚合路由的范围匹配,即使没有精确匹配的网络号,路由器也会根据这个聚合路由转发数据包。
- 丢弃数据包:如果路由表中没有匹配的条目,也没有配置默认路由,或者其他特殊规则(如路由聚合)无法应用,路由器将无法确定数据包的转发路径。在这种情况下,路由器会丢弃数据包,并可能向发送方发送一个ICMP目的地不可达消息,表明数据包无法被送达。
- 手动或动态路由更新:在实践中,为了避免数据包因缺少路由信息而被丢弃,网络管理员可能会手动添加缺失的路由信息到路由表中,或者通过动态路由协议自动更新路由表,以确保网络的连通性和数据包的正确转发。
HTTP协议
基础知识
HTTP协议是应用层协议,属于tcp/ip协议为基础的协议
HTTP协议有不同的版本
在1.0版本中定义了get post head三种请求方法
1.1版本中新增了六种
- options
- put
- patch
- delete
- trace
- connect
序 号 | 方法 | 描述 |
---|---|---|
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。(就是长连接支持) |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
get请求和post请求的区别
- GET 请求的请求参数是添加到 head 中,可以在 url 中可以看到;POST 请求的请求参数是添加到body中,在url 中不可见。
- 请求的url有长度限制,这个限制由浏览器和 web 服务器决定和设置的,例如IE浏览器对 URL的最大限制为2083个字符,如果超过这个数字,提交按钮没有任何反应,因为GET请求的参数是添加到URL中,所以GET请求的URL的长度限制需要将请求参数长度也考虑进去。而POST请求不用考虑请求参数的长度。
- GET请求产生一个数据包; POST请求产生2个数据包,在火狐浏览器中,产生一个数据包,这个区别点在于浏览器的请求机制,先发送请求头,再发送请求体,因为GET没有请求体,所以就发送一个数据包,而POST包含请求体,所以发送两次数据包,但是由于火狐机制不同,所以发送一个数据包。
- GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
- GET是幂等的,而POST不是(幂等表示执行相同的操作,结果也是相同的)
- GET是获取数据,POST是修改数据
状态码
1xx 接受
表示请求已经接收,正在处理
2xx 成功
成功处理,一切正常
200 返回是最常见的,如果是非head请求,服务器会返回body
204 No content,也是常见的成功状态码,只是没有响应体
206 partial content 标表示返回的body数据不是资源的全部,而是一部分
3xx 重定向
表示客户端请求的资源发生了变动,需要客户端用新的url重新发送请求资源,也就是重定向
301 永久重定向,说明资源已经不在了,需要改用新的url访问
302 临时重定向 说明请求的资源还在,但是暂时需要使用另一个url来访问
301 和 302 都会在响应报文中的location字段中指明后续需要跳转的url,浏览器会自动重定向
304 不具备跳转含义,表示资源未修改,重定向 已存在的缓存文件,也称为缓存重定向,用于缓存控制
4xx 做不到
表示客户端发送的报文有误,服务器无法处理,也就是错误码 的意思
400 表示客户端的报文有问题
401 缺失或者错误的认证 这个状态码必须和WWW-Authenticate报头域一起使用。
403 表示服务器禁止访问资源,并不是客户端出错
404 表示请求访问的资源不在服务器上或者不存在找不到,所以无法提供给用户
5xx 错误
表示客户端的报文正常,但是服务器内部出现问题,这个是属于服务器的错误码,早好不要给客户端看到
501 表示客户端请求的功能还不支持
502 服务器自身正常,但是访问服务器的后端服务发生错误
503 表示当前服务器很忙,暂时无法响应
504 网关超时由作为代理服务器的使用这个状态吗,表示不能及时的从远程服务器获得应答
HTTP1.1 更新
这个版本的还支持一个功能,长连接
之前学过websocket就知道,http是无连接的
http1.0 浏览器的每次请求都是一个连接,服务器完成相应之后就会关闭连接,服务器不会记录客户
http1.1 支持持久保持一个链接,并默认使用,这样同一个tcp连接可以传送多个HTTp请求和响应
HTTP的持久连接也需要添加新的响应头支持,
- connection请求头的值
- 如果是keep-alive就会保持连接
- 如果是close就会在本次链接相应之后关闭连接
管道网络传输
什么是管道网络传输?
与管道网络传输相对的就是应答式网络传输,我们发送请求之后需要等待收到响应才能发送下一条请求
而管道网络传输就是不需要等待,可以并行传输,一遍发送请求一遍等待响应
想要实现管道网络传输,需要满足的条件是长连接,也就是多次请求共用一条连接,否则如果请求之间需要建立各自的链接的话,在同一时间内两台主机只能建立一条连接,这样就没法实现管道传输了
HTTP1.1提供的长连接正好可以实现管道网络传输
但是需要注意的是
服务器还是会按照顺序,先响应先到的请求,在未处理完毕之前不会响应其他的请求,所以如果前面的请求特别满,后面的请求也只能等着
HOST字段
在HTTP1.0中认为服务器都有一个唯一的ip地址,因此请求的url中没有包含主机名
但是随着虚拟技术的发展,一台物理主机上可以存在多态虚拟主机,并且他们共享一个ip地址,所以会出错的,服务器并不能分辨到底要交由哪一个主机处理请求
HTTP1.1新加了一个字段,host,这个字段是强制性的,如果没有填写这个字段会报错400
我们应该设置服务器接受绝对路径url请求,这样的话可以为客户端和服务器之间的通信提供更直接、更清晰的交互方式,从而提升系统的效率和可靠性.
100状态码
HTTP1.1新加入了一个状态码100
主要用来试探服务器,例如先发送一个HEAD请求,如果服务器不允许就会回复401权限不足,如果服务器允许就会发送100,表示可以发送带实体的完整请求
Chunked Transfer Coding
可以将数据消息content分成不同的数据块,单独发送,直到最后发送一个长度为0的数据块结尾
这样对于不确定响应到底有多大的请求,服务器就可以分批次响应部分,避免响应过大导致缓存爆炸的情况.
这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。
Cache
HTTP/1.1在之前的基础上加上了一些新的cache特性
当一个缓存对象的年龄age超过设置的过期时间expire的时候这个对象会变成stale对象,cache不需要直接删除stale对象而是重新激活
HTTP2.0 更新
新的二进制格式
之前的HTTP协议都是基于文本解析,也就是传输的都是字符编码
HTTP/2.0传输的是二进制格式,相比于字符编码更加精简
多路复用
即连接共享,我们记得之前的HTTP/1.1中使用到的长连接,允许的一个tcp连接进行多次请求,但是这些请求都是串行传输的,如果前面的请求没有处理完毕,那么后面的请求就只能等待,而这个机制就是为了解决这个问题的
每一个请求都有一个请求id,这样同一个连接上可以有多个请求,这些请求可以随机的混合在一起,接收方可以根据请求id来区分
然后再将这些请求部分根据id规分到不同的服务端请求里面
这样就不会出现队头阻塞
header压缩
之前的协议,每次请求都需要发送的请求头中包含了大量重复的信息
HTTP/2.0使用encoder来减少需要传输的header大小
双方各自缓存一份header fileds表,如果我们需要改动哪一个字段就发送过去就行了
服务端推送
一定程度上改善了传统的服务器被动响应的模式
也可以主动地向客户端发送消息
举个例子来说就是浏览器在请求HTML页面的时候,服务器就料到客户端马上要请求这个html页面中用到的静态资源,服务器直接主动发送过去
这样就可以减少延时等待
但是服务器推送是有限的,主要用于推送一些静态资源,滥用服务器推送会导致性能的下降
数据流
因为多路复用的关系,在一个tcp连接中,连续的数据包可能来自不同的响应
所以必须要对响应的包做出标记,指出它属于哪一个响应
每个请求或回应的所有数据包,称之为数据流(stream)
每个数据流都有自己独一无二的编号,规定客户端的发出的数据流编号为奇数1开始所以是奇数为客户端
服务器发出的响应数据流编号为偶数
客户端还可以指定数据流的优先级,优先级高的请求服务器就会先响应
HTTP3.0 更新
使用了UDP(具体是QUIC)
http2.0的问题是多路复用情况下,如果发生丢包问题,会触发tcp的重传机制,整个连接上的请求都要等待这个包被重传
这个问题是出在tcp协议上,所以HTTP3.0直接把底层传输协议改成了UDP!
HTTP/3.0使用了UDP协议(具体是基于QUIC协议),而不是传统的TCP协议,主要出于以下几个原因:
- 降低延迟:UDP相比TCP具有更低的连接建立和断开时延,以及更小的首部开销,使得HTTP/3.0可以实现更快的数据传输速度。此外,QUIC协议还支持0-RTT连接建立,进一步降低了通信时延。
- 抗拥塞控制:QUIC协议内置了拥塞控制机制,可以更好地适应网络拥塞情况,提高了网络的稳定性和可靠性。
- 多路复用:HTTP/3.0基于QUIC协议实现了多路复用功能,允许在同一个连接上并发进行多个请求和响应,避免了队头阻塞问题,提高了网络利用率。
- 安全性:QUIC协议通过TLS 1.3来进行加密通信,保障数据的安全性和隐私性。
尽管HTTP/3.0使用UDP协议带来了诸多优势,但也存在一些挑战。由于UDP是无连接的、不可靠的协议,它可能会导致一些特定网络环境下的性能问题,比如丢包、乱序等。此外,UDP流量在某些网络设备(如防火墙、代理服务器)上可能被阻止或限制。
目前,HTTP/3.0仍处于较新的阶段,对于广泛采用的程度还较有限。然而,随着对HTTP/3.0和QUIC协议的认识逐渐增加,越来越多的服务提供商和网站开始支持HTTP/3.0,并希望借助其优势提升网站性能和用户体验。预计随着时间的推移,HTTP/3.0的应用将会逐渐增多。
QUIC(Quick UDP Internet Connections)是由Google设计开发的基于UDP协议的传输层协议,目的是加速网络通信并提高网络性能。QUIC旨在解决TCP协议的一些缺点,并结合了部分TCP和TLS的特性,以及新的设计理念,为Web应用提供更快速、更安全的数据传输机制。
以下是QUIC协议的一些主要特点和优势:
- 减少连接建立时延:QUIC支持0-RTT连接建立,可以在第一次连接时就发送数据,从而降低连接建立的时延,提高数据传输效率。
- 多路复用:QUIC支持在同一个连接上进行多个请求和响应的并发传输,避免了 TCP 的队头阻塞问题,提高了网络利用率和数据传输效率。
- 拥塞控制:QUIC内置拥塞控制机制,可以更好地适应网络拥塞情况,保障数据传输的稳定性和可靠性。
- 安全性:QUIC使用TLS 1.3进行加密通信,保障数据的安全性和隐私性,同时也具有抗中间人攻击等安全特性。
- 快速恢复:QUIC具有快速的连接恢复机制,使得在出现数据包丢失或网络变化时能够更快地恢复连接状态,减少影响用户体验的时间。
总的来说,QUIC协议结合了运输层和安全层的特性,通过优化连接建立、多路复用、拥塞控制等方面,提供了更快速、更安全的网络通信方式。QUIC已经被应用于HTTP/3.0协议中,
HTTPS
HTTP协议是明文传输,如果恶意用户拦截了HTTP数据包可以直接解析出内容,非常的不安全
HTTPS是 TLS/SSL协议 + HTTP协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全
普及一下加密
加密算法
加密算法分为对称加密和非加密
具体就是加密和还原两个过程,用到的两个钥匙,如果是一把钥匙可以加密和解密,就是对称加密,如果是加密一把钥匙,解密一把钥匙就是非堆成加密
明显非堆成加密更加安全,在非对称加密中,常常有一把公开的秘钥,和一把私有的秘钥,他们是一对
任意一方都可以用来加密,加密之后都只有另一个钥匙能解密,自己是解不开的
具体步骤
- 客户端先发送请求
- 服务器收到请求之后,将SSL(TLS证书)证书发送给客户端,这个证书里包含公钥以及其他信息
- 客户端检测证书的合法性,是否过期,域名与证书是否匹配等等
- 客户端使用得到的公钥之后,生成一段随机数据,用公钥加密之后发送给服务器,这段随机数据就是随后要用到的对称密钥
客户端使用服务器的公钥对生成对称密钥的过程意味着在HTTPS通信中,客户端和服务器之间采用了混合加密机制。具体来说,这意味着:
- 公钥加密:服务器的公钥用于加密通信中的一段随机数据(ClientKeyExchange)。这段随机数据由客户端生成,并且只有服务器的私钥能够解密。这确保了通信的机密性,因为只有服务器才能解密这段数据,从而得到用于后续通信的对称密钥。
- 对称密钥加密:一旦服务器解密了客户端发送的随机数据,双方都可以使用该随机数据生成的对称密钥来加密和解密通信中的数据。对称密钥加密速度快,适合大量数据的加密和解密,因此在建立安全连接后,客户端和服务器就会使用对称密钥来加密通信中的数据。
这种混合加密机制结合了公钥加密和对称密钥加密的优点,既确保了通信的安全性,又提高了通信效率。客户端和服务器之间的安全通信基于这种机制,使得数据在传输过程中更加安全可靠。
服务器解密数据:服务器使用自己的私钥解密客户端发送过来的数据,获取会话密钥(session key),用于后续的通信。
双方开始加密通信:客户端和服务器双方都使用会话密钥(session key)来加密和解密数据,确保传输的数据在网络上是加密的状态。
安全通信:双方开始通过加密的连接进行通信,保护数据的隐私和完整性。
数字认证
客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
这就存在些问题,如何保证公钥不被篡改和信任度?
所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。
通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。
冒充公钥可能会导致以下风险:
- 中间人攻击(Man-in-the-Middle Attack):攻击者可能会劫持通信过程中的公钥交换步骤,向客户端发送自己的伪造公钥,以替代服务器真实的公钥。这样一来,攻击者就能够解密和篡改通信内容,而客户端和服务器之间并不知情。
- 数据泄露:如果攻击者成功冒充了服务器的公钥,客户端就会误以为与真实服务器建立了安全连接。在这种情况下,攻击者可以窃取通信中的敏感信息,如用户名、密码、信用卡号等,导致用户数据泄露。
- 信息篡改:通过劫持公钥交换过程,攻击者可以篡改通信内容而不被察觉。这意味着攻击者可以修改传输的数据,包括植入恶意软件、篡改网页内容等,从而对通信双方造成损害。
- 身份伪装:攻击者利用冒充公钥的方式可以伪装成合法的服务器,欺骗用户输入敏感信息。这种情况下,用户可能会误认为他们正在与信任的服务通信,从而轻易地泄露个人信息。
因此,冒充公钥是一种严重的安全风险,可能导致用户数据泄露、信息篡改以及身份伪装等严重后果。为了防范此类攻击,通信双方应该采取适当的安全措施,如使用数字证书进行身份验证、采用安全的通信协议等。
请求报文
请求报文有三部分组成
- 请求行
- 请求头
- 请求体
请求行就是第一行,这一行是最常用的信息,所以放在第一行
请求方法
+url地址
+协议和版本
请求头包含一些请求的元数据
请求体包含主体数据
常见的请求头字段
- Accept 告诉服务器,客户端接受的响应类型
- Referer 告诉服务器请求来自哪个url
- Cache-control 缓存控制,请求希望响应内容在客户端缓存一年或者不被缓存(让服务器不要更新)
- Accept-encoding 用来告诉服务器,客户端能够接受的编码格式,包括字符编码和压缩形式,一般有gzip,deflate
- Host 指定要请求所在资源的主机和端口
- User-Agent 告诉服务器客户端的操作系统和浏览器版本
- Connection 决定响应之后是否关闭连接(keep-alive和close)
响应报文
也是三个部分组成
- 响应行
- 响应头
- 响应体
响应行
协议和版本
+状态码
+描述
常见的响应字段
- cache-control 这个字段在请求字段中也出现过,服务器将告诉客户端该如何控制响应的缓存
- Etag 这个表示的是资源的版本,如果资源发成变化,这个值就会变化,就像git一样
- Location 用于重定向,客户端收到这个字段的信息就会自动重定向到location的地址
- Set-cookie 服务器在客户端上设置cookie,就是缓存了一些键值对在客户端上,客户端在请求的时候子自动发送
TCP 协议
传输层协议,用于保证两个远程主机之间的数据通信
TCP协议提供了可靠的传输,支持全双工,是一个链接导向的协议
双工单工
双工就是可以双向工作的意思,双向通信
单工就是只能单向通信的意思
双工又分为半双工和全双工
半双工指的是同一时间只能一方发送或者接受
全双工指的是任何时间双方都可以同时发送并且接收
主要特点
- 面向连接
在双方传输数据之前,必须先建立连接,建立一条通道
实际上就是要让双方找到一条连接对方的通路,两边再确认都没问题,这就叫做建立连接了
- 只能端到端
也就是说TCP协议只能连接两个端点,不能连接多个(实际上就是套接字实现)
- 可靠传输服务
TCP协议确保所有数据不会丢失(丢失会找回),确保通信没有问题
传送的数据无差错、不丢失、不重复、按序到达;
- 提供全双工
允许通信方在任何时候都可以接收和发送
是因为服务器和客户端都设置了发送缓存和接收缓存,这样看似我们发送了,实际上还在缓存中
- 面向字节流
TCP不会计算分割的消息,或者数据包而是将数据看做成数据流,所以TCP并没有检测消息边界的方法
接收端无法知道数据是否接收完毕,而是发送收到的字节数据编码给发送端
应用层需要自己定义消息边界,就是结束符