Android技能树 — 网络小结(2)之TCP/UDP

3,803 阅读11分钟

介于自己的网络方面知识烂的一塌糊涂,所以准备写相关网络的文章,但是考虑全部写在一篇太长了,所以分开写,希望大家能仔细看,最好可以指出我的错误,让我也能纠正。

1.讲解相关的整个网络体系结构:

Android技能树 — 网络小结(1)之网络体系结构

2.讲解相关网络的重要知识点,比如很多人都听过相关网络方面的名词,但是仅限于听过而已,什么tcp ,udp ,socket ,websocket, http ,https ,然后webservice是啥,跟websocket很像,socket和websocket啥关系长的也很像,session,token,cookie又是啥。

Android技能树 — 网络小结(2)之TCP/UDP

Android技能树 — 网络小结(3)之HTTP/HTTPS

Android技能树 — 网络小结(4)之socket/websocket/webservice

相关网络知识点小结- cookie/session/token(待写)

3.相关的第三方框架的源码解析,毕竟现在面试个大点的公司,okhttp和retrofit源码是必问的。

Android技能树 — 网络小结(6)之 OkHttp超超超超超超超详细解析

Android技能树 — 网络小结(7)之 Retrofit源码详细解析


正文

网络体系结构小结中我们知道了大概的网络结构层级,这篇文章侧重的讲一些平时大家听到的熟悉的词汇TCP 与 UDP

1. TCP与UDP:

网络体系结构小结中我们提过TCP/IP的四层网络层级:

而TCP (Transmission Control Protocol,即 传输控制协议)和 UPD (User Datagram Protocol,即用户数据报协议)是在传输层的,所以我们知道UDP和TCP是用来传输数据的一种协议,为主机中不同的进程提供通信,那既然是传输数据,我们举例以快递寄信的逻辑来说明(反正都是某个东西从一个地方到另外一个地方)。

TCP像快递,因为我们现在寄快递都能看到具体快递到哪里了,某个中转站是否已经收到了我的快递,最后的目的地是否收到了我的快递,如果快递丢了也会给你反馈等,帮你重新补寄等。而UDP更像寄信,我反正寄出去了,收不收得到我也不管。(emmm....可能这个例子不太恰当。。。)

所以我们初步感觉:对比于UDP,TCP的传输是可靠的、无差错的。

1.1 TCP通道的连接及断开

既然是数据从一个地方到另外一个地方,我们要先建立一个通道,这样后面数据才能传输流动。(PS:这个比喻可能不恰当。如果有更好的比喻,可以留言。谢谢)

TCP三次握手,四次挥手听到的是不是很多,没错,这个就是用来建立这个通道及断开通道,我面试的别人的时候,三次建立,四次断开基本都知道,但是我问他们为什么要三次,很多都答不上来。为了更好的记忆,我们还是用具体的例子来说明:

三次握手:

1. A发信息给B:你在不在啊?急事!!
2. B发信息给A:我在啊,急事?那你快告诉我,我这边时刻听着你说。

不幸的是A这时候拉肚子,只能马上跑去厕所了,然后一拉就是半个小时,然后B就一直等了半个小时。

这时候你是不是发现了二次握手的问题了,如果第二次B发送给A的话后,A没有马上回相应的信息给B,B就可以认为A已经不在了,从而不再等它,也不建立通道。

所以应该是这样:

1. A发信息给B:你在不在啊?急事!!
2. B发信息给A:我在啊,急事?那你快告诉我,我这边时刻听着你说。
3. A发信息给B:事情是这样的。你听我慢慢道来。
balabala.......
balabala.......
balabala.......

然后A和B之间的通道就通了,然后A这时候可以给B不停的发信息了。

然后有人会问,TCP 又不会拉肚子,那TCP为啥要三次,因为如果规定二次的话: A 发给B信息,申请建立通道,因为网络延迟,B一直没收到,这时候A等的不耐烦了,直接就退出了,但是过了一会儿B收到了这个信息,B以为A是刚发的请求,所以建立了通道,但是A其实早就已经不在了。这样防止B形成死锁、浪费资源等。

当然上面是我们举得例子,具体肯定是通过一些值来传递:具体的图是这样的:

四次挥手:

我们知道TCP连接之后我们可以相互之间发消息了,这里我们假设这个通道里面其实包含了二个小通道,一个通道是用来A发给B的,一个通道用来是B发给A的,这样当我们要断开连接的时候有二大步:

  1. 断开A发给B信息的通道
  2. 断开B发给A信息的通道

我们先看断开A发给B信息的通道:

A发信息给B:我累了,我先睡了,88.

B发信息给A:好的,那你先睡吧。

这时候A就睡觉了,A也不会发信息给B了。但是这时候B还是可以继续给A发信息,B可能深夜突然来个深情告白

B发信息给A: 其实我XXXXXXXX。

所以我们单纯二次挥手是不够的,还要断开B发给A信息的通道

B发信息给A:不过你说你要睡了,我觉得是比较晚了,我也要睡了,晚安。

A发信息给B: 那你也早点睡。晚安

所以连在一起是:

A发信息给B:我累了,我先睡了,88.

B发信息给A:好的,那你先睡吧

B发信息给A:不过你说你要睡了,我觉得是比较晚了,我也要睡了,晚安。

A发信息给B: 那你也早点睡。晚安

那实际的四次挥手肯定也是传值通知,具体的图是这样的:

刚开始是双向通信,然后二次挥手后,A到B的断了,所以这时候变成单向的数据传输,然后再二次挥手,把这个单向数据传输也关闭。

所以我们看到了TCP的连接和断开都这么多步,多次确认等操作,但是UDP是不需要先建立一个稳定的通道,直接就把数据发过去了。所以UDP更快,因为不用先去建立连接。

1.2 TCP的无差错传输

我们平时肯定听到过TCP传输安全,UDP传输不安全等说法,TCP传输保证了数据最终能稳定安全的到达目的地,而UDP只管发送过去,不负责最终是否收到,具体原因是为啥呢???

我还是以下载工具 《迅雷》来进行说明(可能迅雷的功能实现更复杂,我就单纯用来说明TCP例子了,如果例子写的不对,欢迎大家指出):

问题1: 迅雷下载用的是TCP还是UDP?

下载东西我们肯定经历过下载的内容下载到百分之99,可能这个文件都是没用的,说明传输中我们对下载的文件要求百分百都收到。这样肯定是使用TCP来控制,因为UDP发送后不管你有没有收到。

问题2:用它下载东西的时候,突然中间一段时间网络很差,那时候服务器的发送的包都收不到了,但是最终还是下载了一个完整的包(有点类似迅雷的继续下载的感觉)

其实这个问题我说的更详细点:比如一个文件被分割成100份,我再收到第3份的时候如果因为网络不好没收到,它怎么校验我没收到第三份,而不是头脑发热直接发第四份第五份给我。应该是发现我第三份没收到,继续发一份第三份给我。同时如果控制它不是一股脑儿全部100份发出,而是发送一些,接收方收到一些,然后再发送一些。

就像上面说的有100份,但是接收端到第三份的时候就没收到,这时候发送端不应该继续发送第四份,第五份,说明接收端有给发送端反馈,就像:

A通过QQ要发给B 100个文件,但是这些文件是要有顺序的来接受。
这时候A发送一个文件,B接受一个文件,然后的界面就会有相应提示:

这时候A就知道了B已经收到了2个文件了,开始发第三个。
如果过了一段时间都没有收到这个B成功收到文件的提示,
则B就继续发送一个3.txt文件。


而对于A来说,如果QQ没收看到3.txt接受的提示,
而是直接收到了4.txt接受的请求,你肯定就是直接忽略,
而不是去下载4.txt文件,还是重新等待3.txt文件,
反正只要B没收到A成功下载3.txt文件的提示超时后就会重新发送3.txt。

发送端:

对于发送端: 每收到一个确认帧,发送窗口就向前滑动一个帧的距离 当发送窗口内无可发送的帧时(即窗口内的帧全部是已发送但未收到确认的帧),发送方就会停止发送,直到收到接收方发送的确认帧使窗口移动,窗口内有可以发送的帧,之后才开始继续发送 具体如下图:

接收端:

对于接收端:当收到数据帧后,将窗口向前移动一个位置,并发回确认帧,若收到的数据帧落在接收窗口之外,则一律丢弃。

滑动窗口 协议的重要特性:

  • 只有接收窗口向前滑动、接收方发送了确认帧时,发送窗口才有可能(只有发送方收到确认帧才是一定)向前滑动
  • 停止-等待协议、后退N帧协议 & 选择重传协议只是在发送窗口大小和接收窗口大小上有所差别:

1.停止等待协议:发送窗口大小=1,接收窗口大小=1;即 单帧滑动窗口 等于 停止-等待协议
2.后退N帧协议:发送窗口大小>1,接收窗口大小=1。
3.选择重传协议:发送窗口大小>1,接收窗口大小>1。

  • 当接收窗口的大小为1时,可保证帧有序接收。
  • 数据链路层的滑动窗口协议中,窗口的大小在传输过程中是固定的(注意要与TCP的滑动窗口协议区别)

1.3 TCP 与 UDP 区别

角度 TCP UCP
是否连接 面向连接(发送数据前需要建立连接) 无连接(发送数据无需连接)
是否丢包重试 实现了数据传输时各种控制功能,可以进行丢包的重发控制,还可以对次序乱掉的分包进行顺序控制 不会进行丢包重试,也不会纠正到达的顺序
模式 流模式(面向字节流) 数据报模式(面向报文)
对应关系 一对一 支持一对一,一对多,多对一和多对多的交互通信
头部开销 最小20字节 只有8字节
可靠性 全双工非常可靠、无差错、不丢失、不重复、且按序到达 不保证可靠交付,不保证顺序到达
拥塞控制 有控制 有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
资源要求 TCP程序结构较复杂,较多 UDP程序结构简单,少

结语:

其实关于TCP有很多很多可以讲,比如报文段格式,拥塞控制等,而我本文更多的是讲了大家平时听到的更多的知识点,结合通俗易懂的说明方式讲了下。当然我本身网络很差,所以有些地方如果讲错了欢迎大家指出。

关于具体的很细的细节,推荐看:计算机网络:这是一份全面 & 详细 的TCP协议攻略,部分图片都是该文引入。

参考文章:

计算机网络:这是一份全面 & 详细 的TCP协议攻略