文章目录
网络:
初始序列号的作用
三次握手过程中一个随机生成的初始seq,我答的作用就是防止旧分组对新建立的连接造成影响,但是他说还有一个,我查了一下是为了防止伪造序列号攻击
输入一个URL的路径
1、DNS域名解析
2、建立TCP连接;(三次握手)
3、发送http请求;
4、服务器处理请求;
5、返回响应结果;
6、关闭TCP连接;
7、浏览器解析HTML;
8、浏览器布局渲染
客户端收到你输入的域名地址后,它首先去找本地的hosts文件,检查在该文件中是否有相应的域名、IP对应关系,如果有,则向其IP地址发送请求,如果没有,再去找DNS服务器。一般用户很少去编辑修改hosts文件。
epoll和select(IO多路复用的方式)
select,poll,epoll都是IO多路复用的机制。所谓I/O多路复用机制,就是说通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
1、select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。
2、select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。
http协议如何解决粘包拆包问题
针对应用层的数据包。
当数据在传输层时,由于TCP是面向字节流的,所以它看到的数据是按照顺序一个个放在缓冲区中的,而对于应用层而言,看到的只是一连串的数据,那么应用层该从哪里读数据,读到哪合适呢?因此就有了粘包问题。
所以要避免粘包问题,就得明确两个包之间的边界:
对于定长的数据包,保证每次都按固定的大小读取即可;
对于变长的包,可在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置;
对于变长的包,还可以在包和包之间使用明确的分隔符(应用层协议,是我们自己写的,只要保证分隔符不和正文冲突即可)
若传输层是UDP协议,应用层会不会出现粘包问题?
对于UDP而言,报文长度是固定的,就算没有交付,长度依然在,同时,UDP是一个一个把数据交付给应用层的,就有很明显的边界
站在应用层的角度,每次收到的UDP报文,要么是一整个,要么不收,不会出现半个的情况
HTTPS
显然,HTTPS 相比 HTTP最大的不同就是多了一层 SSL (Secure Sockets Layer 安全套接层)或 TLS (Transport Layer Security 安全传输层协议)。有了这个安全层,就确保了互联网上通信双方的通信安全
1、SSL / TLS 以及 SSL / TLS 握手的概念
SSL 和 TLS 协议可以为通信双方提供识别和认证通道,从而保证通信的机密性和数据完整性。TLS 协议是从Netscape SSL 3.0协议演变而来的,不过这两种协议并不兼容,SSL 已经逐渐被 TLS 取代,所以下文就以 TLS 指代安全层。 TLS 握手是启动 HTTPS 通信的过程,类似于 TCP 建立连接时的三次握手。 在 TLS 握手的过程中,通信双方交换消息以相互验证,相互确认,并确立它们所要使用的加密算法以及会话密钥 (用于对称加密的密钥)。可以说,TLS 握手是 HTTPS 通信的基础部分。
2、TLS 握手过程中发生了什么
我们已经知道 TLS 握手的目的是建立安全连接,那么通信双方在这个过程中究竟干了什么呢?下面就是答案:
- 商定双方通信所使用的的 TLS 版本 (例如 TLS1.0, 1.2, 1.3等等);
- 确定双方所要使用的密码组合;
- 客户端通过服务器的公钥和数字证书 (上篇文章已有介绍)上的数字签名验证服务端的身份;
- 生成会话密钥,该密钥将用于握手结束后的对称加密。
3、TLS 握手详细过程
下面来看 TLS 握手的详细过程 (
注
:此图与
HTTPS详解一
中的
HTTPS
原理图的流程大致相同,不同的是此图把重点放在了
TLS
握手的相关概念上):
SSL / TLS 握手详细过程
- **”client hello”消息:**客户端通过发送”client hello”消息向服务器发起握手请求,该消息包含了客户端所支持的 TLS 版本和密码组合以供服务器进行选择,还有一个”client random”随机字符串。
- **”server hello”消息:**服务器发送”server hello”消息对客户端进行回应,该消息包含了数字证书,服务器选择的密码组合和”server random”随机字符串。
-
**验证:**客户端对服务器发来的证书进行验证,确保对方的合法身份,验证过程可以细化为以下几个步骤:
- 检查数字签名
- 验证证书链 (这个概念下面会进行说明)
- 检查证书的有效期
- 检查证书的撤回状态 (撤回代表证书已失效)
- **“premaster secret”字符串:**客户端向服务器发送另一个随机字符串”premaster secret (预主密钥)”,这个字符串是经过服务器的公钥加密过的,只有对应的私钥才能解密。
- **使用私钥:**服务器使用私钥解密”premaster secret”。
-
生成共享密钥
:客户端和服务器均使用 client random,server random 和 premaster secret,并通过相同的算法生成相同的共享密钥
KEY
。 -
**客户端就绪:**客户端发送经过共享密钥
KEY
加密过的”finished”信号。 -
**服务器就绪:**服务器发送经过共享密钥
KEY
加密过的”finished”信号。 - **达成安全通信:**握手完成,双方使用对称加密进行安全通信。
4、TLS 握手过程中的一些重要概念
-
**数字证书 (digital certificate):**在非对称加密通信过程中,服务器需要将公钥发送给客户端,在这一过程中,公钥很可能会被第三方拦截并替换,然后这个第三方就可以冒充服务器与客户端进行通信,这就是传说中的“中间人攻击”(man in the middle attack)。解决此问题的方法是通过受信任的第三方交换公钥,具体做法就是服务器不直接向客户端发送公钥,而是要求受信任的第三方,也就是证书认证机构 (Certificate Authority, 简称 CA)将公钥合并到数字证书中,然后服务器会把公钥连同证书一起发送给客户端,私钥则由服务器自己保存以确保安全。数字证书一般包含以下内容:
-
证书所有者的公钥
-
证书所有者的专有名称
-
证书颁发机构的专有名称
-
证书的有效起始日期
-
证书的过期日期
-
证书数据格式的版本号
-
序列号,这是证书颁发机构为该证书分配的唯一标识符
… …
-
-
**数字签名 (digital signature):**这个概念很好理解,其实跟人的手写签名类似,是为了确保数据发送者的合法身份,也可以确保数据内容未遭到篡改,保证数据完整性。与手写签名不同的是,数字签名会随着文本数据的变化而变化。具体到数字证书的应用场景,数字签名的生成和验证流程如下:
- 服务器对证书内容进行信息摘要计算 (常用算法有 SHA-256等),得到摘要信息,再用私钥把摘要信息加密,就得到了数字签名
- 服务器把数字证书连同数字签名一起发送给客户端
- 客户端用公钥解密数字签名,得到摘要信息
- 客户端用相同的信息摘要算法重新计算证书摘要信息,然后对这两个摘要信息进行比对,如果相同,则说明证书未被篡改,否则证书验证失败
-
**证书链 (certificate chain):**证书链,也称为证书路径,是用于认证实体合法身份的证书列表,具体到 HTTPS 通信中,就是为了验证服务器的合法身份。之所以使用证书链,是为了保证根证书 (root CA certificate)的安全,中间层可以看做根证书的代理,起到了缓冲的作用,如下图所示,这里还以 B 站证书为例:
证书链
证书链从根证书开始,并且证书链中的每一级证书所标识的实体都要为其下一级证书签名,而根证书自身则由证书颁发机构签名。客户端在验证证书链时,必须对链中所有证书的数字签名进行验证,直到达到根证书为止。
4.**密码规范和密码组合 (CipherSpecs 和 CipherSuites):**通信双方在安全连接中所使用的算法必须符合密码安全协议的规定,CipherSpecs 和 CipherSuites 正好定义了合法的密码算法组合。CipherSpecs 用于认证加密算法和信息摘要算法的组合,通信双方必须同意这个密码规范才能进行通信。而 CipherSuites 则定义了 SSL / TLS 安全连接中所使用的加密算法的组合,该组合包含三种不同的算法:
- 握手期间所使用的的密钥交换和认证算法 (最常用的是 RSA 算法)
- 加密算法 (用于握手完成后的对称加密,常用的有 AES、3DES等)
- 信息摘要算法 (常用的有 SHA-256、SHA-1 和 MD5 等)
1、性能指标有哪些?
通常是以 4 个指标来衡量网络的性能,分别是带宽、延时、吞吐率、PPS(Packet Per Second),它们表示的意义如下:
-
带宽
,表示链路的最大传输速率,单位是 b/s (比特 / 秒),带宽越大,其传输能力就越强。 -
延时
,表示请求数据包发送后,收到对端响应,所需要的时间延迟。不同的场景有着不同的含义,比如可以表示建立 TCP 连接所需的时间延迟,或一个数据包往返所需的时间延迟。 -
吞吐率
,表示单位时间内成功传输的数据量,单位是 b/s(比特 / 秒)或者 B/s(字节 / 秒),吞吐受带宽限制,带宽越大,吞吐率的上限才可能越高。 -
PPS
,全称是 Packet Per Second(包 / 秒),表示以网络包为单位的传输速率,一般用来评估系统对于网络的转发能力。
当然,除了以上这四种基本的指标,还有一些其他常用的性能指标,比如:
-
网络的可用性
,表示网络能否正常通信; -
并发连接数
,表示 TCP 连接数量; -
丢包率
,表示所丢失数据包数量占所发送数据组的比率; -
重传率
,表示重传网络包的比例;
2、互联网协议
网络协议就是网络中(包括互联网)传递、管理信息的一些规范。如同人与人之间相互交流是需要遵循一定的规矩一样,计算机之间的相互通信需要共同遵守一定的规则,这些规则就称为网络协议
。
OSI标准模型
TCP/TP协议簇
OSI 模型共有七层,从下到上分别是物理层、数据链路层、网络层、运输层、会话层、表示层和应用层。但是这显然是有些复杂的,所以在TCP/IP协议中,它们被简化为了四个层次
IP 协议
IP 是
互联网协议(Internet Protocol)
,位于网络层。IP是整个 TCP/IP 协议族的核心,也是构成互联网的基础。IP 能够为运输层提供数据分发,同时也能够组装数据供运输层使用。它将多个单个网络连接成为一个互联网,这样能够提高网络的可扩展性,实现大规模的网络互联。二是分割顶层网络和底层网络之间的耦合关系。
网络层最核心的协议是IP协议(Internet Protocol,因特网协议)。IP协议根据数据包的目的IP地址来决定如何投递它。如果数据包不能直接发送给目标主机,那么IP协议就为它寻找一个合适的下一跳nexthop)路由器,并将数据包交付给该路由器来转发。多次重复这一过程,数据包最终到达目标主机,或者由于发送失败而被丢弃。可见,IP协议使用逐跳( hop by hop)的方式确定通信路径。
IP协议的特点: 无连接 不可靠 无状态
无连接是指IP通信的双方都不长久地维持对方的任何信息。这样,上层协议每次发送数据的时候,都必须明确指定对方的IP地址:
不可靠是说: IP协议不保证数据报能准确到达接收端,它只是说尽自己最大努力发送。
无状态: 是说通信双方不同步传输数据的状态信息,也就是说IP数据报的发送、传输、接收都是相互独立的、没有上下文关系的。那么接收端就可能收到重复的、乱序的报文段。这就是所谓的无状态。
总结如下:
①IP协议是一种无连接、不可靠的分组传送服务的协议。
②IP协议是点-点线路的网络层通信协议。:IP协议是针对原主机-路由器、路由器-路由器、路由器-目的主机之间的数据传输的点-点线路的网络层通信协议。
③IP协议屏蔽了网络在数据链路层、物理层协议与实现技术上的差异。:通过IP协议,网络层向传输层提供的是统一的IP分组,传输层不需要考虑互联网在数据链路层、物理层协议与实现技术上的差异,IP协议使得异构网络的互联变得容易了。
ICMP 协议
ICMP 协议是
Internet Control Message Protocol
, ICMP 协议主要用于在 IP 主机、路由器之间传递控制消息。ICMP 属于网络层的协议,当遇到 IP 无法访问目标、IP 路由器无法按照当前传输速率转发数据包时,会自动发送 ICMP 消息,从这个角度来说,ICMP 协议可以看作是
错误侦测与回报机制
,让我们检查网络状况、也能够确保连线的准确性。
ARP 协议
ARP 协议是
地址解析协议
,即
Address Resolution Protocol
,它能够根据 IP 地址获取物理地址。主机发送信息时会将包含目标 IP 的 ARP 请求广播到局域网络上的所有主机,并接受返回消息,以此来确定物理地址。收到消息后的物理地址和 IP 地址会在 ARP 中缓存一段时间,下次查询的时候直接从 ARP 中查询即可。
TCP 协议
TCP 就是
传输控制协议
,也就是
Transmission Control Protocol
,它是一种面向连接的、可靠的、基于字节流的传输协议,TCP 协议位于传输层,TCP 协议是 TCP/IP 协议簇中的核心协议,它最大的特点就是提供可靠的数据交付。
TCP 的主要特点有
慢启动、拥塞控制、快速重传、可恢复
。
UDP 协议
UDP 协议就是
用户数据报协议
,也就是
User Datagram Protocol
,UDP 也是一种传输层的协议,与 TCP 相比,UDP 提供一种不可靠的数据交付,也就是说,UDP 协议不保证数据是否到达目标节点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP 是一种无连接的协议,传输数据之前源端和终端无需建立连接,不对数据报进行检查与修改,无须等待对方的应答,会出现分组丢失、重复、乱序等现象。但是 UDP 具有较好的实时性,工作效率较 TCP 协议高。
FTP 协议
FTP 协议是
文件传输协议
,英文全称是
File Transfer Protocol
,应用层协议之一,是 TCP/IP 协议的重要组成之一,FTP 协议分为服务器和客户端两部分,FTP 服务器用来存储文件,FTP 客户端用来访问 FTP 服务器上的文件,FTP 的传输效率比较高,所以一般使用 FTP 来传输大文件。
DNS 协议
DNS 协议是
域名系统协议
,英文全称是
Domain Name System
,它也是应用层的协议之一,DNS 协议是一个将域名和 IP 相互映射的分布式数据库系统。DNS 缓存能够加快网络资源的访问。
SMTP 协议
SMTP 协议是
简单邮件传输协议
,英文全称是
Simple Mail Transfer Protocol
,应用层协议之一,SMTP 主要是用作邮件收发协议,SMTP 服务器是遵循 SMTP 协议的发送邮件服务器,用来发送或中转用户发出的电子邮件
SLIP 协议
SLIP 协议是指
串行线路网际协议(Serial Line Internet Protocol)
,是在串行通信线路上支持 TCP/IP 协议的一种
点对点(Point-to-Point
)式的链路层通信协议。
PPP 协议
PPP 协议是
Point to Point Protocol
,即点对点协议,是一种链路层协议,是在为同等单元之间传输数据包而设计的。设计目的主要是用来通过拨号或专线方式建立点对点连接发送数据,使其成为各种主机、网桥和路由器之间简单连接的一种共通的解决方案。
传输方式
- 面向连接型中,在发送数据之前,需要在主机之间建立一条通信线路。
- 面向无连接型则不要求建立和断开连接,发送方可用于任何时候发送数据。接收端也不知道自己何时从哪里接收到数据。
五层协议及其作用
1、物理层:物理层不是物理传输媒体。作用是要尽可能屏蔽这些传输媒体和通信手段的差异,使物理层上方的数据链路层感觉不到这些差异,这样就可以使数据链路层只需要考虑如何完成本层的协议和服务。
2、数据链路层:a、封装成帧:在两个相邻节点之间传送数据,将网络层交下来的IP数据报组装成帧,在两个相邻节点间的链路上传送帧。b、差错检测:检查出哪个是错误的将错误丢弃(只检查错误不纠错)c、透明传输:中间如果插入了转义字符不会引起最终数据读取的差错
3、网络层:a、负责选择最佳路径和规划IP地址、路由表,通过IP协议进行地址划分。b、在不同网络之间尽力转发数据包,基于数据包的IP地址转发,如果丢失,不负责丢失重传也不负责顺序。
4、运输层:负责向两个主机中进程之间的通信提供服务。由于一个主机可同时运行多个进程,因此运输层有复用和分用的功能。复用就是多个应用进程可同时使用下面传输层的服务,分用则是运输层把收到的信息分别交付给上面的应用层中相应的进程。
5、应用层;能够和用户交互,所有能够产生网络流量的程序。使得应用程序能够直接运行于传输层之上,直接为用户提供服务。
3、TCP
经典三次握手四次挥手
三次握手:
-
Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
-
Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
-
Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
四次挥手:
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
-
数据传输结束后,客户端的应用进程发出连接释放报文段,并停止发送数据,客户端进入FIN_WAIT_1状态,此时客户端依然可以接收服务器发送来的数据。
-
服务器接收到FIN后,发送一个ACK给客户端,确认序号为收到的序号+1,服务器进入CLOSE_WAIT状态。客户端收到后进入FIN_WAIT_2状态。
-
当服务器没有数据要发送时,服务器发送一个FIN报文,此时服务器进入LAST_ACK状态,等待客户端的确认
-
客户端收到服务器的FIN报文后,给服务器发送一个ACK报文,确认序列号为收到的序号+1。此时客户端进入TIME_WAIT状态,等待2MSL(MSL:报文段最大生存时间),然后关闭连接。
第一次的序号是随机序号,但也不是完全随机,它是使用一个ISN算法得到的。
seq = C + H (源IP地址,目的IP地址,源端口,目的端口)。其中,C是一个计时器,每隔一段时间值就会变大,H是消息摘要算法,输入是一个四元组(源IP地址,目的IP地址,源端口,目的端口)。
为什么是三次握手四次挥手
如果使用两次握手的话,三次握手中的最后一次缺失,服务器不能确认客户端的接收能力。举两个例子,第一种是黑客会伪造大量SYN请求发送给服务器,服务器立即确认并建立连接,分配资源,但是这一系列连接并不是真实存在的,这大大浪费了服务器的资源并且阻塞了正常用户的连接,这种也叫
SYN洪泛攻击
。第二种是服务器返回给客户端的ACK数据包可能会在传输的过程中丢失,而客户端没有收到该ACK数据包而拒绝接收服务器接下来发送的数据,于是服务器一直在发送,客户端一直在拒绝,形成
死锁
。反之三次握手就可以解决以上问题,四次握手是不必要的。
由于TCP是一个全双工通信,在关闭连接时,当服务器收到客户端的FIN报文通知时,它仅仅表示客户端没有数据发送服务器了;但服务器未必将所有的数据都全部发送给了客户端,所以服务器端未必马上也要关闭连接,也即服务器端可能还需要发送一些数据给客户端之后,再发送FIN报文给客户端来表示现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的,这也是为什么释放连接时需要交换四次报文了。
TIME_WAIT状态,以及2MSL原因
TIME_WAIT是指四次挥手中客户端接收了服务端的FIN报文并发送ACK报文给服务器后,仍然需要等待2MSL时间的过程。虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。如果客户端发送的ACK发生丢失,服务器会再次发送FIN报文给客户端,所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
抓包三次握手四次挥手
网络分析工具
Wireshark
tcpdump 和 Wireshark 就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。
- tcpdump 仅支持命令行格式使用,常用在 Linux 服务器中抓取和分析网络包。
- Wireshark 除了可以抓包外,还提供了可视化分析网络包的图形页面。
本次例子,我们将要访问的 http://192.168.3.200 服务端。在终端一用 tcpdump 命令抓取数据包:
接着,在终端二执行下面的 curl 命令:
最后,回到终端一,按下 Ctrl+C 停止 tcpdump,并把得到的 http.pcap 取出到电脑。
使用 Wireshark 打开 http.pcap 后,你就可以在 Wireshark 中,看到如下的界面:
因为服务器端收到客户端的
FIN
后,服务器端同时也要关闭连接,这样就可以把
ACK
和
FIN
合并到一起发送,节省了一个包,变成了“三次挥手”。
而通常情况下,服务器端收到客户端的
FIN
后,很可能还没发送完数据,所以就会先回复客户端一个
ACK
包,稍等一会儿,完成所有数据包的发送后,才会发送
FIN
包,这也就是四次挥手了。
如下图,就是四次挥手的过程:
TCP三次握手异常情况分析
-
TCP 第一次握手的 SYN 丢包了,会发生了什么?
-
TCP 第二次握手的 SYN、ACK 丢包了,会发生什么?
-
TCP 第三次握手的 ACK 包丢了,会发生什么?
丢包重传,那么问题又来了
- 那会重传几次?
- 超时重传的时间 RTO 会如何变化?
- 在 Linux 下如何设置重传次数?
TCP第一次握手SYN丢包
从上图可以发现, 客户端发起了 SYN 包后,一直没有收到服务端的 ACK ,所以一直超时重传了 5 次,并且每次 RTO 超时时间是不同的:
- 第一次是在 1 秒超时重传
- 第二次是在 3 秒超时重传
- 第三次是在 7 秒超时重传
- 第四次是在 15 秒超时重传
- 第五次是在 31 秒超时重传
可以发现,每次超时时间 RTO 是
指数(翻倍)上涨的
,当超过最大重传次数后,客户端不再发送 SYN 包。
在Linux中,第一次握手的SYN超时重传次数,是如下内核参数指定的
$ cat /proc/sys/net/ipv4/tcp_syn_retries
5
tcp_syn_retries
默认值为 5,也就是 SYN 最大重传次数是 5 次。
当客户端发起的 TCP 第一次握手 SYN 包,在超时时间内没收到服务端的 ACK,就会在超时重传 SYN 数据包,每次超时重传的 RTO 是翻倍上涨的,直到 SYN 包的重传次数到达
tcp_syn_retries
值后,客户端不再发送 SYN 包。
TCP第二次握手SYN、ACK丢包
- 客户端发起 SYN 后,由于防火墙屏蔽了服务端的所有数据包,所以 curl 是无法收到服务端的 SYN、ACK 包,当发生超时后,就会重传 SYN 包
-
服务端收到客户的 SYN 包后,就会回 SYN、ACK 包,但是客户端一直没有回 ACK,服务端在超时后,重传了 SYN、ACK 包,
接着一会,客户端超时重传的 SYN 包又抵达了服务端,服务端收到后,超时定时器就重新计时,然后回了 SYN、ACK 包,所以相当于服务端的超时定时器只触发了一次,又被重置了。
- 最后,客户端 SYN 超时重传次数达到了 5 次(tcp_syn_retries 默认值 5 次),就不再继续发送 SYN 包了。
所以,我们可以发现,
当第二次握手的 SYN、ACK 丢包时,客户端会超时重发 SYN 包,服务端也会超时重传 SYN、ACK 包。
当 TCP 第二次握手 SYN、ACK 包丢了后,客户端 SYN 包会发生超时重传,服务端 SYN、ACK 也会发生超时重传。
客户端 SYN 包超时重传的最大次数,是由 tcp_syn_retries 决定的,默认值是 5 次;服务端 SYN、ACK 包时重传的最大次数,是由 tcp_synack_retries 决定的,默认值是 5 次。
TCP第三次握手ACK丢包
-
客户端发送 SYN 包给服务端,服务端收到后,回了个 SYN、ACK 包给客户端,此时服务端的 TCP 连接处于
SYN_RECV
状态; -
客户端收到服务端的 SYN、ACK 包后,给服务端回了个 ACK 包,此时客户端的 TCP 连接处于
ESTABLISHED
状态; -
由于服务端配置了防火墙,屏蔽了客户端的 ACK 包,所以服务端一直处于
SYN_RECV
状态,没有进入
ESTABLISHED
状态,tcpdump 之所以能抓到客户端的 ACK 包,是因为数据包进入系统的顺序是先进入 tcpudmp,后经过 iptables; -
接着,服务端超时重传了 SYN、ACK 包,重传了 5 次后,也就是
超过 tcp_synack_retries 的值(默认值是 5),然后就没有继续重传了,此时服务端的 TCP 连接主动中止了,所以刚才处于 SYN_RECV 状态的 TCP 连接断开了
,而客户端依然处于
ESTABLISHED
状态; -
虽然服务端 TCP 断开了,但过了一段时间,发现客户端依然处于
ESTABLISHED
状态,于是就在客户端的 telnet 会话输入了 123456 字符; -
此时由于服务端已经断开连接,
客户端发送的数据报文,一直在超时重传,每一次重传,RTO 的值是指数增长的,所以持续了好长一段时间,客户端的 telnet 才报错退出了,此时共重传了 15 次。
-
服务端在重传 SYN、ACK 包时,超过了最大重传次数
tcp_synack_retries
,于是服务端的 TCP 连接主动断开了。
-
客户端向服务端发送数据包时,由于服务端的 TCP 连接已经退出了,所以数据包一直在超时重传,共重传了 15 次, telnet 就 断开了连接。
TCP 建立连接后的数据包传输,最大超时重传次数是由
tcp_retries2
指定,默认值是 15 次,如下:
$ cat /proc/sys/net/ipv4/tcp_retries2
15
总结:
在建立 TCP 连接时,如果第三次握手的 ACK,服务端无法收到,则服务端就会短暂处于
SYN_RECV
状态,而客户端会处于
ESTABLISHED
状态。
由于服务端一直收不到 TCP 第三次握手的 ACK,则会一直重传 SYN、ACK 包,直到重传次数超过
tcp_synack_retries
值(默认值 5 次)后,服务端就会断开 TCP 连接。
而客户端则会有两种情况:
-
如果客户端没发送数据包,一直处于
ESTABLISHED
状态,然后经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接,于是客户端连接就会断开连接。 -
如果客户端发送了数据包,一直没有收到服务端对该数据包的确认报文,则会一直重传该数据包,直到重传次数超过
tcp_retries2
值(默认值 15 次)后,客户端就会断开 TCP 连接。
服务器出现大量close-wait
close_wait状态是在TCP四次挥手的时候收到FIN但是没有发送自己的FIN时出现的,服务器出现大量close_wait状态的原因有两种:
服务器内部业务处理占用了过多时间,都没能处理完业务;或者还有数据需要发送;或者服务器的业务逻辑有问题,没有执行close()方法
服务器的父进程派生出子进程,子进程继承了socket,收到FIN的时候子进程处理但父进程没有处理该信号,导致socket的引用不为0无法回收
处理方法:停止应用程序 修改程序里的bug
出现大量TIME_WAIT
这种情况比较常见,一些爬虫服务器或者WEB服务器(如果网管在安装的时候没有做内核参数优化的话)上经常会遇到这个问题,这个问题是怎么产生的呢?
TIME_WAIT是主动关闭连接的一方保持的状态,对于爬虫服务器来说他本身就是“客户端”,在完成一个爬取任务之后,他就 会发起主动关闭连接,从而进入TIME_WAIT的状态,然后在保持这个状态2MSL)
时间之后,彻底关闭回收资源。
现在来说如何来解决这个问题。
解决思路很简单,就是让服务器能够快速回收和重用那些
TIME_WAIT
的资源。
TCP重复确认和快速重传
当接收方收到乱序数据包时,会发送重复的 ACK,以使告知发送方要重发该数据包,
当发送方收到 3 个重复 ACK 时,就会触发快速重传,立该重发丢失数据包。
以上案例在 TCP 三次握手时协商开启了
选择性确认 SACK
,因此一旦数据包丢失并收到重复 ACK ,即使在丢失数据包之后还成功接收了其他数据包,也只需要重传丢失的数据包。如果不启用 SACK,就必须重传丢失包之后的每个数据包。
TCP流量控制
TCP 为了防止发送方无脑的发送数据,导致接收方缓冲区被填满,所以就有了滑动窗口的机制,它可利用接收方的接收窗口来控制发送方要发送的数据量,也就是流量控制。
接收窗口是由接收方指定的值,存储在 TCP 头部中,它可以告诉发送方自己的 TCP 缓冲空间区大小,这个缓冲区是给应用程序读取数据的空间:
- 如果应用程序读取了缓冲区的数据,那么缓冲空间区的就会把被读取的数据移除
- 如果应用程序没有读取数据,则数据会一直滞留在缓冲区。
接收窗口的大小,是在 TCP 三次握手中协商好的,后续数据传输时,接收方发送确认应答 ACK 报文时,会携带当前的接收窗口的大小,以此来告知发送方。
TCP如何保证可靠性
TCP保证可靠性:
(1)序列号、确认应答、超时重传
数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明了它下一次需要接收的数据序列号。如果发送发迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值。
(2)窗口控制与高速重发控制/快速重传(重复确认应答)
TCP会利用窗口控制来提高传输速度,意思是在一个窗口大小内,不用一定要等到应答才能发送下一段数据,窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制,每一个没收到确认应答的数据都要重发。
TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视 频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道使用窗口控制,如果数据段1001-2000丢失,后面数据每次传输,确认应答都会不停地发送序号为1001
的应答,表示我要接收1001开始的数据,发送端如果收到3次相同应答,就会立刻进行重发;但还有种情况有可能是数据都收到了,但是有的应答丢失了,这种情况不会进行重发,因为发送端知道,如果是数据段丢失,接收端不会放过它的,会疯狂向它提醒…
(3)拥塞控制
如果把窗口定的很大,发送端连续发送大量的数据,可能会造成网络的拥堵(大家都在用网,你在这狂发,吞吐量就那么大,当然会堵),甚至造成网络的瘫痪。所以TCP在为了防止这种情况而进行了拥塞控制。
慢启动:定义拥塞窗口,一开始将该窗口大小设为1,之后每次收到确认应答(经过一个rtt),将拥塞窗口大小*2。
拥塞避免:设置慢启动阈值,一般开始都设为65536。拥塞避免是指当拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是加法增加(每次确认应答/每个rtt,拥塞窗口大小+1),以此来避免拥塞。
将报文段的超时重传看做拥塞,则一旦发生超时重传,我们需要先将阈值设为当前窗口大小的一半,并且将窗口大小设为初值1,然后重新进入慢启动过程。
快速重传:在遇到3次重复确认应答(高速重发控制)时,代表收到了3个报文段,但是这之前的1个段丢失了,便对它进行立即重传。然后,先将阈值设为当前窗口大小的一半,然后将拥塞窗口大小设为慢启动阈值+3的大小。
这样可以达到:在TCP通信时,网络吞吐量呈现逐渐的上升,并且随着拥堵来降低吞吐量,再进入慢慢上升的过程,网络不会轻易的发生瘫痪。
TCP拥塞控制算法
防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载,拥塞控制自然也是控制发送者的流量,拥塞控制有四种算法,
慢启动、拥塞避免,快速重传和快速恢复
发送方维持一个拥塞窗口 cwnd ( congestion window )的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口和接受窗口的较小值。
(1)
慢启动
。慢启动算法的思路是当主机开始发送数据时,先以比较小的拥塞窗口进行发送,然后每次翻倍,也就是说,由小到大逐渐增加拥塞窗口的大小,而这个大小是指数增长的,即1、2、4、8、16。为了防止拥塞窗口cwnd增长过大引起网络拥塞,还要另外设置一个慢启动阈值ssthresh状态变量,当拥塞窗口的大小超过慢启动阈值的时候( cwnd > ssthresh 时),停止使用慢开始算法而改用拥塞避免算法
(2)
拥塞避免
。拥塞避免算法的思路是让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。
(3)
快速重传
。当发送端连续收到三个重复的ack时,表示该数据段已经丢失,需要重发。此时慢启动阈值ssth变为原来一半,拥塞窗口cwnd变为ssth+3,然后+1+1的发(每一轮rtt+1)
(4)
快速恢复
。当超过设定的时间没有收到某个报文段的ack时,表示网络拥塞,慢启动阈值ssth变为原来一半,拥塞窗口cwnd=1,进入慢启动阶段
TCP粘包问题和解决办法
粘包问题的最本质原因在与接收对等方无法分辨消息与消息之间的边界在哪。我们通过使用某种方案给出边界,例如:
发送定长包。如果每个消息的大小都是一样的,那么在接收对等方只要累计接收数据,直到数据等于一个定长的数值就将它作为一个消息。
包尾加上\r\n标记。FTP协议正是这么做的。但问题在于如果数据正文中也含有\r\n,则会误判为消息的边界。
包头加上包体长度。包头是定长的4个字节,说明了包体的长度。接收对等方先接收包体长度,依据包体长度来接收包体。
使用更加复杂的应用层协议。
TCP和UDP的区别
TCP的优点: 可靠,稳定 TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源。
TCP的缺点: 慢,效率低,占用系统资源高,易被攻击 TCP在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
UDP的优点: 快,比TCP稍安全 UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以它在传递数据时非常快。没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些。但UDP也是无法避免攻击的,比如:UDP Flood攻击……
UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会很容易丢包。 基于上面的优缺点,那么: 什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。 在日常生活中,常见使用TCP协议的应用如下: 浏览器,用的HTTPFlashFXP,用的FTP Outlook,用的POP、SMTP Putty,用的Telnet、SSH QQ文件传输 ………… 什么时候应该使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。 比如,日常生活中,常见使用UDP协议的应用如下: QQ语音 QQ视频 TFTP ……
TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的 UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视 频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
TCP/IP四层模型
应用层:
决定这次通信的应用类型,比如说FTP、DNS、SMTP
等等,同时HTTP协议也属于应用层的范围。通俗来讲,应用层决定这一次通信要干嘛。
传输层:
传输层提供两台计算机之间的数据传输,传输层中包含着两个很常用的协议,分别是TCP和UDP协议。
网络层:
网络层则是用来处理这些流动的数据包,也就是如果把相应的数据包路由到指定的地点,为通信时的网络传输选择传输路线
数据链路层:
数据链路层包含了软件与硬件的接口部分,以及各种网络设备的硬件,也就是整个网络通信过程中最底层的基础设施
4、HTTP
特点:
-
支持客户/服务器模式。
-
简单快速:客户向服务器请求专服务时,只属需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
-
灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
-
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
-
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
GET和POST的区别
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST没有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。
但是以上都不是主要区别。主要区别如下:对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200ok(返回数据)。
-
GET与POST都有自己的语义,不能随便混用。
-
据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
-
并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
HTTP与HTTPS协议
1)HTTP协议是以明文的方式在网络中传输数据,而HTTPS协议传输的数据则是经过TLS加密后的,HTTPS具有更高的安全性
2)HTTPS在TCP三次握手阶段之后,还需要进行SSL 的handshake,协商加密使用的对称加密密钥
3)HTTPS协议需要服务端申请证书,浏览器端安装对应的根证书
4)HTTP协议端口是80,HTTPS协议端口是443
HTTP状态码
- 1—–消息
- 2—–成功
- 3——重定向
- 4——请求错误
- 5——服务器错误
100 – 继续发送
200 – 请求成功
301 – 资源(网页等)被永久转移到其它URL
404 – 请求的资源(网页等)不存在500 – 内部服务器错误
400 – 请求无效
403 – 禁止访问
HTTP1.0,1.1,1.2的区别
1 HTTP1.0和HTTP1.1的区别
1.1 长连接(Persistent Connection)
HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。
1.2 节约带宽
HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。
1.3 HOST域 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。
1.4缓存处理
在HTTP1.0中主要使用header里的If-Modifified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodifified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
1.5错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,如409(Conflflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
2 HTTP1.1和HTTP2.0的区别
2.1 多路复用
HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
2.2 头部数据压缩
在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。
HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
2.3 服务器推送
服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。
为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。
5、HTTPS协议加密过程
SSL
是传输层的协议
https包括非对称加密和对称加密两个阶段,在客户端与服务器建立连接的时候使用非对称加密,连接
建立以后使用的是对称加密。
-
客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接
-
Web服务器收到客户端请求后,会将网站的公钥传送一份给客户端,私钥自己保存。
-
客户端的浏览器根据双方同意的安全等级,生成对称加密使用的密钥,称为会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站
-
Web服务器利用自己的私钥解密出会话密钥。
-
Web服务器利用会话密钥加密与客户端之间的通信,这个过程是对称加密的过程。服务器第一次传给客户端的公钥其实是CA对网站信息进行加密的数字证书
客户端的对称加密密钥其实是三个随机数的哈希(1. 客户端第一次给服务端发送请求时附带的随机数 2.服务器返回时的随机数 3. 客户端收到返回时的随机数)
6、单播、多播、广播
单播特点:一个单个的发送者和一个接受者之间通过网络进行的通信。
1、服务器及时响应客户机的请求
2、服务器针对每个客户不同的请求发送不同的数据,容易实现个性化服务。
多播特点:一个发送者和多个接受者之间的通信。
广播特点:主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要)。
1、网络设备简单,维护简单,布网成本低廉。
2、由于服务器不用向每个客户机单独发送数据,所以服务器流量负载极低。
7、DOS攻击与DDOS
1.DOS攻击
利用服务器的连接缓冲区,利用特殊的程序,设置TCP的Header,向服务器端不断地成倍发送只有SYN标志的TCP连接请求。当服务器接收的时候,都认为是没有建立起来的连接请求,于是为这些请求建立会话,排到缓冲区队列中。如果SYN请求超过了服务器能容纳的限度,缓冲区队列满,那么服务器就不再接收新的请求了。其他合法用户的连接都被拒绝掉。
这种攻击利用RST位来实现。假设现在有一个合法用户(1.1.1.1)已经同服务器建立了正常的连接,攻击者构造攻击的TCP数据,伪装自己的IP为1.1.1.1,并向服务器发送一个带有RST位的TCP数据段。服务器接收到这样的数据后,认为从1.1.1.1发送的连接有错误,就会清空缓冲区中建立好的连接。这时,如果合法用户1.1.1.1再发送合法数据,服务器就已经没有这样的连接了,该用户就必须从新开始建立连接。攻击时,伪造大量的IP地址,向目标发送RST数据,使服务器不对合法用户服务
如果你的连接带宽足够大而服务器又不是很大,你可以发送请求,来消耗服务器的缓冲区消耗服务器的带宽。
单一的DoS攻击一般是采用一对一方式的,当攻击目标CPU速度低、内存小或者网络带宽小等等各项性能指标不高它的效果是明显的。
DDOS攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DoS攻击,从而成倍地提高拒绝服务攻击的威力。
- IP Flood:此攻击以多个随机的源主机地址向目的主机发送超大量的随机或特定的IP包,造成目标主机不能处理其他正常的IP报文。
-
ICMP Flood:也就是 ping flflood,此攻击
在短时间内向目的主机发送大量的****ping的echo报文
,主机不断响应,造成网络堵塞、主机资源耗尽。** -
Syn Flood:依据
tcp建立连接的三次握手
。此攻击以多个随机的源主机地址
向目的主机发送syn包**,而在
收到目的主机的syn+ack包后并不回应
,**目的主机就为这些源主机建立大量的连接队列,由于没有收到ack一直维护这些连接队列,造成资源的大量消耗而不能向正常的请求提供服务。与之类似的攻击方式还有ackflflood、s-ack-flflood、fifin-flflood、rst-flflood、tcp-flflood - UDP Flood:此攻击在短时间内 模拟随机的源端口地址向随机的目的端口发送大量的udp包,造成目标主机不能处理其他udp的请求
解决DDOS攻击
- 采用高性能的网络设备
- 尽量避免NAT的使用
- 充足的网络带宽保证
- 防护墙代理Syn
- 升级主机服务器硬件
- 把网站做成静态页面
8、Session和cookie的区别
cookie 和session 的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
cookie 和session 的联系:
session是通过cookie来工作的
session和cookie之间是通过
C
O
O
K
I
E
[
′
P
H
P
S
E
S
S
I
D
′
]
来
联
系
的
,
通
过
_COOKIE[‘PHPSESSID’]来联系的,通过
C
O
O
K
I
E
[
′
P
H
P
S
E
S
S
I
D
′
]
来
联
系
的
,
通
过
_COOKIE[‘PHPSESSID’]可以知道session的id,从而获取到其他的信息。
在购物网站中通常将用户加入购物车的商品联通session_id记录到数据库中,当用户再次访问是,通过sessionid就可以查找到用户上次加入购物车的商品。因为sessionid是唯一的,记录到数据库中就可以根据这个查找了。
9、Java BIO与NIO的对比
BIO(传统IO):
BIO是一个同步并阻塞的IO模式,
传统的 java.io 包
,它基于流模型实现,提供了我们最熟知的一些 IO 功能,比如
File抽象、输入输出流
等。
交互方式是同步、阻塞的方式
,也就是说,在读取输入流或者写入输出流时,在读、写动作完成之前,线程会一直阻塞在那里,它们之间的调用是可靠的线性顺序。
NIO(Non-blocking/New I/O)
NIO 是一种同步非阻塞的 I/O 模型,于 Java 1.4 中引入,对应 java.nio 包,提供了 Channel , Selector,Buffer 等抽象。NIO 中的 N 可以理解为 Non-blocking,不单纯是 New。它支持面向缓冲的,基于通道的 I/O 操作方法。NIO 提供了与传统 BIO 模型中的
Socket
和
ServerSocket
相对应的
SocketChannel
和
ServerSocketChannel
两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发
IO模型 | BIO | NIO |
---|---|---|
通信 | 面向流 | 面向缓冲 |
处理 | 阻塞 IO | 非阻塞 IO |
触发 | 无 | 选择器 |
阻塞(Block)与非阻塞(Non-Block)
阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候。
阻塞
:往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否则一直等待在那里。
非阻塞
:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经准备好,也直接返回。
同步(Synchronous)与异步(Asynchronous)
同步和异步都是基于应用程序和操作系统处理 IO 事件所采用的方式。比如
**同步:**是应用程序要直接参与 IO 读写的操作。
**异步:**所有的 IO 读写交给操作系统去处理,应用程序只需要等待通知。
同步方式在处理 IO 事件的时候,必须阻塞在某个方法上面等待我们的 IO 事件完成(阻塞 IO 事件或者通过轮询 IO事件的方式),对于异步来说,所有的 IO 读写都交给了操作系统。这个时候,我们可以去做其他的事情,并不需要去完成真正的 IO 操作,当操作完成 IO 后,会给我们的应用程序一个通知。
所以异步相比较于同步带来的直接好处就是在我们处理IO数据的时候,异步的方式我们可以把这部分等待所消耗的资源用于处理其他事务,提升我们服务自身的性能。
10、Reactor模型
单线程的 Reactor 模型
多线程的 Reactor 模型
多线程主从 Reactor 模型
11、Netty
Netty 是一个 NIO 客户端服务器框架,可快速轻松地开发网络应用程序,例如协议服务器和客户端。它极大地简化和简化了网络编程,例如 TCP 和 UDP 套接字服务器。
“快速简便”并不意味着最终的应用程序将遭受可维护性或性能问题的困扰。Netty 经过精心设计,结合了许多协议(例如FTP,SMTP,HTTP 以及各种基于二进制和文本的旧式协议)的实施经验。结果,Netty 成功地找到了一种无需妥协即可轻松实现开发,性能,稳定性和灵活性的方法。
Netty核心组件
Channel
Channel是 Java NIO 的一个基本构造。可以看作是传入或传出数据的载体。因此,它可以被打开或关闭,连接或者断开连接。
EventLoop 与 EventLoopGroup
EventLoop 定义了Netty的核心抽象,用来处理连接的生命周期中所发生的事件,在内部,将会为每个Channel分配一个EventLoop。
EventLoopGroup 是一个 EventLoop 池,包含很多的 EventLoop。
Netty 为每个 Channel 分配了一个 EventLoop,用于处理用户连接请求、对用户请求的处理等所有事件。EventLoop 本身只是一个线程驱动,在其生命周期内只会绑定一个线程,让该线程处理一个 Channel 的所有 IO 事件。
一个 Channel 一旦与一个 EventLoop 相绑定,那么在 Channel 的整个生命周期内是不能改变的。一个 EventLoop 可以与多个 Channel 绑定。即 Channel 与 EventLoop 的关系是 n:1,而 EventLoop 与线程的关系是 1:1。
ServerBootstrap 与 Bootstrap
Bootstarp 和 ServerBootstrap 被称为引导类,指对应用程序进行配置,并使他运行起来的过程。Netty处理引导的方式是使你的应用程序和网络层相隔离。
Bootstrap 是客户端的引导类,Bootstrap 在调用 bind()(连接UDP)和 connect()(连接TCP)方法时,会新创建一个 Channel,仅创建一个单独的、没有父 Channel 的 Channel 来实现所有的网络交换。
ServerBootstrap 是服务端的引导类,ServerBootstarp 在调用 bind() 方法时会创建一个 ServerChannel 来接受来自客户端的连接,并且该 ServerChannel 管理了多个子 Channel 用于同客户端之间的通信。
ChannelHandler 与 ChannelPipeline
ChannelHandler 是对 Channel 中数据的处理器,这些处理器可以是系统本身定义好的编解码器,也可以是用户自定义的。这些处理器会被统一添加到一个 ChannelPipeline 的对象中,然后按照添加的顺序对 Channel 中的数据进行依次处理。
ChannelFuture
Netty 中所有的 I/O 操作都是异步的,即操作不会立即得到返回结果,所以 Netty 中定义了一个 ChannelFuture 对象作为这个异步操作的“代言人”,表示异步操作本身。如果想获取到该异步操作的返回值,可以通过该异步操作对象的addListener() 方法为该异步操作添加监 NIO 网络编程框架 Netty 听器,为其注册回调:当结果出来后马上调用执行。
Netty 的异步编程模型都是建立在 Future 与回调概念之上的。