笔记:图解⽹络(⼩林coding)
这⾥写⽬录标题
引⾔
最近读完两本不错的书,⼀本是《现代操作系统:原理与实现》。
网上购物最好的网站这本书很详细的阐述了OS⽅⾯的知识,有的术语很新,也⽐较晦涩难懂。
建议看的时候可以不⽤太在意细节,⼀些记了肯定忘的英⽂缩写之类的理解其思想就好,抓重点学习。
这本书的配套lab我没有做,但是听说不错,感兴趣的同学可以做做。由于是纸质书不⽅便做笔记,我就只简单的在纸上记了⼀些关键词来帮助我复习,故不放上来。
另⼀本是⾯向就业的图解教程,由⼩林coding这个良⼼博主总结。
这本书写的很通俗易懂,对于⼀些点钻研的也很深,不过内容覆盖⾯不是特别⼴,个⼈觉得适合初学者和突击就业的⼈阅读。
图解系统那本我也看了⼀些,过段时间看完了同样放上来,不过最近有些别的事。
⼤家可以直接在搜索⼩林coding去获取这本书。
⼀、基础篇
应⽤层是⼯作在操作系统中的⽤户态,传输层及以下则⼯作在内核态。
UDP也可以实现可靠传输,把TCP的特性在应⽤层上实现就可以。
当传输层的数据包⼤⼩超过MSS(TCP最⼤报⽂段⻓度),就要将数据包分块。
在TCP协议中,我们把每个分块称为⼀个TCP段(TCPSegment)。
⼆、HTTP篇
超⽂本是超越了普通⽂本的⽂本,它是⽂字、图⽚、视频等的混合体,最关键有超链接,能从⼀个超⽂本跳转到另外⼀个超⽂本。
Get⽅法的含义是请求从服务器获取资源,这个资源可以是静态的⽂本、⻚⾯、图⽚视频等。⽽POST⽅法则是相反操作,它向URI指定的资源提交数据,数据就放在报⽂的body⾥。GET⽅法就是安全且幂等的,POST⽅法不是。
HTTPS就是在HTTP与TCP层之间增加了SSL/TLS安全传输层。
HTTP连接建⽴相对简单,TCP三次握⼿之后便可进⾏HTTP的报⽂传输。⽽HTTPS在TCP三次握⼿之后,还需进⾏SSL/TLS的握⼿过程,才可进⼊加密报⽂传输。
HTTPS协议需要向CA(证书权威机构)申请数字证书,来保证服务器的⾝份是可信的。
HTTPS:
混合加密:
HTTPS采⽤的是对称加密和⾮对称加密结合的「混合加密」⽅式:
在通信建⽴前采⽤⾮对称加密的⽅式交换「会话秘钥」,后续就不再使⽤⾮对称加密。
在通信过程中全部使⽤对称加密的「会话秘钥」的⽅式加密明⽂数据。
采⽤「混合加密」的⽅式的原因:
对称加密只使⽤⼀个密钥,运算速度快,密钥必须保密,⽆法做到安全的密钥交换。
⾮对称加密使⽤两个密钥:
公钥和私钥,公钥可以任意分发⽽私钥保密,解决了密钥交换问题但速度慢。
因为考虑到性能的问题,所以双⽅在加密应⽤信息时使⽤的是对称加密密钥,⽽对称加密密钥是不能被泄漏的,为了保证对称
加密密钥的安全性,所以使⽤⾮对称加密的⽅式来保护对称加密密钥的协商,这个⼯作就是密钥交换算法负责的。
加密密钥的安全性,所以使⽤⾮对称加密的⽅式来保护对称加密密钥的协商,这个⼯作就是密钥交换算法负责的。
摘要算法:
摘要算法⽤来实现完整性,能够为数据⽣成独⼀⽆⼆的「指纹」,⽤于校验数据的完整性,解决了篡改的⻛险。
数字证书:
借助第三⽅权威机构CA(数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。CA的公钥已事先置⼊到了浏览器或操作系统中。
私钥加密算法,⼜称对称加密算法。公钥加密算法,也就是⾮对称加密算法。
公钥和私钥成对出现,公开的密钥叫公钥,只有⾃⼰知道的叫私钥,⽤公钥加密的数据只有对应的私钥可以解密,⽤私钥加密的数据只有对应的公钥可以解密。
HTTP/2:
头部压缩在客户端和服务器同时维护⼀张头信息表,所有字段都会存⼊这个表,⽣成⼀个索引号,以后就不发送同样字段了,只发送索引号。
⼆进制格式HTTP/2不再像HTTP/1.1⾥的纯⽂本形式的报⽂,⽽是全⾯采⽤了⼆进制格式,头信息和数据体都是⼆进制,并且统称为帧(frame):头信息帧和数据帧。
数据流:
每个请求或回应的所有数据包,称为⼀个数据流(Stream)。每个数据流都标记着⼀个独⼀⽆⼆的编号,其中规
定客户端发出的数据流编号为奇数,服务器发出的数据流编号为偶数。
多路复⽤:
师德演讲稿HTTP/2是可以在⼀个连接中并发多个请求或回应,⽽不⽤按照顺序⼀⼀对应。
服务器推送:
HTTP/2还在⼀定程度上改善了传统的「请求-应答」⼯作模式,服务不再是被动地响应,也可以主动向客户端发送消息。
HTTP/1.1中的管道(pipeline)传输中如果有⼀个请求阻塞了,那么队列后请求也统统被阻塞住了。HTTP/2多个请求复⽤⼀个TCP连接,⼀旦发⽣丢包,就会阻塞住所有的HTTP请求。
HTTP/3把HTTP下层的TCP协议改成了UDP。
HTTP/1.1如何优化:
缓存技术:
不含有包体的304NotModified。
减少重定向请求次数:
重定向的⼯作交由代理服务器完成,就能减少HTTP请求次数了。
合并请求:
把多个访问⼩⽂件的请求合并成⼀个⼤的请求当⼤资源中的某⼀个⼩资源发⽣变化后,客户端必须重新下载整个完整的⼤资源⽂件。
延迟发送请求:
只获取当前⽤户所看到的⻚⾯资源,当⽤户向下滑动⻚⾯的时候,再向服务器获取接下来的资源。
⽆损压缩:
⽆损压缩是指资源经过压缩后,信息不被破坏,还能完全恢复到压缩前的原样。
有损压缩:
有损压缩主要将次要的数据舍弃,牺牲⼀些质量来减少数据量、提⾼压缩⽐。
三、TCP篇
PSH(push):表⽰推送操作,就是指数据包到达接收端以后,不对其进⾏队列处理,⽽是尽可能的将数据交给应⽤程序处理。
URG(urgent):紧急标志,⽤于保证TCP连接不被中断,并且督促中间层设备尽快处理。
为什么是三次握⼿?不是两次、四次?
避免历史连接:
如果是两次握⼿连接,就不能判断当前连接是否是历史连接,三次握⼿则可以在客户端(发送⽅)准备发送第三次报⽂时,客户端因有⾜够的上下⽂来判断当前连接是否是历史连接。
客户端收到后可以根据⾃⾝的上下⽂,判断这是⼀个历史连接(序列号过期或超时),那么客户端就会发送RST(RESET)报⽂给服务端,表⽰中⽌这⼀次连接。
同步双⽅初始序列号:
ISN。
避免资源浪费:
如果客户端的SYN阻塞了,重复发送多次SYN报⽂,那么服务器在收到请求后就会建⽴多个冗余的⽆效链接,造成不必要的资源浪费。
TCP四次挥⼿:
客户端打算关闭连接,此时会发送⼀个TCP⾸部FIN标志位被置为1的报⽂,也即FIN报⽂,之后客户端进⼊FIN_WAIT_1状态。
服务端收到该报⽂后,就向客户端发送ACK应答报⽂,接着服务端进⼊CLOSED_WAIT状态。客户端收到服务端的ACK应答报⽂后,之后进⼊FIN_WAIT_2状态。
等待服务端处理完数据后,也向客户端发送FIN报⽂,之后服务端进⼊LAST_ACK状态。
客户端收到服务端的FIN报⽂后,回⼀个ACK应答报⽂,之后进⼊TIME_WAIT状态服务器收到了ACK应答报⽂后,就进⼊了
CLOSE状态,⾄此服务端已经完成连接的关闭。
客户端在经过2MSL⼀段时间后,⾃动进⼊CLOSE状态,⾄此客户端也完成连接的关闭。
主动关闭连接的,才有TIME_WAIT状态。
服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN⼀般都会分开发送,从⽽⽐三次握⼿导致多了⼀次。陈纪匡
MSL是MaximumSegmentLifetime,报⽂最⼤⽣存时间,它是任何报⽂在⽹络上存在的最长时间,超过这个时间报⽂将被丢弃。因为TCP报⽂基于是IP协议的,⽽IP头中有⼀个TTL字段,是IP数据报可以经过的最⼤路由数,每经过⼀个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报⽂通知源主机。
MSL与TTL的区别:MSL的单位是时间,⽽TTL是经过路由跳数。
2MSL的时间是从客户端接收到FIN后发送ACK开始计时的。如果在TIME-WAIT时间内,因为客户端的ACK没有传输到服务端,客户端⼜接收到了服务端重发的FIN报⽂,那么2MSL时间将重新计时。
TIME_WAIT等待2倍的MSL,⽐较合理的解释是:⽹络中可能存在来⾃发送⽅的数据包,当这些发送⽅的数据包被接收⽅处理后⼜会向对⽅发送响应,所以⼀来⼀回需要等待2倍的时间。防⽌旧连接的数据包、保证连接正确关闭。
优化2MSL:
赴美探亲签证p_tw_reuse 和 tcp_timestamps:
复⽤处于TIME_WAIT的socket为新的连接所⽤。
p_max_tw_buckets:
当系统中处于 TIME_WAIT 的连接⼀旦超过这个值时,系统就会将后⾯的 TIME_WAIT 连接状态重置。
程序中使⽤SO_LINGER:
如果 l_onoff 为⾮ 0, 且 l_linger 值为 0,那么调⽤ close 后,会⽴该发送⼀个 RST 标志给对端,该 TCP 连接将跳过四次挥⼿,也就跳过了 TIME_WAIT 状态,直接关闭。
SYN攻击:
攻击者短时间伪造不同IP地址的SYN报⽂,服务端每接收到⼀个SYN报⽂,就进⼊SYN_RCVD状态,但服务端发送出去的ACK+SYN报⽂,⽆法得到未知IP主机的ACK应答,久⽽久之就会占满服务端的SYN接收队列(未连接队列),使得服务器不能为正常⽤户服务。
防范:
主要有两⼤类,⼀类是通过防⽕墙、路由器等过滤⽹关防护,另⼀类是通过加固TCP/IP协议栈防范。
SYN(未完成连接建⽴)队列与Accpet(已完成连接建⽴)队列是如何⼯作的:
当服务端接收到客户端的SYN报⽂时,会将其加⼊到内核的「SYN队列」;
接着发送SYN+ACK给客户端,等待客户端回应ACK报⽂;
服务端接收到ACK报⽂后,从「SYN队列」移除放⼊到「Accept队列」;
应⽤通过调⽤accpet()socket接⼝,从「Accept队列」取出连接。
SYN Cookie:
当 「 SYN 队列」满之后,后续服务器收到 SYN 包,不进⼊「 SYN 队列」;
计算出⼀个 cookie 值,再以 SYN + ACK 中的「序列号」返回客户端,服务端接收到客户端的应答报⽂时,服务器会检查这个ACK 包的合法性。如果合法,直接放⼊到「 Accept 队列」。
半关闭:
当TCP链接中A向B发送FIN请求关闭,另⼀端B回应ACK之后,并没有⽴即发送FIN给A,A⽅处于半连接状态(半开关),此时A可以接收B发送的数据,但是A已经不能再向B发送数据。
半连接:
发⽣在TCP三次握⼿中,如果A向B发起链接,B也按照正常情况响应了,但是A不进⾏三次握⼿,这
就是半连接。
半打开:
如果⼀⽅关闭或者异常关闭(断电,断⽹),⽽另⼀⽅并不知情,这样的链接称之为半打开。解决:引⼊⼼跳机制。
序列号:在建⽴连接时由计算机⽣成的随机数作为其初始值,通过SYN包传给接收端主机,每发送⼀次数据,就
「累加」⼀次该「数据字节数」的⼤⼩。⽤来解决⽹络包乱序问题。
确认应答号:指下⼀次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。⽤来解决不丢包的问题。
TCP是⾯向连接的、可靠的、基于字节流的传输层通信协议。
MTU:⼀个⽹络包的最⼤⻓度,以太⽹中⼀般为1500字节;
MSS:除去IP和TCP头部之后,⼀个⽹络包所能容纳的TCP数据的最⼤⻓度。
为什么UDP头部没有「⾸部⻓度」字段,⽽TCP头部有「⾸部⻓度」字段呢:
TCP有可变⻓的「选项」字段,⽽UDP头部⻓度则是不会变化的,⽆需多⼀个字段去记录UDP的⾸部⻓度。
TCP数据的长度=IP总长度-IP⾸部长度-TCP⾸部长度。
TCP的连接状态查看,在Linux可以通过netstat-napt命令查看。
由IP层进⾏分⽚传输,是⾮常没有效率的,如果⼀个IP分⽚丢失,整个IP报⽂的所有分⽚都得重传,因为IP层本⾝没有超时重传机制,
由IP层进⾏分⽚传输,是⾮常没有效率的,如果⼀个IP分⽚丢失,整个IP报⽂的所有分⽚都得重传,因为IP层本⾝没有超时重传机制,它由传输层的TCP来负责超时和重传。
所以,为了达到最佳的传输效能TCP协议在建⽴连接的时候通常要协商双⽅的MSS值,当TCP层发现数据超过
余声个人资料MSS时,则就先会进⾏分⽚,当然由它形成的IP包的⻓度也就不会⼤于MTU,⾃然也就不⽤IP分⽚了。
经过TCP层分⽚后,如果⼀个TCP分⽚丢失后,进⾏重发时也是以MSS为单位,⽽不⽤重传所有的分⽚,⼤⼤增加了重传的效率。
TCP保活机制:
定义⼀个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作⽤,每隔⼀个时间间隔,发送⼀个探测报⽂,该探测报⽂包含的数据⾮常少,如果连续⼏个探测报⽂都没有得到响应,则认为当前的TCP 连接已经死亡,系统内核将错误信息通知给上层应⽤程序。
listen backlog:accept队列⼤⼩。
客户端 connect 成功返回是在第⼆次握⼿,服务端 accept 成功返回是在三次握⼿成功之后。
如果⼀个⼤的 TCP 报⽂被 MSS 分⽚,那么所有「分⽚都具有 TCP 头部」,因为每个 MSS 分⽚的是具有TCP 头部的TCP报⽂,那么其中⼀个 MSS 分⽚丢失,就只需要重传这⼀个分⽚就可以。
⼀个 TCP 连接是由四元组(源 IP 地址,源端⼝,⽬标 IP 地址,⽬标端⼝)确定的。
超时重传:
RTT 就是数据从⽹络⼀端传送到另⼀端所需的时间,也就是包的往返时间。
超时重传时间是以 RTO (Retransmission Timeout 超时重传时间)表⽰,RTO应该是⼀个动态变化的值。RTO 也是指数上涨的。
超时重传时间 RTO 的值应该略⼤于报⽂往返 RTT 的值。
沈傲君老公是谁快速重传:
不以时间为驱动,⽽是以数据驱动重传。
快速重传的⼯作⽅式是当收到三个相同的 ACK 报⽂时,会在定时器过期之前,重传丢失的报⽂段。
它依然⾯临着另外⼀个问题。就是重传的时候,是重传之前的⼀个,还是重传所有的问题。
SACK ( Selective Acknowledgment 选择性确认):这种⽅式需要在 TCP 头部「选项」字段⾥加⼀个 SACK 的东⻄。
Duplicate SACK ⼜称 D-SACK 其主要使⽤了 SACK 来告诉「发送⽅」有哪些数据被重复接收。
滑动窗⼝:
窗⼝⼤⼩就是指⽆需等待确认应答,⽽可以继续发送数据的最⼤值(⽀持管线化的机制)。
累计确认或者累计应答:
ACK 600 确认应答报⽂丢失,也没关系,因为可以通过下⼀个确认应答进⾏确认,只要发送⽅收到了 ACK
700 确认应答,就意味着 700 之前的所有数据「接收⽅」都收到了。
通常窗⼝的⼤⼩是由接收⽅的窗⼝⼤⼩来决定的。
发送⽅的滑动窗⼝:使⽤三个指针来跟踪在四个传输类别中的每⼀个类别中的字节。
流量控制:
TCP 提供⼀种机制可以让「发送⽅」根据「接收⽅」的实际接收能⼒控制发送的数据量,这就是所谓的流量控制。
当发送⽅可⽤窗⼝变为 0 时,发送⽅实际上会定时发送窗⼝探测报⽂,以便知道接收⽅的窗⼝是否发⽣了改变。
接收⽅向发送⽅通告窗⼝⼤⼩时,是通过 ACK 报⽂来通告的。
为了防⽌该报⽂丢失造成的死锁问题,TCP 为每个连接设有⼀个持续定时器,只要 TCP 连接⼀⽅收到对⽅的零窗⼝通知,就启动持续计时器。如果持续计时器超时,就会发送窗⼝探测 ( Window probe ) 报⽂,⽽对⽅在确认这个探测报⽂时,给出⾃⼰现在的接收窗⼝⼤⼩。