java面试之网络

Java面试之网络

什么是三次握手,四次挥手

三次握手

三次挥手是建立连接,是为了确保客户端和服务端的发送接收能力都OK

我: 喂 ,你好,能听到我说话吗?

领导: 可以的。

我:好的。

然后开始巴拉巴拉说事情。

这就是三次握手,确保了双方都可以发送和接收。

  1. 第一次握手:客户端发送一个网络包,服务端接收到网络包。说明客户端的发送能力和服务端的接收能力是OK的
  2. 第二次握手:服务端发送一个网络包给客户端,客户端完成接收。这时候客户端完成了一次发报文,并且得到的服务端的响应,那么能说明客户端这边没问题。但是呢客户端只接收了客户端的一次请求包智能说明自己接收能力OK,虽然也发送了一次网络包给客户端,但是这时候客户端还没给我回应所以这时候并不能保证服务端的发送能力是OK的,所以还要再来一次握手。
  3. 第三次握手:客户端收到服务端发来的网络包并给服务端一个回应。这时候服务端接收到消息后才能确定自己第二次挥手的时候发送过去的数据包有被接收到这时候他才能确定自己说我的发送能里很OK!

四次挥手

为什么需要握手三次就可以,挥手需要四次呢。因为握手没有数据传输,只是建立连接。而建立连接后就需要进行数据传输了,为了保证数据传输的完整性,则需要四次挥手。

第一次挥手: 客户端发送一个FIN报文说我要断开连接了。

第二次挥手:服务器收到以后可能数据还没有传输完,这时候会回复一个ACK确认报文。但是数据还没有传输完所以还需要等待数据传输结束。

第三次挥手: 服务器数据传输完发送一个FIN报文给客户端。告诉客户端已经传输完了。

第四次挥手:当客户端收到服务器发送的FIN报文后会发送一个ACK确认报文。当等待2MSL后关闭连接。

等待2MSL是确保服务端收到了客户端的ACK,如果服务端没有收到ACK的话,会继续发送FIN报文。

TCP和UDP的区别

tcp 和 udp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输,而 udp 则常被用于让广播和细节控制交给应用的通信传输。

两者的区别大致如下:

  • tcp 面向连接,udp 面向非连接即发送数据前不需要建立链接;
  • tcp 提供可靠的服务(数据传输),udp 无法保证;
  • tcp 面向字节流,udp 面向报文;
  • tcp 数据传输慢,udp 数据传输快;

http 响应码 301 和 302 代表的是什么?有什么区别?

301:永久重定向。

302:暂时重定向。

它们的区别是,301 对搜索引擎优化(SEO)更加有利;302 有被提示为网络拦截的风险。

forward 和 redirect 的区别?

forward 是转发 和 redirect 是重定向:

  • 地址栏 url 显示:foward url 不会发生改变,redirect url 会发生改变;
  • 数据共享:forward 可以共享 request 里的数据,redirect 不能共享;
  • 效率:forward 比 redirect 效率高。

说一下 tcp 粘包是怎么产生的?

什么是粘包

TCP是面向字节流的协议,就是没有界限的一串数据,本没有“包”的概念,“粘包”和“拆包”一说是为了有助于形象地理解这两种现象。

因为TCP是面向流,没有边界,而操作系统在发送TCP数据时,会通过缓冲区来进行优化,例如缓冲区为1024个字节大小。

如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题。

如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包。

tcp 粘包可能发生在发送端或者接收端,分别来看两端各种产生粘包的原因:

  • 发送端粘包:发送端需要等缓冲区满才发送出去,造成粘包;
  • 接收方粘包:接收方不及时接收缓冲区的包,造成多个包接收。

常见的解决方案

对于粘包和拆包问题,常见的解决方案有四种:

  • 发送端将每个包都封装成固定的长度,比如100字节大小。如果不足100字节可通过补0或空等进行填充到指定长度;
  • 发送端在每个包的末尾使用固定的分隔符,例如\r\n。如果发生拆包需等待多个包发送过来之后再找到其中的\r\n进行合并;例如,FTP协议;
  • 将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;
  • 通过自定义协议进行粘包和拆包的处理。

Netty对粘包和拆包问题的处理

Netty对解决粘包和拆包的方案做了抽象,提供了一些解码器(Decoder)来解决粘包和拆包的问题。如:

  • LineBasedFrameDecoder:以行为单位进行数据包的解码;
  • DelimiterBasedFrameDecoder:以特殊的符号作为分隔来进行数据包的解码;
  • FixedLengthFrameDecoder:以固定长度进行数据包的解码;
  • LenghtFieldBasedFrameDecode:适用于消息头包含消息长度的协议(最常用);

基于Netty进行网络读写的程序,可以直接使用这些Decoder来完成数据包的解码。对于高并发、大流量的系统来说,每个数据包都不应该传输多余的数据(所以补齐的方式不可取),LenghtFieldBasedFrameDecode更适合这样的场景。

OSI 的七层模型都有哪些?

  • 物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
  • 数据链路层:负责建立和管理节点间的链路。
  • 网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
  • 传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。
  • 会话层:向两个实体的表示层提供建立和使用连接的方法。
  • 表示层:处理用户信息的表示问题,如编码、数据格式转换和加密解密等。
  • 应用层:直接向用户提供服务,完成用户希望在网络上完成的各种工作。

get 和 post 请求有哪些区别?

  • get 请求会被浏览器主动缓存,而 post 不会。
  • get 传递参数有大小限制,而 post 没有。
  • post 参数传输更安全,get 的参数会明文限制在 url 上,post 不会。

如何实现跨域请求?

什么是跨域

一个URL由三部分组成:URL 协议 端口号。这三个只要有一个不同那么就属于是跨域。

跨域的产生原因

浏览器的同源策略限制。

同源策略(Same Orgin Policy)是一种约定,它是浏览器核心也最基本的安全功能,它会阻止一个域的js脚本和另外一个域的内容进行交互,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。
所谓同源(即在同一个域)就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。

解决方案

vue是如何解决的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//vue.config.js

module.exports = {
devServer: {
proxy: {
//配置跨域
'/api': {
target: 'http://x.x.x.x:x/', //这里填写项目真实的后台接口地址
changOrigin: true, //设置允许跨域
pathRewrite: {//这个重写不可省略!因为我们真正请求的地址并不含 /api
'^/api': ''
/* 当我们在浏览器中看到请求的地址为:http://localhost:8080/api/data/getdata 时
因为重写了 /api ,所以实际上访问的地址是:http://x.x.x.x:x/data/getdata,
*/
}
}
}
}
}

在vue项目中配置proxy解决跨域问题的原理是:将域名发送给本地的服务器(启动vue项目的服务,localhost:8080),再由本地的服务器去请求真正的服务器。

nginx反向代理解决跨域(前端常用)

  • 正向代理:

    a–>b访问不了,可以找个中间的服务器c, 先访问c再从c到b,类似曲线救国。
    明确访问的目的地,但是用户不知道中间的代理服务器。(忽略中间服务器)

  • 反向代理

    a明确访问c代理服务器,但是不知道c的内容从哪里来,c反向从别的地方拿来数据。(忽略的是目标地址)

    浏览器可以访问a,而服务器之间不存在跨域问题,浏览器先访问a的服务器c,让c服务器作为代理去访问b服务器,拿到之后再返回数据给a。

  • nginx是静态服务器,跨域请求放在api下面好管理http://www.baidu.com:80/api/user
    可以在nginx下面的config下面的nginx.conf里面配置
    从80端口进来的就拦截一下,代理到81端口
    
    server{
            location /api {
                    //拦截一下
                    proxy_pass  http://www.baidu.com:81;
        }
    }
    

CORS解决跨域 (第三方模块)

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

浏览器端:

目前,所有浏览器都支持该功能(IE10以下不行)。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。

服务端:

CORS通信与AJAX没有任何差别,因此你不需要改变以前的业务逻辑。只不过,浏览器会在请求中携带一些头信息,我们需要以此判断是否运行其跨域,然后在响应头中加入一些信息即可。这一般通过过滤器完成即可。

优势:

在服务端进行控制是否允许跨域,可自定义规则
支持各种请求方式

缺点:

会产生额外的请求

jsonp

利用了 script 不受同源策略的限制

缺点:只能 get 方式,易受到 XSS攻击

·CORS(Cross-Origin Resource Sharing),跨域资源共享

当使用XMLHttpRequest发送请求时,如果浏览器发现违反了同源策略就会自动加上一个请求头 origin;

后端在接受到请求后确定响应后会在后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin;

浏览器判断响应中的 Access-Control-Allow-Origin 值是否和当前的地址相同,匹配成功后才继续响应处理,否则报错

缺点:忽略 cookie,浏览器版本有一定要求

·代理跨域请求

前端向发送请求,经过代理,请求需要的服务器资源

缺点:需要额外的代理服务器

·Html5 postMessage 方法

允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本、多窗口、跨域消息传递

缺点:浏览器版本要求,部分浏览器要配置放开跨域限制

·修改 document.domain 跨子域

相同主域名下的不同子域名资源,设置 document.domain 为 相同的一级域名

缺点:同一一级域名;相同协议;相同端口

·基于 Html5 websocket 协议

websocket 是 Html5 一种新的协议,基于该协议可以做到浏览器与服务器全双工通信,允许跨域请求

缺点:浏览器一定版本要求,服务器需要支持 websocket 协议

·http://document.xxx + iframe

通过 iframe 是浏览器非同源标签,加载内容中转,传到当前页面的属性中

缺点:页面的属性值有大小限制

说一下 JSONP 实现原理?

jsonp:JSON with Padding,它是利用script标签的 src 连接可以访问不同源的特性,加载远程返回的“JS 函数”来执行的。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!