JAVA计算机网络面试题

OSI七层与TCP/IP五层区别

 

在表示上,TCP/IP的五层中,将应用层包含了OSI中的应用层、表示层和会话层。

OSI(开放式系统互联)模型是一个参考标准,它具有通用性。而TCP/IP参考模型是先有的协议再建立的模型,适用于如今大部分的TCP/IP网络

各层工作

  • 应用层,直接为应用程序提供服务,常见的协议有HTTP、FTP、SMTP等。

  • 传输层,主要是负责提供端到端的稳定传输(UDP是个例外),协议TCP、UDP。

  • 网络层,提供对目标IP的解析,判断是不是同一子网,确定下一跳发送是网关转发还是局域网内广播。

  • 数据链路层,负责MAC地址相关,接收到的广播包通过MAC地址判断是否为本机的,和ARP协议寻找目标机器的MAC地址;还有个就是针对物理层传输的电信号解码封装成帧,对帧的校验。

  • 物理层,传输的物理介质

一个数据包的发送流程(TCP/IP模型)

  1. 应用层准备好待发送的数据。如果目的地址是域名则需要先通过DNS获得IP地址。

  2. 交付到运输层处理,进行适当分组,对每个分组加上TCP头(包含源地址、源端口、目的地址、目的端口等)

  3. 交付到网络层处理,根据IP协议进行寻址(根据子网掩码判断目标IP是否在同一子网内,还是需要交付给路由转发),添加IP头(包含源地址端口,目的端口这里是下一跳的转发地址等)

     

  4. 交付到数据链路层,通过ARP协议包获取目标mac地址,添加报头,把数据封装成帧(首位部添加标志用于帧定界)

  5. 交付到物理层,传输。

  6. 如果在同一网段则直接传输给指定机器,否则的话发送给网关,路由根据路由表层层寻址,直到目标机器

  7. 目标机器接收到数据后,在数据链路层解帧,并对数据进行CRC校验(帧尾部存有计算结果,本机计算后和结果对比即可),有错的会被丢弃。

  8. 交付给网络层。网络层解帧校验目标IP端口与本机是否相符,以及上层是否有声明的套接字(IP:端口)可以处理。错误丢弃

  9. 交付给传输层,根据端口找到对应的程序,传输给程序进行下一步处理

TCP

总体认知

  • TCP是传输层协议,基于TCP实现的应用层协议有HTTP、SMTP、FTP等

  • 可以提供端到端的稳定传输,它是通过三次握手、四次挥手建立的稳定连接。

  • 通过滑动窗口协议按组发送数据,提高发送效率。

  • 通过校验位、确认应答机制、超时重传、流量控制、拥塞控制这些机制确保数据的传输无误。

     

报头结构

 

结构用途
序号序号是本报文段发送的数据组的第一个字节的序号。(e.g.一个报文段序号为300,长度为100字节,则下一报文段序号为400)
确认号指明下一个期望接收到的第一个数据字节的序号,表名该序号之前的都准确接收到了。当前报文段最后一个字节编号+1即为确认号。
控制位URG(紧急指针标志),ACK(确认序号标志),PSH(push标志,接收方应尽快交给应用程序而不是在缓冲区排队),RST(重置连接标志,重置主机崩溃或其他原因造成的错误,或拒绝非法报文段和拒绝连接请求),SYN(同步序号),FIN(终止连接标志)。
数据偏移TCP数据报,首部包含可选内容,所以长度不固定,数据偏移存了报头的长度,用于计算数据部分的起始位置。
窗口用于告知发送端接收端的缓存大小,以此控制发送端发送的速率
校验和对整个TCP报文段计算所得的校验值,由接收端验证是否接收正确。

三次握手

 

第一次握手:A向B发送TCP数据报SYN标志位为1,seq = x,并进入SYN-SENT状态。等待B确认。

第二次握手:B收到syn包,回复给A一个TCP包标志位SYN和ACK都为1,seq = y,ack = x + 1,B进入SYN-RCVD(半连接)状态。

第三次握手:A收到二次的包后,返回ACK标志位为1,seq = x + 1,ack = y + 1的包,A进入ESTAB-LISHED(全连接)状态,B收到后也进入全连接状态。

为什么不能用两次握手?

假设只有两次握手,第二次握手的数据包在发送给A时因为网络原因丢失了,而B认为已经建立了连接从而开始发送数据,而A仍然在等待确认应答包,从而丢弃B发送的数据分组,而B认为发送的分组丢失了又不断的重发,形成了死循环。

如果建立了长连接后客户端出现了故障怎么办

TCP在操作系统的实现中有一个保活计时器,服务端每收到客户端的请求后都会复位计时器,默认是2小时,若空闲超过2小时,则会发送探测报文,反应正常则复位计时器;若无应答,则每隔75秒发送一次重复发送10次后关闭连接;若对方重启了则会直接返回标志位RST为1的拒绝连接,收到后也会关闭连接。

syn flood洪水攻击

原理:

通过伪造IP向服务器发送大量SYN数据包,服务器在收到后会返回ACK,因为是伪造的IP,因此不会回应第三个ACK,那么服务器将会有大量的半连接状态请求,从而塞满半连接队列,或者耗尽资源。

如何防御?

修改二次握手重试的次数加快半连接的回收,增大半连接队列。

linux中默认使用syn cookie机制,在收到首次握手的SYN包后立即回复,并不放入半连接队列中,从而破解了普通的洪水攻击。但是仍然会导致其他问题。

四次挥手

 

第一次挥手:客户端停止发送数据,发出FIN报文,seq = u,客户端进入FIN-WAIT-1状态。

第二次挥手:服务器接收到FIN报文后,回复ACK报文,seq = v,ack = u + 1,进入CLOSE-WAIT状态,但是可能仍在发送数据。客户端收到后进入FIN-WAIT2(只收不发)状态

第三次挥手:在服务器发送完数据后,向客户端发出FIN=1,ACK=1,seq = w,ack = u + 1释放报文,服务器进入LAST-ACK状态

第四次挥手:客户端收到释放报文后,回复ACK报文,同时进入TIME-WAIT状态等待2MSL(最长报文寿命)。服务端收到后进入CLOSE

为什么关闭的时候是四次挥手?

因为TCP是全双工的,客户端发起关闭后服务端可能还没发送完数据,如果是三次挥手,那么可能会出现客户端收到服务端回复的ACK后就不再接收数据了,那么服务端就会出现丢包,客户端接收的数据也不完整。

为什么客户端TIME_WAIT状态要持续2MSL?

2MSL是两个最大报文生存时间,也就是报文一来一回的时间,如果来2MSL内没有再收到服务端发送过来的FIN报文,说明服务端收到了最后的ACK,如果收到了说明上一个ACK丢失了那么再重发即可。

出现大量TIME-WAIT的场景以及解决

场景:

通常出现在服务端,高并发下短连接请求较多,断开后都进入了TIME-WAIT状态。它会占有用一定的内存,文件描述符等资源。

解决:

修改配置开启TIME-WAIT socket重用策略,当同一个客户端再次发起请求时可以重用;修改配置开启TIME-WAIT socket快速回收,根据网络情况降低等待时间。

TCP如何保证可靠传输?

校验和

发送方发送前计算校验和,并放在TCP报头的校验位。

接收方收到后也会计算校验和然后与校验位比较,判断收到的数据报是否正确。

确认应答机制

TCP通过返回ACK包确认接收到的数据,ACK包中带有确认号,告诉发送方下一段数据应该从哪里开始发。

超时重传

由确认应答机制可知,接收方在接收到一组数据后会回复一个确认包,如果迟迟没有收到确认,可能是如下两个原因:

  1. 发送的数据全部丢失,接收方压根没收到。

  2. 接收方收到了,但是回复的ACK丢包了。

TCP由此引入了超时重传的机制,发送方在发送完毕后会等待一段时间,如果没有收到确认应答,会将刚刚发送的数据重新发送一遍。接收方收到后如果是情况1就正常返回一个ACK;如果是情况2那么会丢弃新收到的数据包,仍旧回复一个ACK。

在Linux中,超时等待是500ms为一个单位,每次判断重发超时都是500ms的整数倍,重发一个无响应,等待2 * 500ms,再重传等待4 * 500,以此类推,到达一定次数后,TCP会认为出现异常,强制关闭连接。

连接管理

三次握手,四次挥手,确保建立稳定连接

流量控制

接收端处理数据的速度是有限的,如果发送方发送过快,会导致接收端的缓冲区被填满,此时再收到发送方的数据就会丢包。

因此,加入了流量控制机制,在TCP报头中有一个16位的窗口长度,当接收端收到发送方的数据后,会在ACK的窗口中放入缓冲区的剩余大小,接收方根据窗口值决定发送的速度。如果缓冲区满了。就将窗口值设置为0,发送方就不再发送数据了,而是定期发送窗口探测报文,等待缓冲区释放后继续发送。

拥塞控制

拥塞控制是防止过多的数据注入网络中,导致网络中的路由器或者链路过载,从而造成的网络拥塞。拥塞控制是动态的过程,它根据网络情况动态调整。

拥塞控制解决方式:慢启动、拥塞避免、快重传、快恢复

拥塞窗口cwnd:发送方维护cwnd变量,该变量的大小取决于网络的拥塞程度,并且动态的在变化,窗口越大每次发送的数据越多,同时也会受到流量控制的限制。

慢启动: 在刚开始发送数据时,先发送少量的数据包探测网络状态,如果顺畅会指数增长cwnd的值,增大到一定阈值(ssthresh)后开始拥塞避免。

拥塞避免: cwnd到达阈值(ssthresh)后,进入拥塞避免,此时不再是指数增长了,而是替换成加法增长,每次只常数的增加。

如果在慢启动或者拥塞避免阶段遇到了网络拥塞(没收到ACK),就会把ssthresh设定为出现拥塞时窗口大小的一半,并进入慢开始算法。

 

快重传:TCP可能会因为等待重传而耗费较多的时间,快重传机制要求接受放接收到一个失序的报文段时就立马返回正确接受的最后一个分组的ACK,那么发送端就会立即重发。

 

如图,接受端收到了M1,M2,M4,M5,发现缺失了M3,则立即返回M2的ACK,那么发送方就会重发从M3开始从分组。而不必等待这段分组的重传计时器超时。

快恢复: 如果发送端连续收到3个相同的ACK,这种情况可能是报文丢失了,此时执行快恢复算法,将ssthresh设置为cwnd的一半,并开始拥塞避免算法。

滑动窗口机制

为了充分利用带宽,TCP在发送时每次是按分组发送,这个分组的大小由窗口的值确定

窗口的值由接收方的缓冲区大小和拥塞控制窗口的大小共同决定。

接收方可以使用累计确认,对按序到达的最后一个分组发送确认,表名这一个分组都已经正确收到了。如果中间少了,就变得无序,就会触发快重传机制。

在收到确认后,窗口就会向后滑动。

服务器最多可以有多少个TCP连接

理论上TCP连接是由一个四元组来唯一标识一个TCP连接{local ip, local port,remote ip,remote port},所以按照理论来看可以有2 ^ 32(ip数) * 2 ^ 16(端口数) = 2 ^ 48次方个连接。

但是实际上还会被硬件所限制,TCP全连接队列的长度,当无限来说,那么就考验内存的大小了,内存够大以后,还有系统文件描述符数量的限制(每个socket就是一个文件描述符),还有每个进程能够操作的文件描述符个数的限制,这些都是可以通过改变配置来扩大。如果考虑处理的效率,还有C10K问题,需要IO多路复用来解决,CPU负载过大。

粘包/半包

概念

粘包: 多个数据包合并在一起

半包: 只读到部分数据包

粘包发生的原因

发生在发送端:

在TCP连接没断开的情况下,可以持续不断的发送多个数据包给接收端,如果发送的数据包很小,TCP本身会使用优化算法Nagle对较小的数据包进行合并,然后发送。

解决很简单,关闭Nagle算法即可。

发生在接收端:

接收端收到数据报后放在缓冲区中,如果没有及时读取,可能下次读取时会出现一次取走多个数据包的情况。

半包发生的原因

接收端在接收时读取的长度不正确

如何解决?

发生在客户端的好解决,关闭使用Nagle算法。

实际的解决应该是在应用层:

  1. 基于消息边界的方式,在一个数据包的末尾加上特殊符号区分边界,得防止符号出现重复

  2. 基于固定长度读取的方式,发送端将每个数据包固定长度,不够的也许填满,接收端每次只需要按协商好的长度读取。可能浪费空间,不灵活。

  3. 基于消息头执行消息长度的方式,发送端在每个数据段首部添加长度,接收端通过读取包首部长度的字段就可以知道实际的长度了。增加一些CPU负担,但是灵活

UDP

头部结构/特点

 

  • UDP是无连接的

  • UDP不保证可靠传输,没有拥塞控制,确认应答等机制。

  • UDP支持一对一,一对多和多对多通信

  • UDP的头部开销小只有8字节

  • UDP是基于数据报的协议,一个UDP数据报为一个单位,它不会为应用层的数据分包,直接交给网络层IP协议发送。

TCP/UDP使用场景

  1. TCP主要用于实现可靠传输的情况,如文件传输,发送接收邮件,远程登录等。

  2. UDP用于高速传输和实时性较高但是正确性要求较低的场合,如网络电话,视频聊天,直播,出现丢包也只是短暂的卡顿

TCP协议: FTP,SMTP,HTTP,Telnet等

UDP协议: DNS,SNMP,TFTP等

如何保证UDP的可靠传输

只能在应用层由程序员自己实现,主要实现确认机制,重传机制。

 

HTTP

请求报文结构

 

 

请求头和请求数据之间由一个空行区分开

②请求URL:如果是Get请求参数都拼接在这

⑤请求体:如果是POST请求参数数据在这儿。

响应报文

 

GET和POST的区别

  1. 使用情景不同,规范中要求GET请求用于从服务器上获取资源,POST请求用于向服务器提交数据。

  2. GET方法传参是通过URL明文,用户可见的。POST是将数据封装到请求体重发送给服务器。

  3. GET通过URL传参,因此GET能传输的数据长度是有限的,POST更适合传输大量数据。

常见状态码

  • 1XX,表示请求已经被接受,但是仍然需要处理

  • 2XX,表示请求成功。

  • 3XX,表示客户端重定向,并告诉客户端重定向地址

  • 4XX,表示客户端请求错误。客户端可能发送了服务器无法处理的错误信息。

  • 5XX,表示服务器错误,客户端发送了有效请求,但是服务器无法处理。

状态码含义
200请求成功
302重定向
404请求资源不存在
400请求语法错误,服务器无法理解
403服务器收到请求,但是拒绝提供服务
500服务器内部错误
503服务器当前无法处理请求,需要等待一段时间后才能恢复

常见请求头

请求头含义
Host指定请求资源的主机名和端口号
User-Agent用户请求的代理软件,包含操作系统浏览器等属性
Referer代表当前访问的URL的上一个地址是什么,如请求该页面上的图片,则referer是该html所在地址
Cookie此域名对应的cookie
Accept浏览器可接受的数据类型

常见响应头

响应头含义
Server服务器使用的Web服务器名称
Set-Cookie向客户端设置的Cookie
Location配合302重定向使用,告诉客户端重定向的地址
Refresh告诉浏览器多长时间后刷新

HTTP请求的流程

  1. 浏览器首先需要解析域名,从本地获取,没有的话从操作系统获取,再到路由器,再没有就请求DNS服务器获取域名对应的IP。

  2. 获取到IP后发起TCP三次握手,OSI五层去走。

HTTP各个版本的区别与特性

HTTP1.0和1.1区别

  1. 1.0默认短连接,每个请求都需要一个独立的短连接,1.1版本默认使用长连接来降低传输 延迟,避免每次握手挥手的开销

  2. 节省带宽了。1.0的版本中是不支持断点续传的,例如浏览器只需要加载部分文档的内容,但是必须全部传输。在1.1中支持只请求某个资源的一部分,在响应头中声明了这部分对象的长度和偏移。

  3. 支持了多主机服务器。1.0版本中认为每个服务器对应有唯一的IP,随着虚拟主机技术的发展,一个IP可以对应多个主机,1.1版本中新加入了Host请求头,指定主机名,从而支持了虚拟主机技术。

HTTP1.1和2.0区别

  1. HTTP2.0支持了同一连接多路复用技术,可以做到一个连接并发异步处理多个请求(同一服务器)。而1.1的长连接是阻塞式的,所有请求串行发送,可能会受到某个慢请求影响所有。

  2. 头部数据压缩,原先是对请求体和响应体部分压缩,2.0多了对请求头的压缩,从而更加节省带宽

HTTPS

HTTP和HTTPS的区别

  • HTTP是明文传输的,HTTPS是加密传输的

  • HTTP默认使用80端口,HTTPS默认使用443端口

HTTPS工作原理/流程

  1. 首先客户端向服务端获取数字证书

  2. 客户端收到证书后验证域名对应证书的合法性,通过操作系统维护的CA机构的公钥,解密数字证书中服务端的公钥(服务端的公钥被CA机构使用私钥加密过)

  3. 客户端生成随机码,使用解密出的服务器公钥加密,并传给服务器

  4. 服务器使用私钥解密获得随机码,自此客户端与服务端的对称加密协商完毕

  5. 服务器和客户端使用这串随机码作为对称加密的秘钥加密内容传输

文章

[OSI七层大白话]  https://blog.csdn.net/taotongning/article/details/81352985 

 

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值