【Java 总结思考】Java 答疑解惑之网络通信篇

打破舒适圈,经常对知识进行总结思考,才能保证自己不掉队。

系统化重学 Java 第五篇,虽然网络通信不属于 Java 技术领域,但是它是很重要的基础知识,也需要熟练掌握。

开头碎碎念

终于还是提了离职,在单位待了整整六年,走到最后满心疲惫,最初的热情消耗殆尽。

烟台这个城市很美,人很热情,大海也很漂亮,但我终究不属于这里。

离职是改变的起点,改变也意味着新的契机,虽然不知道未来在哪里,但是心怀希望,全力去做总是没错的。

言归正传,系统化重学 Java 不知不觉更新到第五篇了,越来越发现 “知道的越多,不知道的东西越多” ,所以坚持学习是非常重要的,不仅是为了面试进入好的公司,更多的是为了成为更好的自己,共勉。


第一问: 在浏览器中输入URL到访问到页面的过程中发生了什么?

  • 浏览器输入对应的域名地址;
  • 通过 DNS 服务器,将域名解析为对应的 IP 地址返回给客户端;
  • 客户端根据返回的 IP 地址,和服务器端建立 TCP 连接;
  • 客户端发送 HTTP 请求(会携带 cookies);
  • 服务端根据请求中的参数(也包括 cookies)进行处理,将响应的结果通过 HTTP 响应的方式发送给客户端;
  • 客户端接收到响应后进行页面渲染,呈现给用户对应的效果;
  • 不需要通信时,客户端主动发送断开连接请求,结束当前连接;

第二问: TCP 和 UDP 的区别有哪些?

TCP:提供面向连接的服务,传送数据前必须先建立连接,结束后要释放连接;

UDP:无需建立连接,收到数据也不需要给出确认,不保证数据传输的可靠性;

面向连接

可靠性

传输形式

传输效率

所需资源

应用场景

首部字节

TCP

可靠

字节流

要求通信数据可靠

20-60

UDP

不可靠

数据报文段

要求通信速度高

8


第三问: TCP 如何保证可靠传输?

TCP 通过分割数据段,包编号,校验和,丢弃重复数据,流量控制,阻塞控制,ARQ 协议,超时重传等机制来保证可靠传输。

  • 分割数据段:数据被分割成 TCP 认为最适合发送的数据块,来降低丢失的概率;
  • 包编号:给发送的每个包都进行编号,接收方对数据包进行排序,把有序数据传送给应用层;
  • 校验和:保持它首部和数据的检验和,目的是检测数据在传输过程中的变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段。
  • 丢弃重复数据:也就是去重;
  • 流量控制: 使用可变大小的滑动窗口协议实现流量控制,每一方都有固定的缓冲空间,如果接收方来不及处理数据,就会提示发送方降低发送速度。
  • 阻塞控制:当网络拥塞时,减少数据的发送;
  • ARQ协议:每发完一个分组就停止发送,等待对方确认,在收到确认后再发下个分组;它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。
  • 超时重传:当报文段发出后,发送端启动定时器,等待目的端确认收到这个报文段,如果不能及时收到确认消息,将重发这个报文段。

第四问: TCP 的三次握手指什么?

SYN 是请求连接标志,表示同意建立连接;

ACK 是确认报文,表示收到了请求报文。

第一次握手:

客户端主动发送带有 SYN 标志的数据包(seq=x)给服务器端,表示请求建立连接;

第二次握手:

服务器收到了客户端请求,向客户端发送带有 ACK / SYN 标志的数据包(seq=y,ack=x+1),表示确认收到的客户端的报文序号有效,并同意建立新连接;

第三次握手:

客户端收到服务端请求后,发送带有 ACK 标志的数据包(seq=x+1,ack=y+1),表示接收到了服务端发送的数据,可以正常进行通信了;


第五问: TCP 为什么需要三次握手?

就好比两个人聊天:

A:你吃了么?

B:我吃了,你呢?

A:我也吃了。

这样双方就都知道对方吃饭了,就放心一起出去玩了。

放在 TCP 通信的场景中,就是客户端和服务端都知道自己和对方的消息收发正常,就可以正常通信了。


第六问: TCP 的四次挥手是什么?

 第一次挥手:

客户端主动发送带有 FIN 标志的数据包(seq=u)给服务器端,表示请求关闭连接,进入FIN_WAIT_1 状态;

 第二次挥手:

服务端收到后,发送带有 ACK 标志的数据包(seq=k,ack=u+1),表示确认收到了关闭的请求,进入 CLOSE_WAIT 状态;

 第三次挥手:

之后,服务器把剩余数据传输结束后,发送带有 FIN 标志的数据包(seq=w,ack=u+1),表示自己也可以关闭连接了,进入 LAST_ACK 状态;

第四次挥手:

客户端收到 FIN 数据包后,进入 TIME_WAIT 状态,并发送 ACK 数据包(seq=u+1,ack=w+1)给服务端,服务端随之进入CLOSED 状态,完成四次挥手。

补充:

客户端收到 FIN 数据包后,进入 TIME_WAIT 状态,这个状态的维持时间是 2 MSL(数据包在网络中的最大生存时间)。

为什么要这么设计呢?

第一个原因是为了实现连接的可靠释放。

如果客户端发送的 ACK 在网络中丢失,由于 TCP 协议的重传机制,服务端将会重发 FIN,在该FIN 到达客户端前,客户端必须维护连接状态。

也就说这条 TCP 连接所对应的资源不能被立即释放或重新分配,直到另一方重发的 FIN 到达。

当 FIN 到达后,客户端需要重发 ACK,经过 2MSL 时间周期没有再收到另一方的 FIN 之后,该TCP 连接才能恢复初始的 CLOSED 状态。

第二个原因是为了使旧的数据包不要影响到其它新建立的连接。

假如新的 TCP 连接建立了,旧的延迟后的 FIN 数据包又到达了,就会对新的连接造成影响。


第七问: 为什么TCP 需要四次挥手?

比如两个人在聊天:

A 说,我不想说话了;

B 说,好吧,我知道了;

B 上个话题还没说够,又把剩下的话说完了,然后告诉A,我说完了没啥事了;

A 说,嗷,你可算说完了,再见;

之所以握手有三次,而挥手需要四次,是因为挥手过程涉及了剩余数据的传输处理,所以多了一个步骤。


第八问: URI 和 URL 的区别是什么?

URI (Uniform Resource Identifier) 是统一资源标志符,可以唯一标识一个资源。

URL(Uniform Resource Location) 是统一资源定位符,可以提供该资源的路径。

它是一种具体的 URI,即 URL 可以用来标识一个资源,而且还指明了如何定位这个资源。


第九问:开发中的常见状态码有哪些?

猜你喜欢

转载自blog.csdn.net/j1231230/article/details/119488959
今日推荐