Java 总结思考Java 答疑解惑之网络通信篇
Posted 盛夏温暖流年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 可以用来标识一个资源,而且还指明了如何定位这个资源。
第九问:开发中的常见状态码有哪些?
以上是关于Java 总结思考Java 答疑解惑之网络通信篇的主要内容,如果未能解决你的问题,请参考以下文章