一、网络基础
1、认识 IP 地址
概念
IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。
作用
IP地址 是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
格式
IP地址 是一个 32位的二进制数,通常被分割为 4 个 “8位二进制数”(也就是4个字节),
通常用 “点分十进制” 的方式来表示,即 a.b.c.d 的形式(a,b,c,d都是0~255之间的十进制整数)。
组成
IP地址分为两个部分,网络号和主机号
- 网络号:标识网段,保证相互连接的两个网段具有不同的标识;
- 主机号:标识主机,同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号;
通过合理设置网络号和主机号,就可以保证在相互连接的网络中,每台主机的IP地址都是唯一的。
分类
分类 | 范围 | 适用网络 | 网络数量 | 主机最大连接数 |
---|---|---|---|---|
A类 | 0.0.0.0 ~ 127.255.255.255 | 大型网络 | 126 | 16777214 |
B类 | 128.0.0.0 ~ 191.255.255.255 | 中等规模网络 | 约16000个 65534 | ( 2 16 2^{16} 216-2) |
C类 | 192.0.0.0 ~ 223.255.255.255 | 小型网络 | - | 254( 2 8 2^8 28-2) |
D类 | 224.0.0.0 ~ 239.255.255.255 | - | - | - |
E类 | 240.0.0.0 ~ 247.255.255.255 | - | - | - |
备注:主机最大连接数减去2,是扣除主机号为全0和全1的特殊IP地址。
2、子网掩码
在上述的分类中,存在IP地址浪费的问题:
- 单位一般会申请B类网络(C类连接主机数量有限),但实际网络架设时,连接的主机数量又常远小于65534(B类连接主机数),造成IP地址浪费;同理,A类网络的IP地址也会造成大量的浪费。
- 当一个单位申请了一个网络号。他想将该网络能表示的IP地址再分给它下属的几个小单位时,如 果在申请新的网络就会造成浪费。
为了解决以上问题,引入子网掩码来进行子网划分:
格式
子网掩码格式和IP地址一样,也是一个32位的二进制数。其中左边是网络位,用二进制数字“1”表示,1 的数目等于网络位的长度;右边是主机位,用二进制数字“0”表示,0的数目等于主机位的长度。
子网掩码也可以使用二进制所有高位1相加的数值来表示。
作用
- 划分A,B,C三类 IP 地址子网: 如一个B类IP地址:191.100.0.0,按A ~ E类分类来说,网络号二进制数为16位网络号+16位主机号。 假设使用子网掩码
255.255.128.0(即17)来划分子网,意味着划分子网后,高17位都是网络位/网络 号,也就是将原来16位主机号,划分为1位子网号+15位主机号。
此时,IP地址组成为:网络号+子网号+主机号,网络号和子网号统一为网络标识(划分子网后的网络号/网段)- 网络通信时,子网掩码结合IP地址,可以计算获得网络号(划分子网后的网络号)及主机号(划
分子网后的主机号)。一般用于判断目的IP与本IP是否为同一个网段。
对于网络通信来说,发送数据报时,目的主机与发送端主机是否在同一个网段,流程是不一样 的。
计算方式
将 IP 地址和子网掩码进行“按位与”操作(二进制相同位,与操作,两个都是1结果为1,否则为0),得到的结果就是网络号。
将子网掩码二进制按位取反,再与 IP 地址位与计算,得到的就是主机号。
特殊的 IP 地址
- 192.168.0.1 / 192.168.1.1:主机号为 .1 的 IP,通常用来作为 “网关”。关:入口,出口。
- 192.168.0.0 / 192.168.1.0:主机号为 .0 的 IP,作为网络号(表示当前局域网 / 网段)。
- 192.168.0.255 / 192.168.1.255:主机号为 .255 的 IP,通常作为 广播 IP
- 127.0.0.1 / 127.* :环回 IP(表示主机自己)
3、认识 MAC 地址
MAC地址,即 Media Access Control Address,用于标识网络设备的硬件物理地址。
- 主机具有一个或多个网卡,路由器具有两个或两个以上网卡;其中每个网卡都有唯一的一个MAC 地址。
- 网络通信,即网络数据传输,本质上是网络硬件设备,将数据发送到网卡上,或从网卡接收数据。
- 硬件层面,只能基于MAC地址识别网络设备的网络物理地址。
- MAC地址用来识别数据链路层中相连的节点;
- 长度为48位,及6个字节。一般用16进制数字加上冒号的形式来表示(例如:08:00:27:03:fb:19)
- 在网卡出厂时就确定了,不能修改。虚拟机中的MAC地址不是真实的MAC地址,可能会冲 突;也有些网卡支持用户配置MAC地址。
特殊的MAC地址
广播数据报:发送一个广播数据报,表示对同网段所有主机发送数据报。广播数据报的MAC地址为:
FF:FF:FF:FF:FF:FF
4、总结IP地址和MAC地址
- IP地址 描述的是路途总体的起点和终点;是给人使用的网络逻辑地址。
- MAC地址 描述的是路途上的每一个区间的起点和终点,即每一跳的起点和终点;是给网络硬件设 备使用的网络物理地址。
二、应用层重点协议
1、DNS
DNS,即Domain Name System,域名系统。DNS 是一整套从域名映射到IP的系统。
TCP/IP 中使用 IP 地址 来确定网络上的一台主机,但是 IP 地址 不方便记忆,且不能表达地址组织信息,于是人们发明了域名,并通过域名系统来映射域名和IP地址。
域名可以通过 DNS 系统自动转换成对应的 IP 地址。
最早的 DNS 系统,是一个文件,称为 hosts 文件。这个方式比较原始,现在基本上不用了。
现在的网站,成千上万,不能把所有的映射关系都写到文件中。
因此,更科学的方法,使用专门的 DNS 服务器,来保存这个文件。
使用服务器把这些映射关系都存储好,哪个电脑需要 DNS 解析,就访问这个 DNS 服务器即可。
但全世界要上网的设备,是非常多的,每个设备上网的时候,都要请求 DNS 服务器?DNS
服务器能扛得住这么大的访问量吗?显然是不能的,那么如何解决 DNS 服务器访问量太大的问题呢?
- 主机在请求 DNS 之后,会对映射关系在本地进行缓存,这样就可以大大的减少客户端访问 DNS 服务器请求的数量。(域名 => IP 这个映射关系,虽然会变,但是频率比较低)
- 在全世界,架设很多的 DNS 镜像服务器
- 最初的 DNS 服务器,称为 “根服务器”。
- 其他的 DNS 服务器,从根服务器上同步数据,称为 “镜像服务器”。
2、NAT
NAT:IP 地址转换
把 IP 地址分成两个大类:
- 内网 IP(局域网中使用的 IP)
- 外网 IP(广域网中使用的 IP)
允许局域网之间的内网 IP 重复,但是外网 IP 要保持唯一。
同一个局域网中的 IP 地址不能相同,但是不同局域网中的 IP 允许重复。
NAT 机制的本质就是用一个 外网 IP 代表一大批 内网的设备!
3、NAPT
那么问题来了,如果局域网内,有多个主机都访问同一个外网服务器,那么对于服务器返回的数据中,目的IP都是相同的。那么NAT路由器如何判定将这个数据包转发给哪个局域网的主机?
这时候NAPT来解决这个问题了。使用IP+port来建立这个关联关系
这种关联关系也是由NAT路由器自动维护的。例如在TCP的情况下,建立连接时,就会生成这个表项;在断开连接后,就会删除这个表项
4、HTTP/HTTPS
HTTP及HTTPS是应用层重点协议,我们会在Web开发中学习。
三、传输层重点协议
1、TCP
TCP,即Transmission Control Protocol,传输控制协议。人如其名,要对数据的传输进行一个详细的控制。
① TCP协议段格式
- 源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
- 32位序号/32位确认号:给发送个每一个数据都进行编号;如果当前报文是普通报文,则确认序号不生效
- 4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是 15 * 4 = 60
- 6位标志位:
- URG:紧急指针是否有效
- ACK:确认号是否有效(是否为应答报文)
- PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
- RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
- SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
- FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
- 16位窗口大小:后面再说
- 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分。
- 16位紧急指针:标识哪部分数据是紧急数据;
- 40字节头部选项:暂时忽略;
② TCP原理
TCP对数据传输提供的管控机制,主要体现在两个方面:可靠和效率。
这些机制和多线程的设计原则类似:保证数据传输可靠的前提下,尽可能的提高传输效率。
Ⅰ 确认应答机制(可靠性)
- 一口气发了 1000 个字节的数据(一个 TCP 数据报,长度是 1000,序号是 1)
- 应答报文中的确认序号,就是 1001.
- 应答报文:可视为只有 TCP 报头,没有载荷.
- 意思就是 < 1001 的数据,B 已经收到了;接下来 A 要从 1001 开始往后发送!!!
TCP将每个字节的数据都进行了编号。即为序列号。
下图体现的是报文的字节:
由于 TCP 是面向字节流的,编号的时候,是按照字节来编的!
Ⅱ 超时重传机制(可靠性)
在确认应答的情况下,如果没有收到 ACK,就需要通过其他途径来处理!
超时重传:不是说没有收到 ACK,立即就放弃,就需要重新再发一遍!
网络的环境是非常复杂的,尤其是有些时候,网络会拥堵,拥堵就可能会导致丢包!
丢包,是 “无差别” 丢的。任何一个数据报,都有可能会丢包!
普通报文 可能丢失,ACK 也可能丢失!
业务数据丢失
发送方等待一定的时间之后,没有收到 ACK 就会重传!
ACK 丢失
业务数据已经到了 主机 B 了,反馈的 ACK 没有回过去,发送方等待一会之后,就触发了重传!
- 对于 发送方 来说,无法区分是 业务数据丢失,还是 ACK 丢失。因此 发送方 能做的只是,达到一定时间之后,就重传!
- 对于 接收方 来说,会根据序号,来进行数据去重。接收方 知道自己都收到了哪些数据,当发现又收到了一份之前的数据就会自动丢弃,保证应用层读到的数据是不重复的!
假设第一次重传失败了,进行第二次重传,又失败了;
第一次丢包超时时间为 t1,第二次丢包超时时间为 t2,此时一定:t1 < t2
丢包超时等待的时间间隔,随着丢包此时的增加,越来越大!
连续重传之后又丢包的次数越多,此时意味着单次发送的丢包概率越大,那么可能是网络上遇到了非常严重的故障,短期内恢复不了;发送的再频繁也没有用!
- 如果连续几次重传都不行,那就只能放弃了!
- 超时重传也不会无限制的重传下去,尝试几次之后,仍无法传输,就会放弃尝试,并断开连接!
Ⅲ 连接管理机制(可靠性)
确认应答 和 超时重传 可以认为是保证 TCP 可靠性的 最核心机制!
但是 连接管理 是面试中最高频的问题(网络知识)!
在正常情况下,TCP 要经过 三次握手 建立连接,四次挥手 断开连接!
三次握手:必须是客户端主动,服务器被动
经历这四次交互,就完成了建立连接的过程,其实是两对操作,客户端和服务器,互相给对方发送了一个 SYN,再互相给对方发送了一个 ACK,一共是四次交互,完成了这个过程!
但是因为中间的两次 即 服务器给 客户端发送 SYN 和 ACK,都是内核收到 A 的 SYN 之后,立即返回的,可以合并为一次!
所以整个过程又叫 “三次握手”。
三次握手的意义:(三次握手,认为是一种保证可靠性的机制)
- 这个东西相当于 “投石问路”,在正式通信之前,先确定好通信链路是否畅通!
如果通信链路不畅通,后续大概率要丢包! - 能够让通信双方协商一些重要的参数!(比如:序号是从几开始的;MSS 等等)
四次挥手:客户端和服务器都可以主动
与 三次握手 不同,四次挥手 看起来也是双方各自给对方发送 FIN,各自给对方发送 ACK。
但是,四次挥手 这里的 中间两次,不能合并!
B 返回 ACK 是 内核 的行为,操作系统内容接收到 FIN 之后,就会立即返回 ACK;
而接下来 B 返回 FIN 是用户代码的行为,用户在代码中调用 socket.close 方法,才会触发 FIN!
因此 B 发送 FIN 和 发送 ACK 之间会有不可忽视的时间间隔,正因为有了时间间隔,就不能合并了
举例:
- 把建立连接,理解成入职:B 这边属于没有工作的状态,A 抛出橄榄枝了,B 立即就同意了,就可以立即入职了!
- 把断开连接,理解成离职:A 通知 B,你被解雇了,你自己提交一个辞职报告把;此时 B 还有一些工作交接,不能立即离职!
完整过程:
TCP 的状态:
- LISTEN :(服务器的状态)服务器已经启动完毕,已经绑定端口成功!
例如:手机开机完毕,信号良好(随时有人给他打电话) - ESTABLISHED:连接建立好了,可以进行后续通信!
例如:打电话号码拨通,对方已经接听,接下来就可以随时说话了 - CLOSE_WAIT:(被动接受 FIN 的一方,进入 CLOSE_WAIT)这个状态就是自己收到了 FIN 也返回了 ACK,在自己发送 FIN 之前,处于的状态。(等待代码调用 close 方法,发送 FIN)
- TIME_WAIT:(主动发起 FIN 的一方,会进入 TIME_WAIT)主动的一方,收到对方的 FIN,并返回 ACK 之后,就会进入这个状态,而不是直接进入 CLOSED 状态,在 TIME_WAIT 状态下停留一段时间,才会进入 CLOSED 彻底释放连接。
(防止最后一个 ACK 丢失,万一最后一个 ACK 丢失,在 TIME_WAIT 状态下,还可以重传)
Ⅳ 滑动窗口机制(效率)
我们要清楚一点:**可靠性 和 效率是冲突的!**保证 可靠性 肯定会影响到 效率 的。
TCP 在保证 可靠性 的前提下,尽可能的提高 效率。
滑动窗口机制的本质就是把等待 ACK 的时间重叠起来。
减少等待时间,就相当于提高了效率。
每次传输,都需要等待 ACK,收到 ACK 再发下一题数据,这样效率就很低。
我们一次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)。
- 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000 个字节(四个段)。
- 发送前四个段的时候,不需要等待任何ACK,直接发送;
- 收到第一个 ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
- 操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有 应答;只有确认应答过的数据,才能从缓冲区删掉;
- 窗口越大,则网络的吞吐率就越高;
我们之前提到了TCP 在保证 可靠性 的前提下,尽可能的提高 效率。 那么在滑动窗口之下,可靠性是否有影响呢?
- 确认应答:还是正常应答,没有什么影响。
- 超时重传:在滑动窗口下,丢包了,怎么办?
对于超时重传丢包,这里分两种情况讨论。
情况一:ACK 丢失
这种情况下,部分 ACK 丢了并不要紧,因为可以通过后续的 ACK 进行确认;
情况二:数据包丢失
主机 A 发了半天之后,看到了连续的好几个 1001,它就明白了,是 1001 这个数据丢了!
接下来,A 就会重传 1001 这个数据了。
此处的原则是:哪条丢了,就重传哪条;已经传输到的数据,不必重复传输!
这种机制被称为 “快速重传”(不是说重传的有多快,而是说没有冗余的操作)
Ⅴ 流量控制机制(可靠性)
滑动窗口,窗口大小越大,发送速率就越快!流量控制,就是在针对发送速率进行制约!
接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应,反而还降低了速率。
流量控制,就是通过 接收缓冲区 剩余空间大小,来作为下一次发送时候的窗口大小。
- 16位窗口大小:当前是 ACK 报文的时候,16位窗口大小会生效;这个窗口大小就表示了接收缓冲性的剩余空间大小;根据这个大小,就可以进一步的影响到发送速率了。
我们之前了解到 16位 即 64 KB,那么是否意味着窗口大小最大就是 64 KB呢?并不是,这个是可选项
- 选项:可以有,也可以没有;可以有一个,也可以有多个;这里有一个特殊字段,窗口扩大因子 M,实际窗口大小是 窗口字段的值左移 M 位。
流程演示:
Ⅵ 拥塞控制机制(可靠性)
流量控制,站在接收方的角度,来控制发送速率;
但是整体的传输,其实不光有发送方和接收方,还有中间的一系列用来转发的设备。
拥塞控制,采取的方法:做实验。
通过实验的方式,找出一个合适的窗口大小。
- 刚开始按照小的窗口来发送。
- 如果不丢包,说明网络中间环境 比较畅通,就可以逐渐放大发送窗口的大小。
- 放大到一定程度,速率已经比较快,网络上就容易出现拥堵,进一步出现丢包;当发送方发现丢包之后,就减小发送的窗口。
反复在 2 和 3 之间循环!
这个过程,就达到了一个 “动态平衡”,发送速率不慢,接近了能承载的极限,同时还可以尽量少丢包,还能适应网络环境的动态变化。
流量控制 和 拥塞控制 都能影响发送方的滑动窗口大小!最终的滑动窗口大小,就取决于两者的较小值。
像上面这样的拥塞窗口增长速度,是指数级别的。“慢启动” 只是指初使时慢,但是增长速度非常快。
- 为了不增长的那么快,因此不能使拥塞窗口单纯的加倍。
- 此处引入一个叫做慢启动的阈值
- 当拥塞窗口超过这个阈值的时候,不再按照指数方式增长,而是按照线性方式增长
拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。
Ⅶ 延迟应答机制(效率)
延时应答也是一个用来 提高效率的机制。
延时应答,则是让窗口能够大一些。
在流量控制中,通过 ACK 告知发送方,窗口大小是多少合适,这里的窗口大小是由接收缓冲区的空余空间来决定的。
- 如果立即返回 ACK,可能接收端缓冲区空余空间为 5KB;
- 稍等一会(例如 500 ms),在这个过程中,应用程序不断的取走数据,接收端缓冲区空余空间可能为 100 KB 了。
在延时应答下,ACK 不一定要和发送的数据表一一对应,少点也是可以的。
那么所有的包都可以延迟应答么?肯定也不是;
- 数量限制:每隔N个包就应答一次;
- 时间限制:超过最大延迟时间就应答一次;
具体的数量和超时时间,依操作系统不同也有差异;一般N取2,超时时间取 200ms;
Ⅷ 捎带应答机制(效率)
正常来说,ACK 是收到请求之后,内核立即返回的;而响应数据,则是应用程序代码,发送的。二者是不同的时机,就不能把 ACK 和 响应报文 合并。
但是基于延时应答等的基础上,延时一会,就可能和返回 响应数据,时间上重合了。
响应在收到请求之后,多长时间之内返回?不确定:
- 可能快:本来也要发送 数据报文,ACK 就搭个顺风车;
- 可能慢:ACK 就先走了。
Ⅸ 面向字节流
面向字节流,指的是读写载荷数据的时候,是按照 “字节流” 的方式来读取的。
TCP 数据报,本身仍然是 一个一个 “数据报” 这样的方式来传输的。
(应用程序,是感受不到从哪里到哪里是一个数据报的)
传输数据的时候,数据会先写入 接收缓冲区,应用程序直接从 接收缓冲区 取数据。
此时,应用程序在读取数据的时候,就可以灵活的进行了,可以一次读 M 个字节,分 N 次读。
Ⅹ 粘包问题
如果一个 TCP 连接,里边只传一个 应用层数据包,这个时候不会粘包(短链接)。
如果一个 TCP 连接,传输多个应用层数据包,这个时候就容易分不清,从哪到哪是一个完整了应用层数据(长连接)。这就是粘包问题。
不仅仅是 TCP ,只要是面向字节流的传输,都有粘包问题(文件传输)。
粘包问题的解决方案:在应用程序代码中,明确包之间的边界!
- 使用分隔符
- 约定长度
③ TCP异常情况
Ⅰ 主机关机(按照固定程序关机)
按照程序关机,会先杀死所有的用户进程(也就包括我们自己写的 TCP 程序)
杀死进程 => 释放进程 PCB => 释放文件描述符表上对应的文件资源(相当于调用 close)
这个时候就会出发 FIN,开启 四次挥手 的流程!
- 如果四次挥手挥完了,就继续关机;
- 如果还没有挥完,就已经关机了,对端重传 FIN 若干次,没有响应,就放弃了。
Ⅱ 程序崩溃
同上,程序是正常关闭,还是异常崩溃,都会释放 PCB,都会释放文件描述符表(相当于调用 close)
也还是会正常 四次挥手(虽然进程没了,但是本身 TCP 连接也是内核负责,内核仍然会继续完成后续的挥手过程)
Ⅲ 主机掉电(突然拔电源)
笔记本还好(内置电源),如果是台式机之类的,直接没了,肯定来不及挥手。
- 接收方掉电:对方尝试发送数据,发现没有 ACK,尝试重传,重传几次,仍然没有 ACK,发送方尝试重新建立连接。如果重新建立也不成,认为是当前网络上出现了严重问题,就自然放弃了。
- 发送方掉电:接收方就在等待发送方发的数据,由于发送方没了,这个数据显然发不过来了,接收方 也不知道是 发送方 没有发,还是 发送方 出现异常了(接收方区分不了)。
接收方 如果一段时间没有收到数据,就会定期给 发送方,发送 “心跳包”:
接收方 给对方发一个特殊的报文(ping),发送方 返回一个特殊的报文(ping)。
Ⅳ 网线断开
和主机掉电,相同。
④ TCP小结
为什么TCP这么复杂?因为要保证可靠性,同时又尽可能的提高性能。
可靠性:
- 校验和
- 序列号(按序到达)
- 确认应答
- 超时重发
- 连接管理
- 流量控制
- 拥塞控制
提高性能:
- 滑动窗口
- 快速重传
- 延迟应答
- 捎带应答
其他:
- 定时器(超时重传定时器,保活定时器,TIME_WAIT定时器等)
⑤ 基于TCP的应用层协议
- HTTP
- HTTPS
- SSH
- Telnet
- FTP
- SMTP
当然,也包括你自己写TCP程序时自定义的应用层协议;
2、UDP
① UDP协议端格式
源端口号
发送方
目的端口号
接收方
UDP长度
最大接收长度为 65535 字节 即 64 KB.
校验和
可以认为是针对数据特征进行的 “摘要”,接收方就可以根据校验和来进行检查了!
网络传输中,传输的数据,不一定是准确无误的!
本质上是光信号/电信号,使用不同频率的光信号,表示 1-0,使用不同电频的电信号,表示 1-0;传输过程中,信号是可能受到干扰的!
干扰就可能造成 “比特反转”(1 和 0 互换)
接收方,收到了数据之后,就需要验证,当前的数据是否正确!
② UDP的特点
UDP传输的过程类似于寄信。
Ⅰ 无连接
知道对端的IP和端口号就直接进行传输,不需要建立连接;
Ⅱ 不可靠
没有任何安全机制,发送端发送数据报以后,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息;
Ⅲ 面向数据报
应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并; 用UDP传输100个字节的数据:
如果发送端一次发送100个字节,那么接收端也必须一次接收100个字节;而不能循环接收10次,每次接收10个字节。
Ⅳ 缓冲区
UDP只有接收缓冲区,没有发送缓冲区: UDP没有真正意义上的
发送缓冲区。发送的数据会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作;
UDP具有接收缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃;
UDP的socket既能读,也能写,这个概念叫做 全双工
Ⅴ 大小受限
UDP协议首部中有一个16位的最大长度。也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)。
③ 基于UDP的应用层协议
- NFS:网络文件系统
- TFTP:简单文件传输协议
- DHCP:动态主机配置协议
- BOOTP:启动协议(用于无盘设备启动)
- DNS:域名解析协议
当然,也包括你自己写UDP程序时自定义的应用层协议。
④ 扩展问题
这是一个经典面试题:
- UDP本身是无连接,不可靠,面向数据报的协议,如果要基于传输层UDP协议,来实现一个可靠传输,应该如何设计?
- UDP大小是受限的,如果要基于传输层UDP协议,传输超过64K的数据,应该如何设计?
以上两个问题答案类似,都可以参考TCP的可靠性机制在应用层实现类似的逻辑:
例如:
- 引入序列号,保证数据顺序;
- 引入确认应答,确保对端收到了数据;
- 引入超时重传,如果隔一段时间没有应答,就重发数据;
- ……
3、TCP/UDP对比
- 如果需要关注可靠性传输,优先考虑 TCP。
- 如果传输的单个数据报比较大(UDP 报文上限是 64 KB),优先考虑 TCP。
- 如果可靠性要求不高,但对于性能要求很高,优先考虑 UDP(网络环境简单,带宽充裕,主机间通信能够足够快)。
- 如果是需要进行 “广播”,优先考虑 UDP(1 个发送方,N 个接收方)。
归根结底,TCP和UDP都是程序员的工具,什么时机用,具体怎么用,还是要根据具体的需求场景去判定。
四、网络层重点协议
1、IP
协议头格式如下:
- 4位版本号:指定IP协议的版本。
- 4位首部长度:IP 报头的长度,带有选项字段,(0~15)* 4个字节,最长是 60 字节,最短是 20 字节。
- 8位服务类型(Type Of Service):其实只有 4 位有效,另外 4 位是保留位。
4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。这四者相互冲突,只能选择一个。 - 16位总长度:一个 IP 数据报的长度(报头 + 载荷),载荷部分就是一个完整的传输层数据报。
- 16位标识:唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每
一个片里面的这个id都是相同的。 - 3位标志字段:第一位保留。第二位置为 1 表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示 “更多分片”,如果分片了的话,最后一个分片置为 1,其他是 0。类似于一个结束标记。
- 13位分片偏移:描述了拆出来的每个包的先后顺序。
- 8位生存时间(Time To Live,TTL):描述了这个 IP 数据报,还能在网络上存活多久。数据报到达目的地的最大报文跳数 64(32,64,128),每次数据报经过一个路由器的转发,TTL -= 1,一旦 TTL 为 0了,则认为这个 IP 就找不着,包就要丢弃。
- 8位协议:表示上层协议的类型。
- 16位头部校验和:使用CRC进行校验,来鉴别头部是否损坏,不对数据部分校验;数据部分的校验,由传输层的协议来负责。
- 32位源地址和32位目标地址:表示发送端和接收端。
2、解决 IP 地址不够用的问题
① DHCP
DHCP:动态分配 IP 地址
- 一个设备上网,就分配 IP
- 不上网,就不分配 IP
② NAT
NAT:IP 地址转换
把 IP 地址分成两个大类:
- 内网 IP(局域网中使用的 IP)
- 外网 IP(广域网中使用的 IP)
允许局域网之间的内网 IP 重复,但是外网 IP 要保持唯一。
同一个局域网中的 IP 地址不能相同,但是不同局域网中的 IP 允许重复。
NAT 机制的本质就是用一个 外网 IP 代表一大批 内网的设备!
③ IPv6
IPv6 相当于是另一个网络层的协议,和 IPv4 可以视为是完全不同的两个协议,而不是 IPv4 的升级版。
IPv6 使用 16字节(128位);IPv4 使用 4字节 (32位)。
IPv6 的 IP 地址是非常多的,可以说根本用不完。
但是 IPv6 有一个很大的问题:IPv6 和 IPv4 是不兼容的!
现存的支持 IPv4 的网络设备(路由器,网卡,交换机,…)不一定支持 IPv6。
要想升级,就得换设备,换设备,就要花钱,这个事情就给 IPv6 的普及带来了很大的阻碍!
2019年,由国家推进 IPv6,然后各大公司不计成本的升级 IPv6;如今,国内 IPv6 普及度已经非常高了。那么为什么国家要推进 IPv6 呢?
有了 IPv6,家里的设备就可以直接在外网访问了;
IPv4 的话,得通过特殊手段(内网穿透),才能做到。
3、路由选择
路由选择 就和 地图寻路 差不多的。从 A 到 B,路线规划的过程中,就是路由选择。
路由器撒花姑娘进行路径规划的时候,没有那么多空间来保存全局的信息。
每个路由器只能知道位置信息的一部分。
路由器这里的数据转发,就类似于没有百度地图之前的,原始的寻路方式,问路。
每次问路,就相当于经历了一次 “路由转发”。
每个人脑子里面记住的一些位置信息,称为 “路由表”。
路由器会根据 目的 IP 在路由表 中匹配:
- 如果匹配到了,就会按照制定的方向继续往下转发。
- 如果没有匹配到,会有一个默认等待方向(下一跳地址,路由表中的默认选项)。
无、数据链路层重点协议
1、认识以太网
以太网 协议,即插网线协议。平时插的网线,也叫做 “以太网线”
“以太网” 不是一种具体的网络,而是一种技术标准;既包含了数据链路层的内容,也包含了 一些物理层的内容。例如:规定了网络拓扑结构,访问控制方式,传输速率等;
① 以太网帧格式
以太网的帧格式如下:
- 目的地址、源地址:mac 地址(物理地址),不是 IP 地址。
- CRC:校验码,处于帧的末尾。
- ARP 请求/应答:根据 IP 地址,找到对应的 mac 地址。
- RARP 请求/应答:根据 mac 地址,找到对应的 IP 地址。
2、认识MTU
MTU相当于发快递时对包裹尺寸的限制。这个限制是不同的数据链路对应的物理层,产生的限制。
- 以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节, 要在后面补填充位;
- 最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
- 如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对 数据包进行分片(fragmentation);
- 不同的数据链路层标准的MTU是不同的;
3、ARP
作用:ARP协议建立了主机 IP地址 和 MAC地址 的映射关系。
- 在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬 件地址;
- 数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不 符,则直接丢弃;
- 因此在通讯前必须获得目的主机的硬件地址;
六、总结
1、经典面试题
从浏览器中输入 URL 开始,到最终看到页面位置,中间发生了哪些事情?
- 应用层角度:浏览器是客户端,这里输入 URL 就会访问对应的服务器。
- DNS 解析
- 构造 HTTP 请求
- 传输层角度:对应到 TCP 协议。
- 先三次握手,建立连接
- 传输数据(确认应答,超时重传,滑动窗口,流量控制,拥塞控制,…)
- 网络层角度:网络数据报转发过程,一跳一跳的方式来转发。
(路由表,路由表匹配规则,下一跳相关内容) - 数据链路层角度:以太网数据帧,mac 地址,mac 在转发过程中如何变换,MTU,MTU 影响到的 IP 分包。
- 物理层角度:上述数据会转成 “光信号” “电信号” 进行编码,传输。
- 总结:
- 发送的过程中,涉及到从上到下的封装
- 接收方,涉及到从下到上的分用
上述过程是客户端给服务器发送请求的过程,后面服务器还要根据请求计算响应,把响应按照类似的流程转发给客户端。
2、总结
数据链路层
- 数据链路层的作用:两个设备(同一种数据链路节点)之间进行传递数据
- 以太网是一种技术标准;既包含了数据链路层的内容,也包含了一些物理层的内容。例如:
规定了网络拓扑结构,访问控制方式,传输速率等; - 以太网帧格式
- 理解mac地址
- 理解arp协议
- 理解MTU
网络层
- 网络层的作用:在复杂的网络环境中确定一个合适的路径。
- 理解IP地址,理解IP地址和MAC地址的区别。
- 理解IP协议格式。
- 了解网段划分方法
- 理解如何解决IP数目不足的问题,掌握网段划分的两种方案。理解私有IP和公网IP
- 理解网络层的IP地址路由过程。理解一个数据包如何跨越网段到达最终目的地。
- 理解IP数据包分包的原因。
- 了解NAT设备的工作原理。
传输层
- 传输层的作用:负责数据能够从发送端传输接收端。
- 理解端口号的概念。
- 认识UDP协议,了解UDP协议的特点。
- 认识TCP协议,理解TCP协议的可靠性。理解TCP协议的状态转化。
- 掌握TCP的连接管理,确认应答,超时重传,滑动窗口,流量控制,拥塞控制,延迟应答,
捎带应答特性。 - 理解TCP面向字节流,理解粘包问题和解决方案。
- 能够基于UDP实现可靠传输。
- 理解MTU对UDP/TCP的影响。
应用层
- 应用层的作用:满足我们日常需求的网络程序,都是在应用层
- 能够根据自己的需求,设计应用层协议。
- 了解HTTP协议。
- 理解DNS的原理和工作流程。