开通VIP,畅享免费电子书等14项超值服
首页
好书
留言交流
下载APP
联系客服
2021.11.04
OSI七层模型「物理层」
首先解决两台物理机之间的通信需求,具体就是机器A往机器B发送比特流,机器B能收到比特流。
物理层主要定义了物理设备的标准,如网线的类型,光纤的接口类型,各种传输介质的传输速率。
主要作用是传输比特流(0101二进制数据),将比特流转化为电流强弱传输,到达目的后再转化为比特流,即常说的数模转化和模数转换。
这层数据叫做比特。「网卡工作在这层」。
物理层是OSI七层模型的物理基础,没有它就谈不上数据传输了
物理层就是由实物所承载的,所以作比喻的话,公路、汽车和飞机等承载货物(数据)的交通工具,就是物理层的象征
「数据链路层」
在传输比特流的过程中,会产生错传、数据传输不完整的可能。
数据链路层定义了「如何格式化数据进行传输」,以及如何控制对物理介质的访问。通常提供错误检测和纠正,以确保数据传输的准确性。
本层将比特数据组成帧,交换机工作在这层,对帧解码,并根据帧中包含的信息把数据发送到正确的接收方。
该层负责物理层面上互连的节点之间的通信传输。例如与1个以太网相连的两个节点间的通讯。
常见的协议有HDLC、PPP、SLIP等
数据链路层会将0、1序列划分为具有意义的数据帧传送给对端(「数据帧的生成与接收」)
「网络层」
随着网络节点的不断增加,点对点通讯需要通过多个节点,如何找到目标节点,如何选择最佳路径成为首要需求。
网络层主要功能是将网络地址转化为对应的物理地址,并决定如何将数据从发送方路由到接收方。
网络层通过综合考虑发送优先权、网络拥塞程度、服务质量以及可选路由的花费来决定从一个网络中节点A到另一个网络中节点B的最佳路径。
由于网络层处理并智能指导数据传送,路由器连接网络隔断,所以路由器属于网络层。
网络层负责将数据传输到目标地址。目标地址可以使多个网络通过路由器连接而成的某一个地址。因此这一层主要负责「寻址和路由选择」。主要由IP、ICMP两个协议组成
网络层将数据从发送端的主机发送到接收端的主机,两台主机间可能会存在很多数据链路,但网络层就是负责找出一条相对顺畅的通路将数据传递过去。传输的地址使用的是IP地址。IP地址通过不断转发到更近的IP地址,最终可以到达目标地址
「传输层」
传输层解决了主机间的数据传输,数据间的传输可以是不同网络,并且传输层解决了「传输质量」的问题。
「会话层」
自动收发包,自动寻址。
会话层作用是「负责建立和断开通信连接」,何时建立,断开连接以及保持多久的连接。常见的协议有ADSP、RPC等
「表示层」
Linux给WIndows发包,不同系统语法不一致,如exe不能在Linux下执行,shell不能在Windows不能直接运行。于是需要表示层。
解决「不同系统之间通信语法问题」,在表示层数据将按照网络能理解的方案进行格式化,格式化因所使用网络的不同而不同。
它主要负责数据格式的转换。具体来说,就是讲设备固有的数据格式转换为网络标准格式。常见的协议有ASCII、SSL/TLS等
「应用层」
规定发送方和接收方必须使用一个固定长度的消息头,消息头必须使用某种固定的组成,消息头中必须记录消息体的长度等信息,方便接收方正确解析发送方发送的数据。
四层传输层数据被称作「段」(Segments);
三层网络层数据被称做「包」(Packages);
二层数据链路层时数据被称为「帧」(Frames);
一层物理层时数据被称为「比特流」(Bits)。
OSI模型注重通信协议必要的功能;TCP/IP更强调在计算机上实现协议应该开发哪种程序
「TCP/IP划分了四层网络模型」
「四层网络协议的作用」
「举个例子:」
我们需要发送一个「index.html」。
两台电脑在应用层都使用HTTP协议(即都使用浏览器)。
在传输层,TCP协议会将HTTP协议发送的数据看作一个数据包,并在这个数据包前面加上TCP包的一部分信息(部首)
在网络层,IP协议会将TCP协议要发送的数据看作一个数据包,同样的在这个数据包前端加上IP协议的部首
在数据链路层,对应的协议也会在IP数据包前端加上以太网的部首。
源设备和目标设备通过网线连接,就可以通过物理层的二进制传输数据。
数据链路层,会使用对应的协议找到物理层的二进制数据,解码得到以太网的部首信息和对应的IP数据包,再将IP数据包传给上层的网络层。
数据链路层>网络层>传输层>应用层,一层层的解码,最后就可以在浏览器中得到目标设备传送过来的「index.html」。
「TCP/IP协议族」
从字面意义上来讲,TCP/IP是指「传输层」的TCP协议和「网络层」的IP协议。
实际上,TCP/IP只是利用IP进行通信时所必须用到的协议群的统称。
具体来说,在网络层是IP/ICMP协议、在传输层是TCP/UDP协议、在应用层是SMTP、FTP、以及HTTP等。他们都属于TCP/IP协议。
交换机可以接入多台电脑
每个电脑网卡的「MAC地址」都是不一样的,电脑发送数据时,数据头部携带网卡的MAC地址,用MAC地址标识来不同的电脑
交换机就可以识别数据头部的MAC地址来区分不同的电脑
交换机除了能识别不同的电脑,还需要找到电脑连接的「交换机端口」,才能顺利的把数据从相应端口发送出去
交换机通过「自学机制」,把学习到的设备MAC地址和交换机端口号添加到「MAC地址表」,并根据MAC地址表进行数据「转发」
交换机需要记录的MAC地址表也越来越多,需要的交换机也越来越多
但是交换机的「容量和性能有限」,MAC地址表无法记录全世界电脑的MAC地址和对应的端口号,MAC地址表太大也无法快速查找到对应的MAC地址表项
于是就有了三层网络设备「路由器」,路由器可以把全世界的网络连接起来
局域网内的网络连接可以使用「交换机」,例如一个公司内的网络或者一个校园内的网络通过交换机连接
不同区域的局域网互联使用「路由器」
那么如何区分不同的网络区域呢?又是如何跨网络区域进行数据转发的呢?
路由器有多个端口,分别连接不同的网络区域,不同网络区域的IP地址「网络号不同」
它通过识别目的IP地址的「网络号」,再根据「路由表」进行数据转发
「请求方法」
HTTP1.0定义了三种请求方法:GET,POST和HEAD方法。
HTTP1.1新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE和CONNECT方法。
「GET请求和POST请求的区别」
「状态码由3位数字组成,第一位定义响应的类别」
1XX:指示信息,表示请求以接收,继续处理
2XX:成功,表示请求已经被成功接收、理解、接受
3XX:状态码表示客户端请求的资源发送了变动,需要客户端用新的URL重新发送请求获取资源,也就是「重定向」。
301和302都会在响应头里使用字段Location,指明后续要跳转的URL,浏览器会自动重定向新的URL。
4XX:状态码表示客户端发送的「报文有误」,服务器无法处理,也就是错误码的含义。
5XX:状态码表示客户端请求报文正确,但是「服务器处理时内部发生了错误」,属于服务器端的错误码。
「301和302的区别」
301重定向,指页面永久性转移,表示为资源或页面永久性地转移到了另一个位置。
301是HTTP协议中的一种状态码,当用户或搜索引擎向服务器发出浏览请求时,服务器返回的HTTP数据流中头信息中包含状态码301,表示该资源已经永久改变了位置。
302重定向是页面暂时性转移,搜索引擎会抓取新的内容而保存旧的网址并认为新的网址只是暂时的。
「长连接」
HTTP1.1支持长连接
HTTP1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。
HTTP1.1则支持持久连接PersistentConnection,并且默认使用,在同一个TCP的连接中可以传送多个HTTP请求和响应,多个请求和响应可以重叠,多个请求和响应可以同时进行,更加多的请求头和响应头
HTTP1.1的持续连接,也需要增加新的请求头来帮助实现,例如,Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接;Connection请求头的值为Close时,客户端通知服务器返回本次请求结果后关闭连接。
「管道网络传输」
HTTP/1.1采用了长连接的方式,这使得管道网络传输成为了可能。
举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求,管道机制则是允许浏览器同时发出A请求和B请求。
但是服务器还是按照「顺序」,先回应A请求,完成后再回应B请求,要是前面的回应特别慢,后面就会有许多请求排队等着。
「Host字段」
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名,但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。
HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400BadRequest)。
此外,服务器应该接受以绝对路径标记的资源请求。
「100Status」
HTTP/1.1加入了一个新的状态码100。
客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);
如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。
100状态代码的使用,允许客户端在发request消息body之前先用requestheader试探一下server,看server要不要接收requestbody,再决定要不要发requestbody。
「ChunkedTransferCoding」
HTTP/1.1将发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。
这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。
「Cache」
HTTP/1.1在1.0的基础上加入了一些Cache的新特性,当缓存对象的Age超过Expire时变为Stable对象,Cache不需要直接抛弃Stable对象,而是与源服务器进行重新激活。
「HTTP2.0和HTTP1.X相比的新特性」
HTTP/2还在一定程度上改善了传统的请求-应答工作模式,服务不再是被动地响应,也可以「主动」向客户端发送消息。
举例来说,在浏览器刚请求HTML的时候,就提前把可能会用到的JS、CSS文件等静态资源主动发给客户端,「减少延时的等待」,也就是服务器推送。
「数据流」
HTTP/2的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。
因此,必须要对数据包做标记,指出它属于哪个回应。
每个请求或回应的所有数据包,称为一个数据流(Stream)。
每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数,服务器发出的数据流编号为偶数
客户端还可以「指定数据流的优先级」。优先级高的请求,服务器就先响应该请求。
「HTTP2.0的多路复用和HTTP1.X中的长连接复用有什么区别」
「使用UDP协议」
HTTP/2主要的问题在于:多个HTTP请求在复用一个TCP连接,下层的TCP协议是不知道有多少个HTTP请求的。
所以一旦发生了丢包现象,就会触发TCP的重传机制,这样在一个TCP连接中的「所有的HTTP请求都必须等待这个丢了的包被重传回来」。
这都是基于TCP传输层的问题,所以「HTTP/3把HTTP下层的TCP协议改成了UDP!」
「HTTP与HTTPS的区别」
HTTP是明文传输协议,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全
「工作原理」
HTTPS协议会对传输的数据进行加密,而加密过程是使用了非对称加密实现
HTTPS的整体过程分为证书验证和数据传输阶段,具体的交互过程如下:
客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
这就存在些问题,如何保证公钥不被篡改和信任度?
所以这里就需要借助第三方权威机构CA(数字证书认证机构),将「服务器公钥放在数字证书」(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。
通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。
「请求头」
HTTP请求报文由3部分组成(请求行+请求头+请求体)
「常见的HTTP报文头属性」
决定当前事务(三次握手和四次挥手)完成后,是否关闭网络连接。
响应报文与请求报文一样,由三个部分组成(响应行,响应头,响应体)
「HTTP响应报文属性」
TCP是一个传输层协议,提供可靠传输,支持全双工,是一个连接导向的协议。
「双工/单工」
在任何一个时刻,如果数据只能单向发送,就是单工。
如果在某个时刻数据可以向一个方向传输,也可以向另一个方向反方向传输,而且交替进行,叫作半双工;半双工需要至少1条线路。
如果任何时刻数据都可以双向收发,这就是全双工,全双工需要大于1条线路。
TCP是一个双工协议,数据任何时候都可以双向传输。
这就意味着客户端和服务端可以平等地发送、接收信息。
「TCP协议的主要特点」
「TCP的可靠性原理」
可靠传输有如下两个特点:
首先,采用三次握手来建立TCP连接,四次握手来释放TCP连接,从而保证建立的传输信道是可靠的。
其次,TCP采用了连续ARQ协议(回退N(Go-back-N);超时自动重传)来保证数据传输的正确性,使用滑动窗口协议来保证接方能够及时处理所接收到的数据,进行流量控制。
最后,TCP使用慢开始、拥塞避免、快重传和快恢复来进行拥塞控制,避免网络拥塞。
TCP虽面向字节流,但传送的数据单元为报文段
报文段=首部+数据2部分
TCP的全部功能体现在它首部中各字段的作用
「端口」:
源端口号和目地端口各占16位两个字节,也就是端口的范围是2^16=65535
另外1024以下是系统保留的,从1024-65535是用户使用的端口范围
「seq序号」:占4字节,TCP连接中传送的字节流中的每个字节都按顺序编号。
例如:一段报文的序号字段值是107,携带的数据是100个字段,下一个报文段序号从107+100=207开始。
「ack确认号」:4个字节,是期望收到对方下一个报文段的第一个数据字节的序号。
例如:B收到A发送的报文,其序号字段是301,数据长度是200字节,表明B正确收到A发送的到序号500为止的数据(301+200-1=500),B期望收到A下一个数据序号是501,B发送给A的确认报文段中把ack确认号置为501。
「数据偏移」:头部有可选字段,长度不固定,指出TCP报文段的数据起始处距离报文段的起始处有多远。
「保留」:保留今后使用的,被标为1。
「控制位」:由8个标志位组成。每个标志位表示一个控制功能。
其中主要的6个:
「窗口」:滑动窗口大小,用来告知发送端接收端缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。
「校验和」:奇偶校验,此校验和是对整个的TCP报文段(包括TCP头部和TCP数据),以16位进行计算所得,由发送端计算和存储,接收端进行验证。
「紧急指针」:只有控制位中的URG为1时才有效,指出本报文段中的紧急数据的字节数。
「选项」:其长度可变,定义其他的可选参数。
TCP是面向字节流的协议,把上层应用层的数据看成字节流,所以它发送的不是固定大小的数据包,TCP协议也没有字段说明发送数据包的大小。
而且TCP不保证接受方应用程序收到的数据块和发送应用程序发送的数据块具有对应的大小关系
比如发送方应用程序交给发送方TCP10个数据块,接受方TCP可能只用了4个数据块就完整的把接受到的字节流交给了上层应用程序。
TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题
「TCP粘包/拆包解决策略」
由于TCP无法理解上一层的业务数据特点,所以TCP是无法保证发送的数据包不发生粘包和拆包,这个问题只能通过上层的协议栈设计来解决,解决思路有一下几种:
「第一次握手」:
客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器端确认。
「第二次握手」:
服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将TCP报文标志位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状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
「上面写的ack和ACK,不是同一个概念:」
「TCP为什么三次握手而不是两次握手」
「《计算机网络》中是这样说的:」
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
在书中同时举了一个例子,如下:
于是就向client发出确认报文段,同意建立连接,假设不采用「三次握手」,那么只要server发出确认,新的连接就建立了,由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。
但server却以为新的连接已经建立,并一直等待client发来数据,这样,server的很多资源就白白浪费掉了。
采用「三次握手」的办法可以防止上述现象发生,例如刚才那种情况,client不会向server的确认发出确认,server由于收不到确认,就知道client并没有要求建立连接。
「什么是半连接队列」
服务器第一次收到客户端的SYN之后,就会处于SYN_RCVD状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为「半连接队列」。
当然还有一个「全连接队列」,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
补充一点关于「SYN-ACK重传次数」的问题:
「三次握手过程中可以携带数据吗」
其实第三次握手的时候,是可以携带数据的,也就是说,第一次、第二次握手不可以携带数据,而第三次握手是可以携带数据的。
而对于第三次的话,此时客户端已经处于established状态,也就是说,对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据没啥毛病。
挥手请求可以是Client端,也可以是Server端发起的,我们假设是Client端发起:
「为什么连接的时候是三次握手,关闭的时候却是四次握手?」
建立连接时因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。所以建立连接只需要三次握手。
由于TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,TCP是全双工模式。
这就意味着,关闭连接时,当Client端发出FIN报文段时,只是表示Client端告诉Server端数据已经发送完毕了。当Server端收到FIN报文并返回ACK报文段,表示它已经知道Client端没有数据发送了,但是Server端还是可以发送数据到Client端的,所以Server很可能并不会立即关闭SOCKET,直到Server端把数据也发送完毕。
当Server端也发送了FIN报文段时,这个时候就表示Server端也没有数据要发送了,就会告诉Client端,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
「为什么TIME_WAIT要等待2MSL?」
有以下两个原因:
「RTT和RTO」
「滑动窗口」
TCP的滑动窗口主要有两个作用:
TCP报文头有个字段叫Window,用于接收方通知发送方自己还有多少缓存区可以接收数据,发送方根据接收方的处理能力来发送数据,不会导致接收方处理不过来,这便是流量控制。
发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。
发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。
不同的滑动窗口协议窗口大小一般不同。
发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧
接收窗口的大小就是滑动窗口的最大值,数据传输过程中滑动窗口的可用大小是动态变化的。
但是还有这么一点,滑动窗口的设计仅仅是考虑到了处理方的处理能力,但是没有考虑到道路的通畅问题
就好像服务端可以处理100M数据,但是传输的数据99M都堵在路上了,这不就是导致道路阻塞了么?这就需要另外一个设计「拥塞避免」
「流量控制的目的」
如果发送者发送数据过快,接收者来不及接收,那么就会有分组丢失。
为了避免分组丢失,控制发送者的发送速度,使得接收者来得及接收,这就是流量控制。
流量控制根本目的是防止分组丢失,它是构成TCP可靠性的一方面。
「如何实现流量控制」
由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。
主要的方式就是接收方返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。
「流量控制引发的死锁」
当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。
但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。
「为什么要进行拥塞控制」
假设网络已经出现拥塞,如果不处理拥塞,那么延时增加,出现更多丢包,触发发送方重传数据,加剧拥塞情况,继续恶性循环直至网络瘫痪。
拥塞控制与流量控制的适应场景和目的均不同。
拥塞发生前,可避免流量过快增长拖垮网络;拥塞发生时,唯一的选择就是降低流量。
主要使用4种算法完成拥塞控制:
算法1、2适用于拥塞发生前,算法3适用于拥塞发生时,算法4适用于拥塞解决后(相当于拥塞发生前)。
「rwnd与cwnd」
rwnd(ReceiverWindow,接收者窗口)与cwnd(CongestionWindow,拥塞窗口):
同时考虑流量控制与拥塞处理,则发送方窗口的大小不超过min{rwnd,cwnd}。
「慢启动算法」
慢开始算法的思路就是,不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。
这里用报文段的个数作为拥塞窗口的大小举例说明慢开始算法,实际的拥塞窗口大小是以字节为单位的。
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量。
ssthresh的用法如下:
注意,这里的慢并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,然后逐渐增大,这当然比按照大的cwnd一下子把许多报文段突然注入到网络中要慢得多。
「拥塞避免算法」
这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半(但不能小于2)。
然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。
「整个拥塞控制的流程:」
假定cwnd=24时,网络出现超时(拥塞),则更新后的ssthresh=12,cwnd重新设置为1,并执行慢开始算法。
当cwnd=12=ssthresh时,改为执行拥塞避免算法
注意:拥塞避免并非完全能够避免了阻塞,而是使网络比较不容易出现拥塞。
「快重传算法」
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。
「快恢复算法」
快重传配合使用的还有快恢复算法,有以下两个要点:
考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。
所以此时不执行慢开始算法,而是将cwnd设置为ssthresh减半后的值,然后执行拥塞避免算法,使cwnd缓慢增大。
即套接字,是应用层与TCP/IP协议族通信的中间软件抽象层,表现为一个封装了TCP/IP协议族的编程接口(API)
Socket不是一种协议,而是一个编程调用接口(API),属于传输层(主要解决数据如何在网络中传输)
对用户来说,只需调用Socket去组织数据,以符合指定的协议,即可通信
「UDP协议特点」
「TCP和UDP的区别」
「基于TCP和UDP的常用协议」
HTTP、HTTPS、FTP、TELNET、SMTP(简单邮件传输协议)协议基于可靠的TCP协议。
TFTP、DNS、DHCP、TFTP、SNMP(简单网络管理协议)、RIP基于不可靠的UDP协议
UDP的报文段共有2个字段:数据字段+首部字段
「UDP报文中每个字段的含义如下:」
MAC称为物理地址,也叫硬件地址,用来定义网络设备的位置,MAC地址是网卡出厂时设定的,是固定的(但可以通过在设备管理器中或注册表等方式修改,同一网段内的MAC地址必须唯一)。
MAC地址采用十六进制数表示,长度是6个字节(48位),分为前24位和后24位。
MAC地址对应于OSI参考模型的第二层数据链路层,工作在数据链路层的交换机维护着计算机MAC地址和自身端口的数据库,交换机根据收到的数据帧中的目的MAC地址字段来转发数据帧。
常见的IP地址分为IPv4与IPv6两大类,当前广泛应用的是IPv4,目前IPv4几乎耗尽,下一阶段必然会进行版本升级到IPv6;
IP地址是以网络号和主机号来标示网络上的主机的,我们把网络号相同的主机称之为本地网络,网络号不相同的主机称之为远程网络主机
本地网络中的主机可以直接相互通信;远程网络中的主机要相互通信必须通过本地网关(Gateway)来传递转发数据。
IP地址对应于OSI参考模型的第三层网络层,工作在网络层的路由器根据目标IP和源IP来判断是否属于同一网段,如果是不同网段,则转发数据包。
「IP地址格式和表示」
IP地址(IPv4)由32位二进制数组成,分为4段(4个字节),每一段为8位二进制数(1个字节)
每一段8位二进制,中间使用英文的标点符号.隔开
由于二进制数太长,为了便于记忆和识别,把每一段8位二进制数转成十进制,大小为0至255。
IP地址的这种表示法叫做「点分十进制表示法」。
IP地址表示为:xxx.xxx.xxx.xxx
举个栗子:210.21.196.6就是一个IP地址的表示。
计算机的IP地址由两部分组成,一部分为网络标识,一部分为主机标识,同一网段内的计算机网络部分相同,主机部分不能同时重复出现。
「路由器」连接不同网段,负责不同网段之间的数据转发,「交换机」连接的是同一网段的计算机。
通过设置网络地址和主机地址,在互相连接的整个网络中保证每台主机的IP地址不会互相重叠,即IP地址具有了唯一性。
「IP地址分类详解」
IP地址分A、B、C、D、E五类,其中A、B、C这三类是比较常用的IP地址,D、E类为特殊地址。
「子网掩码的概念及作用」
通过子网掩码,才能表明一台主机所在的子网与其他子网的关系,使网络正常工作。
子网掩码和IP地址做与运算,分离出IP地址中的网络地址和主机地址,用于判断该IP地址是在本地网络上,还是在远程网络网上。
子网掩码还用于将网络进一步划分为若干子网,以避免主机过多而拥堵或过少而IP浪费。
「子网掩码的组成」
同IP地址一样,子网掩码是由长度为32位二进制数组成的一个地址。
子网掩码32位与IP地址32位相对应,IP地址如果某位是网络地址,则子网掩码为1,否则为0。
举个栗子:如:11111111.11111111.11111111.00000000
左边连续的1的个数代表网络号的长度,(使用时必须是连续的,理论上也可以不连续),右边连续的0的个数代表主机号的长度。
「为什么要使用子网掩码」
两台主机要通信,首先要判断是否处于同一网段,即网络地址是否相同。
如果相同,那么可以把数据包直接发送到目标主机,否则就需要路由网关将数据包转发送到目的地。
可以这么简单的理解:A主机要与B主机通信,A和B各自的IP地址与A主机的子网掩码进行And与运算,看得出的结果:
1、结果如果相同,则说明这两台主机是处于同一个网段,这样A可以通过ARP广播发现B的MAC地址,B也可以发现A的MAC地址来实现正常通信。
2、如果结果不同,ARP广播会在本地网关终结,这时候A会把发给B的数据包先发给本地网关,网关再根据B主机的IP地址来查询路由表,再将数据包继续传递转发,最终送达到目的地B。
计算机的网关(Gateway)就是到其他网段的出口,也就是路由器接口IP地址。
路由器接口使用的IP地址可以是本网段中任何一个地址,不过通常使用该网段的第一个可用的地址或最后一个可用的地址,这是为了尽可能避免和本网段中的主机地址冲突。
在如下拓扑图示例中,A与B,C与D,都可以直接相互通信(都是属于各自同一网段,不用经过路由器)
但是A与C,A与D,B与C,B与D它们之间不属于同一网段,所以它们通信是要经过本地网关,然后路由器根据对方IP地址,在路由表中查找恰好有匹配到对方IP地址的直连路由,于是从另一边网关接口转发出去实现互连
「子网掩码和IP地址的关系」
子网掩码是用来判断任意两台主机的IP地址是否属于同一网络的依据
拿双方主机的IP地址和自己主机的子网掩码做与运算,如结果为同一网络,就可以直接通信
「如何根据IP地址和子网掩码,计算网络地址:」
将IP地址与子网掩码转换成二进制数。
将二进制形式的IP地址与子网掩码做与运算。
将得出的结果转化为十进制,便得到网络地址。
网关实质上是一个网络通向其他网络的IP地址。
比如有网络A和网络B,网络A的IP地址范围为192.168.1.1~192.168.1.254,子网掩码为255.255.255.0;
网络B的IP地址范围为192.168.2.1~192.168.2.254,子网掩码为255.255.255.0。
在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。
而要实现这两个网络之间的通信,则必须通过网关。
如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。网络B向网络A转发数据包的过程。
「所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。」
那么这个IP地址是哪台机器的IP地址呢?
网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。
Ping是我们测试网络连接的常用指令。
它利用ICMP报文检测网络连接。
「假设ApingB」
接下来是ARP协议根据IP地址查找MAC地址的过程:
符合,接受,接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的的IP地址协议层协议,IP协议层检查之后,将有用的信息提取给ICMP协议,后者处理,马上构建一个ICMP应答包,发送给A,其过程和主机A发送ICMP请求包到B的过程类似,但不用ARP广播收取A的信息,因为请求包中已经有足够的信息用于B回应A。
若不符合,丢弃。
可以知道PING的过程即一段发送报文和接受确认报文的过程,在来回直接可以计算时延。
DNS通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。
「通俗的讲」,我们更习惯于记住一个网站的名字,www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2
将主机域名转换为ip地址,属于应用层协议,使用UDP传输。
第一步,客户端向本地DNS服务器发送解析请求
第二步,本地DNS如有相应记录会直接返回结果给客户端,如没有就向DNS根服务器发送请求
第三步,DSN根服务器接收到请求,返回给本地服务器一个所查询域的主域名服务器的地址
第四步,本地dns服务器再向返回的主域名服务器地址发送查询请求
第六步,本地DNS服务器继续向接收到的地址进行查询请求
第七步,下级域名服务器有相应记录,返回结果
第八步,本地dns服务器将收到的返回地址发给客户端,同时写入自己的缓存,以便下次查询
DNS域名查询实际上就是个不断递归查询的过程,直到查找到相应结果,需要注意的时,当找不到相应记录,会返回空结果,而不是超时信息
A记录
上面的就是一条DNS记录,纯文本即可。
www.example.com是要解析的域名。
A是记录的类型,A记录代表着这是一条用于解析IPv4地址的记录。
从这条记录可知,www.example.com的IP地址是139.18.28.5。
CNAME
CNAME用于定义域名的别名,如下面这条DNS记录:
定义www.example.com的别名a.example.com.INCNAMEb.example.com.这条DNS记录定义了a.example.com是b.example.com的别名。
用户在浏览器中输入a.example.com时候,通过DNS查询会知道a.example.com是b.example.com的别名,因此需要实际IP的时候,会去拿b.example.com的A记录。
当你想把一个网站迁移到新域名,旧域名仍然保留的时候;还有当你想将自己的静态资源放到CDN上的时候,CNAME就非常有用。
AAAA记录
A记录是域名和IPv4地址的映射关系。和A记录类似,AAAA记录则是域名和IPv6地址的映射关系。
MX记录
MX记录是邮件记录,用来描述邮件服务器的域名。
比如说,发送一封邮件到xiaoming@xiaoflyfish.com,那么如何知道哪个IP地址是邮件服务器呢?
这个时候就可以用到下面这条MX记录:
mail.xiaoflyfish.com的IP地址可以通过查询mail.xiaoflyfishcom的A记录和AAAA记录获得。
NS记录
NS记录是描述DNS服务器网址。从DNS的存储结构上说,NameServer中含有权威DNS服务的目录。
也就是说,NS记录指定哪台Server是回答DNS查询的权威域名服务器。
当一个DNS查询看到NS记录的时候,会再去NS记录配置的DNS服务器查询,得到最终的记录。如下面这个例子:
a.com.INNSns1.a.com.a.com.INNSns2.a.com.当解析a.com地址时,我们看到a.com有两个NS记录,所以确定最终a.com的记录在ns1.a.com和ns2.a.com上。
从设计上看,ns1和ns2是网站a.com提供的智能DNS服务器,可以提供负载均衡、分布式Sharding等服务。
比如当一个北京的用户想要访问a.com的时候,ns1看到这是一个北京的IP就返回一个离北京最近的机房IP。
上面代码中a.com配置了两个NS记录。
通常NS不会只有一个,这是为了保证高可用,一个挂了另一个还能继续服务。
通常数字小的NS记录优先级更高,也就是ns1会优先于ns2响应。
配置了上面的NS记录后,如果还配置了a.com的A记录,那么这个A记录会被NS记录覆盖。
ARP即地址解析协议,用于实现从IP地址到MAC地址的映射,即询问目标IP对应的MAC地址。
「ARP协议的工作过程」
首先,每个主机都会有自己的ARP缓存区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系
当源主机要发送数据时,首先检测ARP列表中是否对应IP地址的目的主机的MAC地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送ARP数据包
当本网络的所有主机收到该ARP数据包时,首先检查数据包中的IP地址是否是自己的IP地址,如果不是,则忽略该数据包,如果是,则首先从数据包中取出源主机的IP和MAC地址写入到ARP列表中,如果存在,则覆盖然后将自己的MAC地址写入ARP响应包中,告诉源主机自己是它想要找的MAC地址
源主机收到ARP响应包后,将目的主机的IP和MAC地址写入ARP列表,并利用此信息发送数据,如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
网络传输过程中需要经过很多中间节点,虽然数据无法被解密,但可能被篡改
数字签名校验数据的完整性
「数字签名有两种功效」:
将一段文本先用Hash函数生成消息摘要,然后用发送者的私钥加密生成数字签名,与原文文一起传送给接收者
接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与上一步得到的摘要信息对比。
如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
SQL注入的原理是将SQL代码伪装到输入参数中,传递到服务器解析并执行的一种攻击手法。
「SQL注入攻击实例」
下面我们分析一下:从理论上说,后台认证程序中会有如下的SQL语句:
「应对方法」
预编译
使用预编译手段,绑定参数是最好的防SQL注入的方法。
目前许多的ORM框架及JDBC等都实现了SQL预编译和参数绑定功能,攻击者的恶意SQL会被当做SQL的参数而不是SQL命令被执行。
在mybatis的mapper文件中,对于传递的参数我们一般是使用#和$来获取参数值。
当使用#时,变量是占位符,就是一般我们使用java的jdbc的PrepareStatement时的占位符,所有可以防止sql注入;
当使用$时,变量就是直接追加在sql中,一般会有sql注入问题。
使用正则表达式过滤传入的参数
过滤参数中含有的一些数据库关键词
加密算法分「对称加密」和「非对称加密」,其中对称加密算法的加密与解密密钥相同,非对称加密算法的加密密钥与解密密钥不同,此外,还有一类不需要密钥的「散列算法」。
常见的「对称加密」算法主要有DES、3DES、AES等,常见的「非对称算法」主要有RSA、DSA等,「散列算法」主要有SHA-1、MD5等。
在「对称加密算法」中,使用的密钥只有一个,发送和接收双方都使用这个密钥对数据进行「加密」和「解密」。
「非对称加密算法」,它需要两个密钥,一个称为「公开密钥」(publickey),即「公钥」,另一个称为「私有密钥」(privatekey),即「私钥」。
因为「加密」和「解密」使用的是两个不同的密钥,所以这种算法称为「非对称加密算法」。
「例子」:甲方生成「一对密钥」并将其中的一把作为「公钥」向其它人公开,得到该公钥的「乙方」使用该密钥对机密信息「进行加密」后再发送给甲方,甲方再使用自己保存的另一把「专用密钥」(「私钥」),对「加密」后的信息「进行解密」。
「XSS:」
跨站脚本是一种网站应用程序的安全漏洞攻击,是代码注入的一种。
它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响,这类攻击通常包含了HTML以及用户端脚本语言。
比如通过客户端脚本语言(最常见如:JavaScript)
在一个论坛发帖中发布一段恶意的JavaScript代码就是脚本注入,如果这个代码内容有请求外部服务器,那么就叫做XSS
「XSS攻击分类」
反射性XSS攻击(非持久性XSS攻击)
例如,正常发送消息:
接收者接收消息显示的时候将会弹出警告窗口!
持久性XSS攻击(留言板场景)
一般指XSS攻击代码存储在网站数据库,当一个页面被用户打开的时候执行。
也就是说,每当用户使用浏览器打开指定页面时,脚本便执行。
与非持久性XSS攻击相比,持久性XSS攻击危害性更大。
从名字就可以了解到,持久性XSS攻击就是将攻击代码存入数据库中,然后客户端打开时就执行这些攻击代码。
例如,留言板表单中的表单域:
而非正常操作流程是攻击者在value填写:
并将数据提交、存储到数据库中;当其他用户取出数据显示的时候,将会执行这些攻击性代码
「CSRF:」
比如冒充用户发起请求(在用户不知情的情况下),完成一些违背用户意愿的请求(如恶意发帖,删帖,改密码,发邮件等)。
DOS:中文名称是拒绝服务,该攻击的效果是使得计算机或网络无法提供正常的服务
「DOS攻击的原理:」
「DDOS:中文名称是分布式拒绝服务攻击」
指的是攻击者控制多台主机同时向同一主机或网络发起DOS攻击
DRDoS分布反射式拒绝服务攻击这是DDoS攻击的变形
「DDOS究竟如何攻击」
目前最流行也是最好用的攻击方法就是使用SYN-Flood进行攻击,SYN-Flood也就是SYN洪水攻击
若是一个用户在连接时出现问题导致服务器的一个线程等待1分钟并不是什么大不了的问题,但是若有人用特殊的软件大量模拟这种情况,那后果就可想而知了。一个服务器若是处理这些大量的半连接信息而消耗大量的系统资源和网络带宽,这样服务器就不会再有空余去处理普通用户的正常请求(因为客户的正常请求比率很小),这样这个服务器就无法工作了,这种攻击就叫做SYN-Flood攻击
到目前为止,进行DDoS攻击的防御还是比较困难的
首先,这种攻击的特点是它利用了TCP/IP协议的漏洞,除非你不用TCP/IP,才有可能完全抵御住DDoS攻击
不过这不等于我们就没有办法阻挡DDoS攻击,我们可以尽力来减少DDoS的攻击
「下面就是一些防御方法:」
Session是「基于Cookie实现」的另一种记录服务端和客户端会话状态的机制。
Session是存储在服务端,而SessionId会被存储在客户端的Cookie中。
Session的「认证过程」:
「Cookie和Session的区别」
「在浏览器地址栏键入URL」
1.DNS解析:浏览器会依据URL逐层查询DNS服务器缓存,解析URL中的域名对应的IP地址,DNS缓存从近到远依次是浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、域名服务器缓存、顶级域名服务器缓存。
从哪个缓存找到对应的IP直接返回,不再查询后面的缓存。
2.TCP连接:结合三次握手
3.发送HTTP请求:浏览器发出读取文件的HTTP请求,该请求发送给服务器
4.服务器处理请求并返回HTTP报文:服务器对浏览器请求做出响应,把对应的带有HTML文本的HTTP响应报文发送给浏览器
5.浏览器解析渲染页面
6.连接结束:浏览器释放TCP连接,该步骤即四次挥手。
第5步和第6步可以认为是同时发生的,哪一步在前没有特别的要求