面试总结3——计算机网络

主要参考于这个博主https://blog.csdn.net/justloveyou_的一些文章,并根据自己的面试经验做了相关的补充。

层次结构

计算机网络的体系结构:

1,OSI七层:结构清楚,理论完整,复杂不实用,层次划分不合理,功能重复出现。

  • 应用层:应用进程之间相互通信和交互,DNS、HTTP、FTP、SMTP,交互的数据称为报文
  • 表示层:信息的加密,解密,压缩,解压缩等。
  • 会话层:不同机器上的用户之间建立和管理会话。
  • 运输层:为两台主机的进程之间的通信提供通用的数据传输服务。一台主机可以运行多个线程,所以具有复用和分用的功能。复用指的是多个应用层进程可以同时使用下面运输层的服务,分用指的是运输层把收到的信息分别交付给应用层中相应的进程。主要用TCP和UDP两种协议。
  • 网络层:负责为分组交换网上的不同主机提供通信服务。把运输层产生的报文或者数据报封装成分组和包进行传送。交互的数据称为IP数据报。另一个任务就是选择合适的路由。
  • 数据链路层:两台主机之间的数据传输。将网络层交下来的IP数据报组装成帧,在两个相邻节点的链路上传送帧。每一帧包括数据和必要的控制信息(同步信息,地址信息,差错控制等),数据链路层可以检错还可以纠错。
  • 物理层:传送的数据单位为比特,实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。

2,TCP/IP四层:

  • 应用层:
  • 运输层:
  • 网络层:
  • 网络接口层

3, 五层:OSI和TCP/IP折中,简介又将概念阐述清楚。

  • 应用层:
  • 运输层:
  • 网络层:
  • 数据链路层:
  • 物理层:

不同层次涉及到的设备:

  1. 物理层:网卡,网线,集线器,中继器,调制解调器
  2. 数据链路层:网桥、交换机
  3. 网络层:路由器
  4. 传输层及以上:网关

路由器:连通不同的网络,选择信息传送的线路。

交换机:进行报文交换的机器,可以进行地址学习,采用存储转发的形式来交换报文。

集线器:采用广播的形式来传输信息。

 

交换机和路由器的区别:

  1. 工作层次不同: 数据链路层、网络层
  2. 数据转发对象不同:根据MAC地址转发数据帧、根据IP地址转发IP数据包/分组。MAC地址固化在网卡的ROM中,不能被修改,IP地址描述主机所在的网络。可以修改。
  3. 分工不同:交换机用来连接局域网中的电脑,组建局域网(不能访问外网),路由器负责让主机连接外网,连接不同的网络。
  4. 冲突域和广播域:交换机分割冲突域,不分割广播域,路由器分割广播域。
  5. 路由器一般具有防火墙的功能,能够对一些网络数据包选择性过滤。

 

集线器与交换机的区别:

  1. 工作层次:物理层;数据链路层
  2. 宽带影响:共享;独享
  3. 数据传输:广播发送(局域网内所有电脑都可以接收到消息);有目的的发送(MAC地址)
  4. 传输模式:半双工;全双工或半双工;

应用层

HTTP协议

超文本传输协议,所有的www文件都必须遵守这个标准。

Http和Https的区别

  1. 应用层、传输层
  2. 不安全(明文传输,无法验证相互的身份)、安全(SSL(安全套接层)+HTTP,增加了加密和认证机制的http)
  3. 端口号:80、443
  4. 不需要申请证书,需要申请证书
  5. 资源开销小、由于加密需要消耗更多的资源

HTTPS认证过程

有单向验证和双向验证之分

单向验证就是server端将证书发送给客户端,客户端验证server端证书的合法性等,例如百度、新浪、google等普通的https网站,

双向验证则是不仅客户端会验证server端的合法性,同时server端也会验证客户端的合法性,例如银行网银登陆,支付宝登陆交易等。

SSL缺省只进行server端的认证,客户端的认证是可选的。

 

  1. 服务器把自己的公钥登录至数字证书认证机构。
  2. 数字证书机构把自己的私有密钥向服务器的公开密码部署数字签名并颁发公钥证书。
  3. 客户端拿到服务器的公钥证书后,使用数字证书认证机构的公开密钥,向数字证书认证机构验证公钥证书上的数字签名。以确认服务器公钥的真实性。
  4. 客户端将自己的对称加密的密钥用服务器的公钥加密以后传给服务器,。
  5. 服务器用私有密钥对报文解密,得到对称密钥,进行数据传送。

面试总结3——计算机网络_第1张图片

Https应用场景

银行网站、支付网关、购物网站、登录页、电子邮件以及一些企业部门的网站应该使用 HTTPS。

影响 HTTP 网络请求的因素

1,带宽:

如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。

2,延迟:

网络波动和延迟

DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。

浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。

服务器本身的原因:跨域服务,服务器超负荷,配置过低等。

建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。

 

如何网络诊断:

Ping:查看连通性

Traceroute:用于检查您本地设备发送数据包到远程服务器所经过所有网关的地址及时间。 使用这个命令,可以检查访问服务器是因为哪里的网关速度慢而影响了访问速度。

http和https的端口号是否可以修改,怎么修改?

可以修改。

http通过Apache安装目录下的httped.conf文件,将listen后面的80改为想要的端口号;

https通过Apache安装目录下的httped-ssl.conf文件,将所有的443改为你想设置的端口号;

最后重启Apache。

对称加密和非对称加密

对称加密是指加密和解密使用同一个密钥,问题:如何将密钥安全的发送给对方。

非对称加密:加密用公钥,解密用私钥。问题:效率慢。

解决方法:还是用对称加密发送文件,但是使用非对称加密发送对称加密的密钥。

Get与POST的区别

两种http的方法。

  1. get从服务器获取资源;post更新服务器资源。
  2. get是幂等的,多次读取统一资源,得到相同的数据;post不是幂等的,会改变服务器资源。
  3. get请求的参数附在URL之后,即放在http报文的请求行中,以?分割URL和参数,参数之间用&相连,ascii编码;post请求把提交的数据放在http请求报文的请求体中,标准字符集编码。
  4. get提交的数据明文出现在url中,不安全,post包装在请求体中。
  5. get请求的长度受限于浏览器或服务器对于url长度的限制,post请求没有大小限制。

 

Get请求中为什么要URL编码:

Get请求中会对url中非西文字符进行编码,目的是避免歧义,比如参数中含有&时,误认为&为参数连接的标志。

 

Http的其他请求方法:

Get: 发送请求来获得服务器上的资源

Post: 向服务器提交资源让服务器处理

Head: 获取http的头信息,主要用来检查资源或超链接的有效性或是否可以可达、检查网页是否被串改或更新,获取头信息等

Put:和post类似,html表单不支持,发送资源与服务器,并存储在服务器指定位置,要求客户端事先知道该位置;

Delete:请求服务器删除某资源。

Connect:就是把服务器作为跳板,去访问其他网页,然后把数据返回回来,连接成功后,就可以正常的get、post了。

Options:获取http服务器支持的http请求方法,

Trace:回显服务器收到的请求,主要用于测试或诊断。

从输入网址到获得页面的过程,其中涉及到的协议

  1. 浏览器查询DNS,获取域名对应的IP地址。
  2. 浏览器向服务器请求建立连接,发起tcp三次握手
  3. 浏览器向服务器发送http请求
  4. 服务器接收并处理http请求,将结果返回给浏览器。
  5. 浏览器显示页面。

DNS,TCP,IP,OSPF,ARP,RARP,HTTP

常见状态码及原因短语:

1)1xx:请求处理中,请求已被接受,正在处理

2)2xx:请求被成功处理

         200:请求成功,一般用于get和post

         201:成功请求并创建了资源。

3)3xx:重定向

         301:永久性转移

         302:暂时性转移

         303:已缓存

4)4xx:客户端错误

         400:请求有语法错误

         401:需要验证用户

         403:拒绝请求,不允许访问

         404:页面不存在

5)5xx:服务器端错误

         500:服务器内部错误

         502:网关错误

         503:服务不可用

301和302的区别

重定向

就是地址A跳转到地址B啦。百度百科的解释:重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向、域名的重定向、路由选择的变化也是对数据报文经由路径的一种重定向)。

为什么要进行重定向啊?什么时候需要重定向呢?

1)网站调整(如改变网页目录结构);

2)网页被移到一个新地址;

3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。

 

使用301跳转的场景:

使用域名跳转。

1)域名到期不想续费(或者发现了更适合网站的域名),想换个域名。

2)在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。

3)空间服务器不稳定,换空间的时候。

使用302跳转的场景:

--尽量使用301跳转

 

为什么尽量要使用301跳转?

——URL劫持

搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B 上的内容,这种情况就叫做网址URL 劫持。

HTTP工作方式

请求/响应的工作方式

1

  • 请求报文:请求行,请求头,请求体
  • 请求行:请求方式+请求url+协议及版本号
  • 请求头:声明客户端、服务器报文的部分信息,采用header(字段名):value(值)的方法。
  • 请求体:存放需要发送的数据。

2

  • 响应报文:状态行、响应头、响应体
  • 状态行:状态码+原因短语+协议及版本号
  • 响应头:声明客户端、服务器报文的部分信息,采用header(字段名):value(值)的方法
  • 响应体:存放需要发送的数据。

HTTP1.1和HTTP1.0的区别

  1. 引入持久连接(长连接),同一个tcp连接中可以传送多个http请求&响应。
  2. 缓存处理:引入了更多可供选择的缓存头来控制缓存策略。
  3. 带宽优化及网络连接的使用:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分。
  4. 错误通知的管理,在HTTP1.1中新增了24个错误状态响应码。
  5. HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。

http2.0

SPDY是2012年谷歌推出的是基于SSL/TLS的传输协议,SPDY有降低延迟,多路复用,头部压缩,服务端推送等特点,这些特点也称为了后续HTTP2.0的功能基石,HTTP2.0是SPDY/3 draft的优化版。

  1. HTTP/1.x是基于文本解析的,HTTP/2.0是基于二进制解析的
  2. HTTP/2.0采用多路复用,一个域一个tcp连接,很好的解决了浏览器限制同一个域名下的请求数量的问题
  3. HTTP/2.0采用Header压缩,HTTP/1.x的header携带大量信息且重复,HTTP/2.0的通信双方各执一份header fields缓存,减少了传输大小与重复header的传输
  4. HTTP/2.0支持服务端推送,减少了请求次数。
  5. 请求优先级:服务器可以根据流的优先级,控制资源分配(CPU、内存、带宽),而在响应数据准备好之后,优先将最高优先级的帧发送给客户端。

HTTP/2的多路复用和HTTP1.1中的长连接复用有什么区别?

  1. HTTP/1.0 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接;    、HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;  
  2. HTTP/2多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;

DNS

域名系统,将域名和IP地址相互映射的一个分布式数据库。

工作原理:浏览器搜索自身的DNS缓存、向本地域名服务器发起查询(UDP);本地域名服务器查询自身资源缓存(有则将解析结果返回),没有则进行迭代或者递归;

  1. 递归:本地DNS代表客户机向其他DNS服务器发起请求。
  2. 迭代:本地DSN向根DNS发送请求,根DNS返回一个所查域的主DNS的地址,本地DNS向返回的主DNS发送请求,若有则返回结果,若没有则返回下一级域名服务器地址,重复这个过程知道找到相关记录。

本地DNS将结果保存到缓存,并返回给客户机。

传输层

TCP和UDP的区别

  1. TCP:面向连接的;可靠的;面向字节流;有拥塞控制;只有点对点的通信链接;提供全双工通道;首部开销20字节。
  2. UDP:无连接;不可靠;面向报文的;没有拥塞控制(适合实时应用);支持一对一,一对多,多对一,多对多的交互通信;首部开销少(8字节)。

TCP和UDP对应的应用层协议:

1,TCP对应:

FTP:文件传输协议,端口号21;下载文件,上传主页;

Talnet:远程登录协议,端口号23;

SMTP:简单邮件传输协议,端口号25;发送邮件;

POP3:用于接收邮件,端口号110;可以不以Web方式登陆进邮箱界面,直接用邮件程序就可以收到邮件;

HTTP:超文本传输协议,端口号80;从Web服务器传输超文本到本地浏览器的传送协议。

2,UDP对应:

DNS:域名解析,端口号53;域名转为IP地址;

TFTP:简单文件传输协议,端口号69;

SNMP:简单网络管理协议,端口号161;管理网络设备;

TCP三次握手

  1. 客户端将SYN置为1,随机产生一个seq=i,并将数据包发送给服务器,客户端进入SYN_SENT状态,等待服务器确认。
  2. 服务器收到数据包后,由SYN为1知道客户端请求建立连接,将SYN和ACK置为1,ack=i+1,随机产生seq=j,并将数据包发送给客户端以确认连接请求。服务器进入SYN_RCVD状态。
  3. 客户端收到确认后,检查ack是否为i+1,ACK是否为1,如果正确将ACK=1,ack置为j+1,并将数据包发送给服务器,服务器检查ack是否为j+1,ACK=1,如果正确则连接建立成功,双方进入ESTABLISHED状态,完成三次握手。

为什么三次握手?

防止失效的连接请求报文又传到了服务器端,因而产生错误,浪费服务器资源。

为什么要随机产生初始序列号?

如果不是随机产生初始序列号,黑客将会以很容易的方式获取到你与其他主机之间通信的初始化序列号,并且伪造序列号进行攻击,这已经成为一种很常见的网络攻击手段。

TCP四次挥手

  1. 客户端将FIN置为1,发送给服务器,用来关闭客户端到服务器的数据传送,客户端进入FIN_WAIT1状态。
  2. 服务器收到FIN之后,发送一个ACK给客户端,确认序号为收到序号+1,服务器进入CLOSE_WAIT状态,此时TCP连接处于半关闭状态,即客户端没有要发送的数据了,但是仍然可以接受服务器端的数据。
  3. 当服务器也没有要发送的数据时,向客户端发送一个FIN,用来关闭服务器到客户端的数据传送,服务器进入LAST_ACK状态。
  4. 客户端收到FIN之后,进入TIME_WAIT状态,发送一个ACK给客户端,确认序号为收到序号+1,服务器进入CLOSE状态,完成四次挥手。

TIME_WAIT为什么要等待2MSL时间((即两倍的分段最大生存期))?

1)可靠的终止TCP连接(防止客户端发送的确认报文服务端没有收到,服务端会重发fin报文,因此客户端需要停留在某个状态以处理重复收到的结束报文段)。

2)保证让迟来的TCP报文段有足够的时间被识别并丢弃,不会影响其他连接。2MSL时间的TIME_WAIT状态能够确保网络上两个传输方向上尚未被接收到的、迟到的TCP报文段都已经消失(被中转路由丢弃)。

MSL:报文最大生存时间

 

TCP连接中出现RST的情况

RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的。发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。

  1. 端口未打开:服务器程序端口未打开而客户端来连接。服务器程序core dump之后重启之前连续出现RST的情况。
  2. 端口不存在:若端口不存,则直接返回RST,同时RST报文接收通告窗口大小为0.。
  3. 请求超时:建立连接过程中,一端认为接收超时,即使受到了想要的数据,也会发送RST拒绝进一步发送数据。
  4. 提前关闭:
  5. 在一个已关闭的socket上收到数据:
  6. 异常终止连接:一方直接发送RST报文,表示异常终止连接。一旦发送方发送复位报文段,发送端所有排队等待发送的数据都被丢弃。
  7. 处理半打开连接:A关闭了连接,B却没有收到结束报文(如网络故障),此时B还维持着原来的连接。A重启之后收到了B发送的报文,则回应RST复位报文。

RST攻击

A和服务器B之间建立了TCP连接,此时C伪造成A将一个TCP包发给B,B将会丢弃与A的缓冲区上所有数据,强制关掉连接,就是RST攻击了。

发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。

 

伪造什么样的TCP包可以达成目的呢?

  1. 这个包如果是RST包的话,毫无疑问,B将会丢弃与A的缓冲区上所有数据,强制关掉连接。
  2. 如果发过去的包是SYN包,那么,B会表示A已经发疯了(与OS的实现有关),正常连接时又来建新连接,B主动向A发个RST包,并在自己这端强制关掉连接。

 

怎么伪造成A发给B的包?

这里有两个关键因素,源端口和序列号。

一个TCP连接都是四元组,由源IP、源端口、目标IP、目标端口唯一确定一个连接。所以,如果C要伪造A发给B的包,要在上面提到的IP头和TCP头,把源IP、源端口、目标IP、目标端口都填对。

  1. 这里B作为服务器,IP和端口是公开的,A是我们要下手的目标,IP当然知道,但A的源端口就不清楚了,因为这可能是A随机生成的。当然,如果能够对常见的OSwindowslinux找出生成source port规律的话,还是可以搞定的。
  2. 序列号问题是与滑动窗口对应的,伪造的TCP包里需要填序列号,如果序列号的值不在A之前向B发送时B的滑动窗口内,B是会主动丢弃的。所以我们要找到能落到当时的AB间滑动窗口的序列号。这个可以暴力解决,因为一个sequence长度是32位,取值范围0-4294967296,如果窗口大小像上图中我抓到的windows下的65535的话,只需要相除,就知道最多只需要发655374294967296/65535=65537)个包就能有一个序列号落到滑动窗口内。RST包是很小的,IP头+TCP头也才40字节,算算我们的带宽就知道这实在只需要几秒钟就能搞定。

 

那么,序列号不是问题,源端口会麻烦点,如果各个操作系统不能完全随机的生成源端口,或者黑客们能通过其他方式获取到source portRST攻击易如反掌,后果很严重。

 

大量TIMEWAIT的解决方法

TIME_WAIT状态可以通过优化服务器参数得到解决,因为发生TIME_WAIT的情况是服务器自己可控的,要么就是对方连接的异常,要么就是自己没有迅速回收资源,总之不是由于自己程序错误导致的。

CLOSEWAIT原因和解决

当客户端因为某种原因先于服务端发出了FIN信号,就会导致服务端被动关闭,若服务端不主动关闭socket发FIN给Client,此时服务端Socket会处于CLOSE_WAIT状态(而不是LAST_ACK状态)。

  1. 通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(系统默认超时时间的是7200秒,也就是2小时)。如果服务端程序因某个原因导致系统造成一堆CLOSE_WAIT消耗资源,那么通常是等不到释放那一刻,系统就已崩溃。因此,解决这个问题的方法还可以通过修改TCP/IP的参数来缩短这个时间,于是修改tcp_keepalive_*系列参数。
  2. 给每一个socket设置一个时间戳last_update,每接收或者是发送成功数据,就用当前时间更新这个时间戳。定期检查所有的时间戳,如果时间戳与当前时间差值超过一定的阈值,就关闭这个socket。

TCP状态详解

面试总结3——计算机网络_第2张图片

可以用 netstat -nat命令查看tcp各个状态的数量,哪个端口被占用、套接字的状态、接收缓冲区和发送缓冲区中的数据个数、IP、还有程序名字。

客户端的状态可以用如下的流程来表示:

CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

服务器的状态可以用如下的流程来表示:

CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED

NOTE

(1)主动端出现大量的FIN_WAIT1时需要注意网络是否畅通、出现大量的FIN_WAIT2需要仔细检查程序为何迟迟收不到对端的FIN(可能是主动方或者被动方的bug)、出现大量的TIME_WAIT需要注意系统的并发量/socket句柄资源/内存使用/端口号资源等。

(2)被动端出现大量的 CLOSE_WAIT 需要仔细检查为何自己迟迟不愿调用close关闭连接(可能是bug,socket打开用完没有关闭)

 

1,LISTENING:侦听来自远方的TCP端口的连接请求. 首先服务端需要打开一个socket进行监听,状态为LISTEN。TCP状态变化就是某个端口的状态变化,提供一个服务就打开一个端口。关闭不必要的端口是保证安全的一个非常重要的方面(DDoS攻击)。处于侦听LISTENING状态时,该端口是开放的,等待连接,但还没有被连接。

连接:

2,SYN_SENT(客户端):客户端通过应用程序connect()连接时,客户端tcp发送一个SYN以请求建立一个连接,之后状态置为SYN_SENT。正常情况下SYN_SENT状态非常短暂。

如果发现有很多SYN_SENT出现,那一般有这么几种情况:

一是你要访问的网站不存在或线路不好,

二是用扫描软件扫描一个网段的机器,也会出现很多SYN_SENT,

三是可能中了病毒了,例如中了"冲击波",病毒发作时会扫描其它机器(扫描过程发出了同步请求),这样会有很多SYN_SENT出现。

3,SYN_RECEIVED(服务端):当服务器收到客户端发送的同步信号时,将标志位ACK和SYN置1发送给客户端,此时服务器端处SYN_RCVD状态,如果连接成功了就变为ESTABLISHED,正常情况下SYN_RCVD状态非常短暂。

如果发现有很多SYN_RCVD状态,那你的机器有可能被SYN Flood的DoS(拒绝服务攻击)攻击了。这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout。

4,ESTABLISHED:代表一个打开的连接。

服务器出现很多ESTABLISHED状态:当客户端未主动close的时候就断开连接(没有正常进行四次挥手断开连接),若客户端断开的时候发送了FIN包,则服务端将会处于CLOSE_WAIT状态,若断开的时候未发送FIN包,则服务端处还是显示ESTABLISHED状态。当客户端重新连接服务器的时候,服务端肯定是ESTABLISHED状态,如果客户端重复上演这种情况,那么服务端将会出现大量的假的ESTABLISHED连接和CLOSE_WAIT连接。最终结果就是新的其他客户端无法连接上来,但是利用netstat还是能看到一条连接已经建立。

断开

5,FIN-WAIT-1:主动关闭(active close)端应用程序调用close(),于是其TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状。等待远程TCP的连接中断请求,或先前的连接中断请求的确认。

如果服务器(作为主动关闭方?)出现shutdown再重启,使用netstat -nat查看,就会看到很多FIN-WAIT-1的状态。就是因为服务器当前有很多客户端连接,直接关闭服务器后,无法接收到客户端的ACK。

6,CLOSE-WAIT被动关闭(passive close)端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT。

大量closewait的原因:代码层面上未对连接进行关闭,比如关闭代码未写在 finally 块关闭,如果程序中发生异常就会跳过关闭代码;程序响应过慢,比如双方进行通讯,当客户端请求服务端迟迟得不到响应,就断开连接,重新发起请求,导致服务端一直忙于业务处理,没空去关闭连接。这种情况也会导致这个问题;

7,FIN-WAIT-2主动关闭端接到ACK后,就进入了FIN-WAIT-2。这就是著名的半关闭的状态了,这是在关闭连接时,客户端和服务器两次握手之后的状态。在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,而直到应用层来决定关闭这个状态。

8,LAST-ACK被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接。这导致它的TCP也发送一个 FIN,等待对方的ACK.就进入了LAST-ACK。

使用并发压力测试的时候,突然断开压力测试客户端,服务器会看到很多LAST-ACK。

9,TIME-WAIT在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态。等待足够的时间以确保远程TCP接收到连接中断请求的确认。

这个状态是防止最后一次握手的数据报没有传送到对方那里而准备的(注意这不是四次握手,这是第四次握手的保险状态)。这个状态在很大程度上保证了双方都可以正常结束,但是,问题也来了。

由于插口的2MSL状态(插口是IP和端口对的意思,socket),使得应用程序在2MSL时间内是无法再次使用同一个插口的,对于客户程序还好一些,但是对于服务程序,例如httpd,它总是要使用同一个端口来进行服务,而在2MSL时间内,启动httpd就会出现错误(插口被使用)。为了避免这个错误,服务器给出了一个平静时间的概念,这是说在2MSL时间内,虽然可以重新启动服务器,但是这个服务器还是要平静的等待2MSL时间的过去才能进行下一次连接。

10,CLOSED没有任何连接状态

11,CLOSING状态:一般较少出现,这种是客户端和服务端同时发起了FIN主动关闭。如客户端发送FIN主动关闭,但是没有收到服务端发来的ACK确认,而是先收到了服务端发来的FIN关闭连接,所以必须是同时。

在进入CLOSING状态后,只要收到了对方对自己发送的FIN的ACK,收到FIN的ACK确认就进入TIME_WAIT状态,因此,如果RTT(Round Trip Time TCP包的往返延时)处在一个可接受的范围内,发出的FIN会很快被ACK从而进入到TIME_WAIT状态,CLOSING状态持续的时间就特别短,因此很难看到这种状态

TCP通信中服务器处理中一端意外断开

客户端或者服务器并没有正常关闭socket,双方并未按照协议上的四次挥手去断开连接。这时候正在执行Recv或Send操作的一方就会因为没有任何连接中断的通知而一直等待下去,也就是会被长时间卡住。像这种如果一方已经关闭或异常终止连接,而另一方却不知道,我们将这样的TCP连接称为半打开的。

解决意外中断办法都是利用保活机制。而保活机制分又可以让底层实现也可自己实现。

1,编写心跳包程序:一般由客户端发送心跳包,服务端并不回应心跳,只是定时轮询判断一下与上次的时间间隔是否超时(超时时间自己设定)。服务器并不主动发送是不想增添服务器的通信量,减少压力。但这会出现三种情况:

情况1:客户端由于某种网络延迟等原因很久后才发送心跳(它并没有断),这时服务器若利用自身设定的超时判断其已经断开,而后去关闭socket。

情况2:客户端很久没传心跳,确实是自身断掉了。在其重启之前,服务端已经判断出其超时,并主动close,则四次挥手成功交互。

情况3:客户端很久没传心跳,确实是自身断掉了。在其重启之前,服务端的轮询还未判断出其超时,在未主动close的时候该客户端已经重新连接。这时候若客户端断开的时候发送了FIN包,则服务端将会处于CLOSE_WAIT状态;这时候若客户端断开的时候未发送FIN包,则服务端处还是显示ESTABLISHED状态;而新连接上来的客户端(也就是刚才断掉的重新连上来了)在服务端肯定是ESTABLISHED;这时候就有个问题,若利用轮询还未检测出上条旧连接已经超时(这很正常,timer总有个间隔吧),而在这时,客户端又重复的上演情况3,那么服务端将会出现大量的假的ESTABLISHED连接和CLOSE_WAIT连接。

2,启动TCP编程里的keepAlive机制:keepalive的原理就是TCP内嵌的一个心跳包。以服务器端为例,如果当前server端检测到超过一定时间(默认是 7,200,000 milliseconds,也就是2个小时)没有数据传输,那么会向client端发送一个keep-alive packet(该keep-alive packet就是ACK和当前TCP序列号减一的组合),此时client端应该为以下三种情况之一:

情况1:client端仍然存在,网络连接状况良好。此时client端会返回一个ACK。server端接收到ACK后重置计时器(复位存活定时器),在2小时后再发送探测。如果2小时内连接上有数据传输,那么在该时间基础上向后推延2个小时。(对于应用程序来说,2小时的空闲时间太长。因此,我们需要手工开启Keepalive功能并设置合理的Keepalive参数。)

情况2:客户端异常关闭,或是网络断开。在这两种情况下,client端都不会响应。服务器没有收到对其发出探测的响应,并且在一定时间(系统默认为1000 ms)后重复发送keep-alive packet,并且重复发送一定次数(2000 XP 2003 系统默认为5次

情况3:客户端曾经崩溃,但已经重启。这种情况下,服务器将会收到对其存活探测的响应,但该响应是一个复位,从而引起服务器对连接的终止。

TCP如何保证传输的可靠性

  1. 数据报校验:出错丢失
  2. 对失序数据包进行重排序:TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序
  3. 丢失重复数据:
  4. 应答机制:对收到的数据包进行确认
  5. 超时重发:定时器:所以TCP需要不断地采样RTT,还要根据RTT的波动范围,做加权平均算出一个值来。由于重传时间是不断变化的,称为自适应重传算法。
  6. 流量控制:每一方都有一定大小的缓冲区间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据(与拥塞控制的区别!)

TCP的应答机制

  1. 为了保证顺序性,每个包都有一个ID。在建立连接的时候,商定起始的ID。然后按照ID一个一个发送。
  2. 收到包的一端需要对包做应答,一旦应答一个ID,就表明之前的ID都收到了,这个模式称为累计确认或者累计应答。
  3. 为了记录发送和接收的包,TCP在发送端和接收端都缓存记录

TCP的重发机制

接收端收到1,2,3,4,5,7,8,接收端只会ack5,这是,发送端怎么发送数据?

  1. 快重传:把6之后的全部重发一遍。
  2. SACK(Selctive Acknowledgment):在TCP头里加一个SACK的东西,将缓存地图放进去,比如还是7丢了,可以地图是ACK6,SACK8,SACK9。发送方收到后,立马能看出是7丢了。Linux下面可以通过tcp_ack参数打开这个功能。这里还是有一个问题,就是SACK不是最终保证,就是说接收端在发送SACK后是可以把数据再丢了的。虽然这么做不鼓励,但是不排除极端情况,比如内存不够了。所以发送端不能想当然的再也不发SACK的那些包了,还是要看这些包有没有正式的ACK才能最终确认。
  3. D-SACK(Duplicate SACK): D-SACK的作用是接收端告诉发送端包发重了。比如ACK 6丢了,那么发送端会重发,接收端发现收到两个6,现在我都要ACK 8了,则回复ACK 8,SACK 6。

客户端不断进行请求链接会怎样?DDos攻击/SYN Flood攻击

服务器为每个请求建立连接,并发送确认报文,等待客户端进行确认。即DDos攻击。

预防(没有彻底根治的方法):

  1. 限制同时打开SYN半连接的数目。
  2. 缩短SYN半连接的Time out时间。
  3. 关闭不必要的服务。

TCP的拥塞处理

防止过多的数据注入网络,使网络中的路由器或链路不致过载。

  1. 慢开始:不要一开始就发送大量的数据,从1开始指数增加。
  2. 拥塞避免:达到拥塞门限之后,线性增加。

 

  1. 快重传:接收端收到一个失序报文时立即发出重复确认,而不是不等下一次发送消息是附带确认,发送端连续收到三个重复确认时立即重发,不等计时器时间到期。
  2. 快恢复:拥塞门限设为此时拥塞窗口的一半(乘法减小),并且拥塞窗口从拥塞门限开始增加在(加法增加)。(此时还可以收到确认报文,即网络没有出现拥塞,不必从慢开始开始)。

https://img-blog.csdn.net/20180420160407836

Tcp的粘包

TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

 

为什么会出现粘包?

发送方原因:启用Nagle算法(可配置是否启用)对较小的数据包进行合并。

接受方原因:TCP将收到的分组保存至接收缓存里,然后应用程序主动从缓存里读收到的分组。

 

如何处理粘包现象 :

对于发送方造成的粘包现象,我们可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭Nagle算法。

TCP并没有处理接收方粘包现象的机制,我们只能在应用层进行处理。

应用层的处理:循环处理

TCP的报文格式

面试总结3——计算机网络_第3张图片

1、端口号:用来标识同一台计算机的不同的应用进程。

1)源端口:源端口和IP地址的作用是标识报文的返回地址。

2)目的端口:端口指明接收方计算机上的应用程序接口。

TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。

2、序号和确认号:序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。确认号,即ack,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。

3、数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。

4、保留:为将来定义新的用途保留,现在一般置0。

5、控制位:URG  ACK  PSH  RST  SYN  FIN,共6个,每一个标志位表示一个控制功能。

1)URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。

2)ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。

3)PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。

4)RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。

5)SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。

6)FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。

6、窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。

7、校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。

8、紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。

9、选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。

10、数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。

网络层

Ip协议的特点

无连接、不可靠、点对点

路由选择协议

  1. RIP:基于跳数,仅于相邻的路由器交换状态;
  2. OSPF:基于链路状态,向本自治系统所有的路由器发送信息;发送本路由器周边的网络拓扑;

ARP协议工作原理

网络层的ARP协议完成了IP地址与物理地址的映射。

首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址:如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。

ICMP

网际控制协议,分为差错报告报文和查询报文;存储转发IP数据报,提高成功交付的机会;ICMP 协议用于在IP 主机、路由器之间传递控制消息;ICMP 报文是放在 IP 数据报中的数据区域发送的。

应用:

  1. Ping:测试两台主机之间的连通性。工作原理:给目标ip发送一个icmp数据包,对方就要返回一个同样大小的数据包。根据时间和成功响应的次数估算丢失数据包率和网络时延。Ping命令不一定一定能判断对方是否存在:不存在或者不回答ping命令。
  2. Traceroute(Linux、macOS)/Trace(Windows):跟踪一个分组从源点到终点的路径。

首先发送一个TTL为1的ICMP请求回显数据包,在第一跳的时候超时并返回一个ICMP超时数据包,得到第一跳的地址。以此增加TTL的数值,直到到达目标主机,目标主机返回一个ICMP回显应答,traceroute结束。

TTL(time-to-live)是IP数据包中的一个字段,它指定了数据包最多能经过几次路由器。从我们源主机发出去的数据包在到达目的主机的路上要经过许多个路由器的转发,在发送数据包的时候源主机会设置一个TTL的值,每经过一个路由器TTL就会被减去一,当TTL为0的时候该数据包会被直接丢弃(不再继续转发),并发送一个超时ICMP报文给源主机。

IGMP

Internet 组管理协议,运行在主机和组播路由器之间。

IP地址的分类

A类地址:1字节的网络地址+3字节的主机地址 00

B类地址:2字节的网络地址+2字节的主机地址 10

C类地址:3字节的网络地址+2字节的主机地址 110

D类地址:多播地址  1110

E类地址:保留地址  1111

数据链路层

物理层

其他:

NAT(网络地址转换)实现方式

NAT网络地址转换(Network Address Translation)属接入广域网(WAN)技术,是一种将私有(保留)地址转化为合法IP地址的转换技术。

工作在网络层但是要结合传输层共同来实现。

  1. 静态NAT(一对一):将特定的公网地址和端口一对一的映射到特定的私网地址和端口,且每个私网地址都是确定的。
  2. 动态地址NAT(多对一):将内部地址与公网地址一对一的转换,但是动态地址是从合法的地址池中动态的选择未使用的公网地址,是随机的;当用户断开连接后,再次连接,可能外部地址就会切换成了另一个
  3. 端口多路复用地址转换(PAT):这也算是一种动态的,将多个内部地址转换为同一个公网地址,用不同的端口来区别不同的主机,可以分为圆锥型NAT和对称性NAT。

 

作用:

  1. 解决了IP地址不足的问题
  2. 不仅实现了地址转换,还起着防火墙的作用,隐藏内部网络的拓扑结构,有限避免网络外部的攻击。

Sql注入

把sql命令插入到web表单提交或者页面请求的查询字符串,最终达到欺骗服务器执行恶意sql命令的目的。

应对方法:

  1. 参数绑定:目前许多的ORM框架和JDBC等都实现了SQL的预编译和参数绑定功能。恶意sql只会被当作sql的参数而不是sql命令执行。
  2. 使用正则表达式过滤传入的参数。

Xss攻击

恶意攻击者利用网站没有对用户提交的数据进行转义或者过滤不足的缺点,添加一些脚本代码嵌入到web页面当中去,使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料等。

解决方法:

不信任任何客户端提交的数据,都应先进行过滤处理在进行下一步操作。

Session、Cookie

客户端和服务器保持状态的解决方案,

  1. Session:在服务器端保持状态。客户端请求服务器,如果服务器需要记录该用户的状态,就获取Session来保持状态,首先服务器为浏览器创建一个session,并将sessionid返回给客户端保存,可以保存在cookie里,浏览器再次请求的时候,服务器按照sessionid把session检索出来使用。若浏览器禁用cookie,可以通过url重写机制将sessionid传回服务器。
  2. Cookie:在客户端保持状态。实际为一小段的文本信息,客户端请求服务器,如果服务器需要记录该用户的状态,就是用response向客户端浏览器颁发一个Cookie,客户端浏览器把Cookie保存下来,下次请求该网站时,把请求的网址和Cookie一同提交给服务器,服务器检查Cookie,以此来辨认用户状态,也可以根据需要修改Cookie内容。

 

Cookie里面存放的内容:

用户名,密码,访问过的网址,sessionid

 

区别:

  1. 实现机制:session的实现依赖于cookie,通过cookie传回sessionid
  2. 大小限制:cookie有大小限制,而且浏览器对每个站点也有cookie个数限制,session没有大小限制,理论上只与服务器内存大些有关。
  3. 安全性:Cookie存在安全隐患,session相对更安全。
  4. 服务器资源消耗:session过多会增加服务器压力。

URL重写机制(URL重写是支持会话的非常健壮的方法)

如果浏览器不支持Cookie或用户阻止了所有Cookie,可以把会话ID附加在HTML页面中所有的URL上,这些页面作为响应发送给客户。这样,当用户单击URL时,会话ID被自动作为请求行的一部分而不是作为头行发送回服务器。这种方法称为URL重写(URL rewriting)。

 

URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程。

 

举个例子来说,如果通过浏览器进来的URL是“UserProfile.aspx?ID=1”那么它可以被重写成 “UserProfile/1.aspx”,这样的URL,这样的网址可以更好的被网站所阅读。

 

一般来说,URL重写是支持会话的非常健壮的方法。在不能确定浏览器是否支持Cookie的情况下应该使用这种方法。

你可能感兴趣的:(面试,网络,局域网)