- TCP
- UDP
- HTTP
- HTTPS
- TLS
这部分内容可以看陶辉的慕课视频,讲得非常清晰
- 面向连接的流式协议
- 可靠
- 超时重传
- 重复确认
- 拥塞避免
- 面向无连接的报文协议
- 不可靠
- 16位源端口
- 16位目的端口
- 32位序号
- 32位确认序号
- 4位TCP头部长度
- 6位标志位
- 16位滑动窗口
- 16位校验和
- 16位紧急指针
- 注意:TCP的包没有IP地址,只有源端口和目的端口。一个TCP连接需要4个元组来表示一个连接。(源端口,目的端口,源IP,目的IP)
- 主要是初始化序列号和协商最大报文段长度
-
udp不存在粘包的问题,因为udp是个数据包协议,也就是两段数据间有界限的。要么收不到,要么全收。
-
产生粘包的原因:nagle算法为了改善网络传输效率,延迟发送数据。应用层由于某些原因不能及时取出TCP的数据,导致TCP缓冲区存放了多段数据。
-
解决方式:封包和拆包。包头存放一个变量记录包体的长度。在所发送的内容前,加上发送内容的长度。
- http协议是应用层协议,通过请求响应的方式在客户端和服务器端进行通信。
- http协议是以明文的方式进行传输,并且是无状态的通信协议。
- 传输方式:http是明文传输,极易被监听和篡改。而https加入了ssl层,数据经过了加密,从而保护了传输数据的隐私和完整性。
- 身份认证: http没有身份认证,而https经过证书颁发机构的多重认证。
- 连接端口:http为80,https为443。
- 实现成本:http基本没有成本,https需要申请证书,同时在加密解密上需要消耗更多的CPU资源,访问速度有可能降低。
- 加锁的图标显示 谷歌和百度搜索的排名会对非https的排名有影响
- 私钥能解密,但是不能确认是哪个客户端发送的消息,任何人都可以抵赖。为了防止抵赖,可以使用数字签名。
- https是http的安全版,在http的基础上增加了SSL安全层。
- 基于性能的考虑,https一般使用非对称加密算法获得密钥,再用对称加密算法对消息内容进行加密。
https发送请求的过程:
- 第一步,客户端和服务器端交换SSL版本和加密组件列表,同时服务器端将密钥和签名证书发给客户端。
- 第二步:客户端根据证书和密钥进行验证,通过以后协商传输的密钥。这一步使用非对称加密算法。
- 第三步:当双方都获得密钥,且校验码没有问题。则进行TCP三次握手,此时采用对称加密算法,提高效率。
- 长连接:HTTP 1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
- 带宽优化:HTTP/1.1中在请求消息中引入了range头域,它允许只请求资源的某个部分。
- 新增响应状态码:100 continue 已经收到第一部分,正等待剩余部分。 101 switch protocols 服务器已确认切换协议。
- host头域:允许物理主机上多个虚拟主机共享一个IP
- 缓存机制更灵活,新增control-cache头域
- 增加了5个请求方法:put delete connect options trace
- 区别在于:
- 用途上:get一般用于获取资源,post一般用于创建资源。
- 位置上:get请求的的数据会在地址栏上显示出来,以问号分割url与传输数据,多个参数用取地址符连接。而post的数据放在请求体中。
- 安全性上:优于get将信息显示在地址栏,所以对于用户密码等个人隐私信息很不安全,而post放在请求体中,在安全性上要稍微好点。
- 长度限制:get使用地址栏发送数据,而地址栏的长度是有限的。
- 幂等性上:get操作没有副作用,多次操作产生的副作用相同,所以get是幂等的,而post用于创建资源是会又副作用的,所以post不是幂等的。
- cookie和session都是跟踪会话的机制。
- 存储位置:cookie保存在客户端用来记录信息和确定用户身份,session保存在服务端同样用来记录和确定身份。
- 安全性:cookie放在客户端很容易被查看或者破解,没有session安全。
- 关联性:session的运行依赖于session id 而session id 存在cookie中。如果浏览器禁止了cookie,可以使- 用url地址重写来传递session id
- 性能上:session会在有效期内存在于服务器的数据库或者文件,当请求过多时,服务器性能会下降。
- 大小上:单个cookie保存的大小不能超过4k
使用cookie来管理session以弥补http中无状态特性。通过对set-cookie头域写入session ID可以免登录,提高访问的效率。
握手优化:session缓存, session key 放在内存,有内存消耗, 负载均衡后找不session key。session ticket 集群可以共享。
- TCP: 面向连接的安全的流式协议,连接的时候进行三次握手,数据发送的时候会进行数据确认,数据丢失之后,会进行数据重传。 确认和重传机制。
- UDP: 面向无连接的不安全的报文传输,发出去就不管了,收则全收,丢则全丢。
-
TCP三次握手:客户端向服务器端:发送SYN=1和序号seq
-
服务器端向客户端:回应确定信号同意连接ACK=1以及自己的连接请求SYN=1还有序号seq
-
客户端回应服务器端:ACK=1告诉对方它已经知道了服务器端同意,连接成功。
-
TCP四次挥手:主动关闭方发送关闭信号,被动关闭方收到信号。然后进入半关闭状态,关闭的一方能接收数据但是不能发送数据。 等到另一个未关闭的一方,发起关闭信号以后,进入TIME_WAIT状态,等待对方2MSL之后,彻底关闭。
- 客户端发起连接,也就是C语言中的connect函数,发送一个SYN=1的标志位,同时携带一个序号。
- 服务器端有一个accept函数,用于响应连接。服务器端响应连接后回复一个ACK=1的标志位,并且也发送一个SYN=1的标志位建立连接。
- 客户端收到服务器端的ACK应答以后,说明建立成功。两者都同时进入established状态。同时accept和connect函数调用成功,并返回1。
- 主动关闭方向被动关闭放发送FIN标志位,表示要断开连接。被动关闭方同意关闭,并回发ACK标志位。此时主动关闭放进入FIN_WAIT_2状态。以后主动关闭方仍然可以接收数据,但是不可以再发送数据。
- 当另一方也决定关闭时,会发送FIN标志位,接收方回复ACK同意关闭,并且自身进入Time_wait状态,等待2MSL时长后关闭。发送方如果收到ACK应答后,就直接关闭,如果没有收到会一直发FIN标志位。
- 流量控制:防止发送方发的太快,耗尽接收方的资源。
- 控制机制:滑动窗口
- 在TCP报文的头部有一个16位的窗口大小,用于告诉发送方接收方可用的缓冲区大小。
- 拥塞控制:防止发送方发的太快,使网络来不及处理,从而导致网络拥塞
- 控制机制:拥塞窗口
- 慢启动:为了防止大量数据瞬间注入网络,引起网络阻塞。慢启动算法设定,最开始窗口为1个最大报文长度。一个传输轮次增加一倍的窗口大小。当达到慢开始门限后,执行拥塞避免算法。
- 拥塞避免: 每个传输轮次将窗口增加一个单位,即加法增长。
- 快重传: 当收到3个重复确认以后,执行快恢复算法。慢开始门限和发送窗口减半,然后发缺失的数据,进行加法增长,重新进入拥塞避免阶段。
- 快恢复:慢开始门限减半,发送拥塞窗口设定为门限加3。如果后面依旧收到重复的ACK则进行加法增长窗口,如果收到新的ACK,则拥塞窗口设定为慢开始门限的值,并重新进入拥塞避免阶段。
超时进入的是慢启动,重复确认才进入快恢复。
选择性重传在options中left edge和right edge告诉发送方已经收到的报文序号
udp不会出现粘包。发送方发送的若干包数据到接收方接收时,包粘在了一起。
造成粘包的原因时因为发送端延迟发送或者接收方没有及时接收缓冲区中的数据。
- 通常可以使用以下三种方式来解决
- 编程时设定立即发送的操作指令
- 把数据长度与消息一起发送。
- 使用特殊标记来区分消息的间隔
HTTP协议是一种使用明文数据传输的网络协议。HTTPS协议可以理解为HTTP协议的升级,就是在HTTP的基础上增加了数据加密。在数据进行传输之前,对数据进行加密,然后再发送到服务器。这样,就算数据被第三者所截获,但是由于数据是加密的,所以你的个人信息让然是安全的。这就是HTTP和HTTPS的最大区别。
- 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;(递归式和迭代式)
- 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接;
- 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
- 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
- 释放 TCP连接;
- 浏览器将该 html 文本并显示内容;
- 想要做到可靠,必须要做到无重复,无丢失,无错误,无失序。借鉴TCP的可靠机制
- 发送时进行编号
- 接收方收到数据发出应答信号(超时重传,3次确认重传)
- 增加校验位
- NAT用于实现从内部IP地址到外部IP地址的映射
- DNS提供域名到IP地址的映射或者反过来
- ARP提供IP到MAC地址的映射
基于UDP的协议
- 递归查询:父域名代替当前服务器递归查询,最后依次返回
- 迭代查询:父域名服务器告诉当前服务器下一次查询的位置
- 100 continue 等待继续发送
- 200 ok 请求成功
- 206 partial content 部分资源
- 301 永久重定向
- 302 临时重定向 307
- 400 客户端请求报文语法错误
- 403 禁止访问
- 404 资源不存在
- 408 请求超时
- 500 服务器内部错误
- 503 服务器不可用
- 二进制分帧
- 多路复用
- 首部压缩
- 服务器推送
- 0 RTT
- 没有队头阻塞的多路复用
- 前向纠错
- sql注入:用户提交一段数据库查询代码,根据程序返回的结果获得它想得知的数据。
- dos攻击: 让运行的服务器呈停止状态。集中请求造成资源过载,攻击安全漏洞使服务停止。
物数网传会表应 ping是从应用层直接使用网络层的ICMP协议的,不经过传输层。原始套接字直接使用网络层的IP。 两台电脑通信:网线+不同的IP地址和子网掩码,即处于同一网段。 TCP和UDP可以同时使用相同的端口。 应用程序可以同时使用TCP和UDP两个协议。
可以实现多个IP主机通信,但是hub的实现方式是广播,容易产生拥堵。
是集线器的升级版,可以广播可单播。ARP不知道对方MAC地址时,先广播6个ff的MAC地址,所有网卡都会接收,但是只有目的IP会单播回应,其他的都会丢弃。然后发送方收到正确的MAC后再单播传输数据。
给两个MAC地址响应ARP广播的目的IP,经由中间人,窃取信息后再转发到正确的地址。
在同一个交换机连接的网络中,属于同一网段,用不到默认网关。网关用来传递两个不同网段的通信,默认网关通常是路由器。当通信的数据不在当前网段时,即发给默认网关。路由器就是用来连接不同网段的,用来构建一个更大的网络。在传输不同的网段信息时,源IP和目的IP是不变的,源MAC和目的MAC是改变的,每经过一个路由器修改一次,记录的是下一次的目的,和这一次的发送MAC。
ack会随着响应数据发送给对方,如果没有响应的数据就会等待200ms左右,在这期间如果有对方确认到达则立即发送。如果200ms后仍然没有数据需要发送则单独发送ACK。目的是节省带宽。
- 没有已发送未确认报文段时,立即发送数据。
- 存在未确认报文段时,达到mss时再发。
同时有nagle算法和延迟确认存在时会导致网络效率下降,通常会关闭延迟确认和nagle算法。
setsockopt(s,IPPROTO_TCP,TCP_QUICKACK,(int*){1}, sizeof(int)); //关闭延迟确认
setsockopt(client_fd, SOL_TCP, TCP_NODELAY,(int[]){1}, sizeof(int)); //关闭nagle算法
- 客户端和服务器端连接建立后,若某一端关闭连接,而另一端仍然向它写数据,第一次写数据后会收到RST响应,第二次写数据时,内核会向进程发送一个SIGPIPE信号,通知进程此连接已断开,而这个信号的默认处理方式是终止进程,服务器直接关闭。
signal(SIGPIPE, SIG_IGN)
SIGSEGV 11 访问地址无效 SIGIO 29异步通知信号 SIGKILL 9 无条件终止
- 传输层位于网络层之上,为不同主机上的应用进程提供逻辑通信。端到端传输。
- 网络层负责IP数据报的产生以及ip数据包在网络中的路由转发。
- 在Nginx服务器端处理的时间过长,客户端主动关闭了连接。
- transfer-encoding:chunked 响应头域
- 它允许服务器发送给客户端的数据分成多个部分,并且不需要预先直到发送数据的总大小。
- 基本的思想就是要检测出对方已经关闭的socket,然后关闭它。维持一个心跳包或者设置一个超时时间。
- 301 move permanently
- 302 found POST方法的重定向在未询问用户的情况下就变成GET
- 303 see other POST重定向为GET
- 307 temporary redirect 当客户端的POST请求收到服务端307状态码响应时,需要跟用户询问是否应该在新URI上发起POST方法,也就是说,307是不会把POST转为GET的。
- 慢开始:初始窗口,每个往返事件RTT增加一倍的窗口,呈现指数增长。
- 拥塞避免:当窗口大小达到阈值以后,每个RTT增加一个窗口的大小。
- 超时后,进行阈值变为当前窗口的一半,窗口大小从1进行慢启动
- 重复确认:阈值和窗口同时变为当前窗口的一半,进行拥塞避免,称为快恢复。
- close_wait半关闭的被动关闭方
- time_wait被动关闭方,等待2MSL的时间,保证ACK可以顺序送达。使用端口复用可以消除time_wait,修改TCP的参数可以增大或减少这个时间长度。
http2.0 spdy
-
首部压缩
-
多路复用
-
服务器推送
-
http3.0 quic+udp
-
0 RTT
-
前向纠错
-
没有队头阻塞的多路复用
- 流量控制 定义和目的:如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。
实现机制:由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送
可能会引发死锁,怎么避免:当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。
流量控制与拥塞控制的区别
拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:
- 慢开始、拥塞避免
- 快重传、快恢复。
流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
拥塞控制算法
假定:1、数据是单方向传递,另一个窗口只发送确认;2、接收方的缓存足够大,因此发送方的大小的大小由网络的拥塞程度来决定。
- 慢开始算法
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。
慢开始算法的思路就是,不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小
这里用报文段的个数作为拥塞窗口的大小举例说明慢开始算法,实际的拥塞窗口大小是以字节为单位的。如下图:
从上图可以看到,一个传输轮次所经历的时间其实就是往返时间RTT,而且没经过一个传输轮次(transmission round),拥塞窗口cwnd就加倍。
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量。ssthresh的用法如下:当cwnd < ssthresh时,使用慢开始算法。
- 当cwnd>ssthresh时,改用拥塞避免算法。
- 当cwnd=ssthresh时,慢开始与拥塞避免算法任意
注意,这里的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,然后逐渐增大,这当然比按照大的cwnd一下子把许多报文段突然注入到网络中要“慢得多”。
- 拥塞避免算法
拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口按线性规律缓慢增长。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕
- 快重传算法
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期
- 快恢复算法
https是安全版的http协议。
get用来获取资源,post用来创建资源。
get将数据放在url地址栏中,使用问号与url分割,数据间用取地址符分割。post将数据放在请求体中。
安全性上get放在url容易暴露隐私信息,而post放在请求体中可以适当的避免。
get在传输的数据受url地址栏的限制,post不受这种限制
get的操作是幂等的,多次操作产生的影响相同,而post是非幂等的
- 客户端在header中的range字段中指明,请求传输的区间[l, r]
- 服务器端在header中的content-range返回当前接受的范围和文件总大小。并返回206patial content 状态码。
TLS握手协议:1.交换加解密的安全套件 2.验证通讯双方的身份 3.协商加密的参数。
https是在TCP之上增加了一层TLS层
TLS1.3版本限定了安全套件的数量,防止低版本的安全组件被暴力破解。开始时客户端发送hello并携带一个自己生成的公钥,服务器端选择一个安全套件并将自己生成的公钥发给客户端,客户端收到公钥以后,两段此时都有一个对方发来的公钥和自己的私钥。此时使用ECDH椭圆曲线非对称加密算法,生成一个相同的密钥,这个密钥就用来进行后续的对称加密。
校验过程:判断数字证书中的哈希值和公钥解码的哈希值是否一致。
长期处于半连接状态可能会造成TCP内核中SYN队列的爆满,服务器会在一定时间内终止半连接,并回收资源。如果使用syn洪泛攻击,也可能造成SYN队列爆满,可以使用SYN cookie来解决这个问题。即SYN到达时并不放入SYN队列中,而是将所有的信息写入cookie,当客户端ACK到达时验证cookie中的信息后再分配资源。
TCP两次握手会产生什么问题:已经失效的连接报文段突然又被服务器端收到,造成双方的不一致,进而造成资源浪费。此时如果服务器端发送连接到失效的请求,并返回SYN和ACK后,自认为连接已经建立好了,所以会频繁的发送数据到客户端,而客户端处于closed状态,直接把数据丢弃。同时如果此时客户端想要建立新连接,但是已经又连接占用,也会导致客户端无法建立真正的需求。当客户端老是收到丢弃的数据,客户端就会发一个RST强制服务端关闭连接。
RST和ACK收到时不用再回ACK
-
中间人对DNS进行了一些操作导致无法通过域名获得正确的IP。
-
解决方法:1. 使用第三方DNS解析服务 2.搭建自己的DNS服务器
http协议用韵都是客户端发起请求,服务器返回响应,这样就会使得无法实现客户端未发起的请求,而服务器将消息推送给客户端。
请求报文组成部分:1. 请求行 2.请求头 3. 请求空行 4. 请求体
http在1.1版本中,所有的请求头除host外都是可选的。host主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP的URL中提取出来的。不包含host主机头域,服务器会返回400状态码。
1xx: 提示信息,表示请求已接收,继续处理。
2xx: 成功, 表示请求已被成功接收,理解,接受。
3xx: 重定向, 要完成请求必须进行更进一步的操作。
4xx: 客户端错误,请求有语法错误或请求无法实现。
5xx: 服务器错误,服务器未能实现合法的请求。
ssl通信机制:1. 客户端发送client hello报文开始通信。报文中包含SSL指定版本号,加密组件列表,有加密算法和密钥长度。2. 服务器端回应server hello报文作为应答。筛选出SSL版本和加密组件,并发送CA证书,其中包括公钥。3. 第二次交互,客户端生成一个pre-master secret的随机密码串。并使用CA证书中的公钥加密。
- https是http的安全版。
主要区别在于:
- http是明文传输,https是密文传输。
- http默认端口是80, https的默认443
- https需要验证服务器端的身份,如果CA证书不正确则会中断通信。
- CA证书需要成本,加密解密的过程增加CPU和内存的开销。
-
https增加了ssl层,用于确保传输的安全性。
-
通信前先进行ssl层的握手,首先客户端ssl版本号和加密组件发送给服务器端。
-
服务器端筛选出可用的ssl版本号和加密算法同时加上CA证书发送给客户端。
-
客户端验证CA证书的有效性,如果无效则中断通信。
-
若有效客户端发送加密的pre-master secret随机密码串,这一步使用的是非对称加密,用于协商后面对称加密的密钥,所以这一步不能被篡改和截获。客户端得到服务器端的响应后,且验证通过后,后续就使用对称加密加密算法进行加密。然后进行TCP三次握手。