又称计算机的硬件地址, 被固化在适配器(网卡)ROM上的占48位的地址. MAC地址可以用来唯一区别一台计算机, 因为它在全球是独一无二的
ps : 当一台计算机不止有一个网卡时, MAC地址就不能唯一对应一台计算机了. 例如, 一台计算机装了2个网卡, 一个是用于该计算机与外界通信, 而第二个网卡则用来公司内部局域网通信. 这时候虽然有两个MAC地址, 但是其实是同一台计算机.
分组交换
由于数据在这次曾要被分割成一个一个的帧, 由于不同的链路规定了不同的最大帧长, 即MTU(最大传输单元), 凡是超出这个MTU的帧都必须被分块. 例如一台货车一次能运输5吨的货物, 而有条公路限载重2吨, 那么你只好分3次运输.
网桥
网桥工作在数据链路层, 根据MAC帧的目的地址对收到的帧进行转发和过滤.
以太网交换机
实际上就是一个多接口的网桥, 以太网交换机的每个接口都直接与一个单个主机或另一个集线器相连, 可以很容易实现VLAN(虚拟局域网)
以太网的MAC帧
MAC帧的格式为 :
MAC帧格式
-
目的地址 : 接收方48位的MAC地址
-
源地址 : 发送方48位的MAC地址
-
类型字段 : 标志上一层使用的是什么协议, 0x0800为IP数据报
网络层
===
如果只有数据链路层没有网络层, 数据就只能在同一条链路上传输, 不能跨链路传输. 有了网络层, 数据便能跨域不同的数据链路传输.
IP地址
IP地址又称为软件地址, 存储在计算机的存储器上, IPv4地址为32位, IPv6地址为128位
IP地址和MAC地址
-
网络层以上使用IP地址, 数据链路层以下使用MAC地址
-
IP地址是逻辑地址, MAC地址是物理地址
-
IP分组中首部的源地址和目的地址在传输中不会改变, MAC帧中首部的源地址和目的地址每到一个路由器会改变一次
IP地址分类
IP地址 = {<网络号>, <主机号>}
A类地址 : 0.0.0.0 ~ 127.0.0.0 B类地址 : 128.0.0.0 ~ 191.255.0.0 C类地址 : 192.0.0.0 ~ 223.255.255.0
划分子网之后的IP地址
IP地址 = {<网络号>, <子网号>, <主机号>}
例如某单位拥有一个B类IP地址, 145.13.0.0, 但凡目的地址为145.13.x.x的数据报都会被送到这个网络上的路由器R. 内部划分子网后变成 : 145.13.3.0
, 145.13.7.0
, 145.13.21.0
. 但是对外仍表现为一个网络, 即145.13.0.0
. 这样路由器R收到报文后, 再根据目的地址发到对应的子网上.
子网掩码
一般由一串1和一串0组成, 不管网络有没有划分子网, 将子网掩码和IP地址做按位与运算即可得出网络地址.
所有的网络都必须使用子网掩码, 同时在路由表中必须有子网掩码这一栏. 如果一个网络不划分子网, 那么该网络的子网掩码就是默认的子网掩码. A类地址的默认子网掩码为255.0.0.0 B类地址的默认子网掩码为255.255.0.0 C类地址的默认子网掩码为255.255.255.0
尽管划分子网增加了灵活性, 但是却减少了能够连接在网络上的主机总数.
构成超网的IP地址
IP地址 = {<网络前缀>, <主机号>}
使用网络前缀, 无分类域间路由选择CIDR
例如, 128.14.35.7/20, 意思是前20位为网络前缀, 后12位为主机号. 另外, CIDR把网络前缀相同的连续的IP地址组成一个"CIDR地址块"
地址掩码 : CIDR使用32位的地址掩码, 类似于子网掩码.
IP数据报
在网络层, 数据是以IP数据报(IP分组)的形式传输的
IP数据报的格式
首部前20字节为固定长度, 是所有IP数据报必备的. 后4字节是可选字段, 其长度可变.
IP数据报首部固定的字段分析 :
-
版本号 : IP协议的版本, IPv4或IPv6
-
首部长度 : 记录了首部的长度, 最大为1111, 即15个32位字长, 即60字节. 当首部长度不是4字节的整数倍时, 需要使用最后的填充字段加以填充.
-
服务类型 : 一般无用
-
总长度 : 指首部和数据之和的长度. 最大为216-1 = 65535字节. 但是由于数据链路层规定每一帧的数据长度都有最大长度MTU, 以太网规定MTU为1500字节, 所以超出范围的数据报就必须进行分片处理
-
标识 : 每产生一个IP数据报, 计数器就+1, 并将此值赋值给标识字段. 再以后需要分片的数据报中, 标识相同说明是同一个数据报
-
标志 : 占3位, 最低位记为MF(More Fragment). MF = 1说明还有分片; MF = 0说明这已经是最后一个分片. 中间一位记为DF(Don’t Fragment), 意思是不能分片. 只有当DF = 0时才允许分片.
-
段位移 : 又称片位移, 相对于用户数据字段的起点, 该片从何处开始. 片位移以8个字节为偏移单位. 所以, 每个分片的长度一定是8字节的整数倍.
-
生存时间 : TTL(Time To Live). 数据报能在因特网中经过路由器的最大次数为255次, 每经过一个路由器则TTL - 1, 为0时丢弃该报文.
-
协议 : 记录该报文所携带的数据是使用何种协议.
-
首部检验和 : 只检验数据报的首部, 不检验数据部分. 不为0则丢弃报文.
-
源地址和目的地址 : 不解释
IP层转发分组的流程
每个路由器内部都维护一个路由表, 路由表包含以下内容(目的网络地址
, 下一跳地址
).
使用子网时分组转发时, 路由表必须包含以下三项内容: 目的网络地址
, 子网掩码
和下一跳地址
.
特定主机路由 : 对特定的目的地址指明一个路由
默认路由 : 不知道分组该发给哪个路由器时就发给默认路由. 当一个网络只有很少的对外连接时使用默认路由非常合适.
路由器的分组转发算法
-
从数据报中拿到目的IP地址D, 得出目的网络地址N
-
若N就是与此路由器直接相连的某个网络地址, 则直接交付(不需要再交给其他路由器转发, 直接找到该目的主机交付), 否则 -> (3)
-
若路由表中有目的地址为D的特定主机路由, 则把数据报传给该路由器, 否则 -> (4)
-
若路由表中有到达网络N的路由, 则把数据报传给该路由器, 否则 -> (5)
-
若路由表中有默认路由, 则交给该路由器, 否则 -> (6)
-
报告转发分组出错
虚拟专用网VPN
因特网中的所有路由器对该目的地址是专用地址的数据报一律不转发, 下面有3种专用地址(虚拟IP地址)
-
10.0.0.0 ~ 10.255.255.255
-
172.16.0.0 ~ 172.31.255.255
-
192.168.0.0 ~ 192.168.255.255
假设现在公司A有一个部门在广州和另一个在上海, 而他们在当地都有自己的专用网. 那么怎么将这两个专用网连接起来呢?
-
租用电信的通信线路为本机构专用, 但是太贵了
-
利用公用的因特网当做通信载体, 这就是虚拟专用网VPN
网络地址转换NAT
多个专用网内部的主机公用一个NAT路由器的IP地址, 在主机发送和接收IP数据报时必须先通过NAT路由器进行网络地址转换.
NAT路由器的工作原理
不仅如此, NAT还能使用端口号, 摇身一变成为网络地址和端口转换NAPT
ARP协议
ARP是解决同一个局域网上的主机或路由器的IP地址和MAC地址的映射问题, 即 IP地址 -> ARP -> MAC地址
每一个主机都有一个ARP高速缓存, 里面有本局域网上的各主机和路由器的IP地址到MAC地址的映射表. 以下是ARP的工作原理 :
ARP的工作原理.jpg
那如果是跨网络使用ARP呢?
-
在本网络上广播
-
未找到该主机, 则到路由器
-
路由器帮忙转发(在另一网络上广播)
-
找到了则完成ARP请求, 未找到则返回(2)
传输层
===
这一层是重中之重, 因为数据链路层, 网络层这两层的数据传输都是不可靠的, 尽最大能力交付的. 什么意思的? 就是它们不负责提交给你的就是正确的数据. 然而这一层的TCP协议将要提供可靠传输
这一层主要重点是两个协议 : UDP 和 TCP
用户数据报协议UDP
UDP主要特点 :
-
无连接
-
尽最大努力交付
-
面向报文 : 应用层交下来的报文直接加上UDP头部就往IP层扔, 不合并也不拆分
-
没有拥塞控制
-
支持一对一, 一对多, 多对一和多对多的交互通信
-
首部开销小, 只有8个字节
UDP首部
UDP首部格式
-
源端口 : 源端口号. 在需要对方回信时选用, 不需要则全0
-
目的端口 : 目的端口号. 这在终点交付报文时必须要使用到
-
长度 : UDP数据报的长度, 最小值为8(仅有首部)
-
检验和 : 与IP数据报只检验首部不同的是, UDP需要把首部和数据部分一起检验
传输控制协议TCP
TCP主要特点 :
-
面向连接的运输层协议
-
每一条TCP连接只能有2个端点, TCP是点对点的
-
提供可靠交付
-
全双工通信
-
面向字节流
TCP的工作流程
TCP字节流
TCP的连接
TCP连接的端点叫套接字(socket)
socket = (IP地址 : 端口号)
每一条TCP连接唯一地被通信两端的两个端点(socket)所确定. 即 : TCP连接 ::= {socket1, socket2} = {(IP1 : port1), (IP2 : port2)}
TCP报文段的首部
TCP报文段的首部
-
源端口和目的端口 : 同UDP端口作用
-
序号 : 本报文段的数据的第一个字节的序号
-
确认号 : 期望收到对方下一个报文段的第一个数据字节的序号
若确认号 = N, 则表明 : 到序号N-1为止的所有数据都已正常收到
-
数据偏移 : TCP报文段的首部长度
-
保留 : 以后用, 目前为0
-
紧急URG : 若URG = 1时, 说明紧急指针字段有效, 告诉系统这是紧急数据, 应尽快传送. 例如突然要中断传送
-
确认ACK : ACK = 1时确认号才有效, ACK = 0时确认号无效. TCP规定, 连接建立后所有传送的报文段都必须把ACK置1
-
推送PSH : 若PSH = 1, 则接收方收到报文段之后不再等到整个缓存满而是直接向上交付
-
复位RST : 当RST = 1, 说明TCP连接有严重错误, 必须释放连接再重连
-
同步SYN : 在连接建立时用来同步序号. 当SYN = 1, ACK = 0时表明这是一个连接请求报文段, 对方若同意建立连接, 则在响应的报文段中置SYN = 1, ACK = 1
-
终止FIN : 当FIN = 1, 表明此报文段的发送方数据已发送完毕, 并要求释放连接
-
窗口 : 告诉对方 : 从本报文段首部中的确认号算起, 接收方目前允许对方发送的数据量. 这是作为接收方让发送方设置其发送窗口的依据
-
检验和 : 同UDP, 检验首部和数据部分
-
紧急指针 : 当URG = 1时有效, 指出紧急数据的末尾在报文段的位置
-
选项 : 最大可40字节, 没有则为0
最大报文段长度MSS(Maximum Segment Size) : 每一个TCP报文段中数据字段的最大长度, 若不填写则为默认的536字节.
窗口
TCP中很重要的一个概念, 那就是窗口(发送窗口和接收窗口)
窗口
由于停止等待协议非常低效, 于是衍生出窗口这一概念. 上图为发送方维持的发送窗口, 位于发送窗口的5个分组都可以连续发送出去而不需要等待对方的确认. 每收到一个确认, 就把发送窗口前移一个分组的位置. 这大大提高了信道利用率!
接收方不必发送每个分组的确认报文, 而是采用累积确认的方式. 也就是说, 对按序到达的最后一个分组发送确认报文.
超时重传
如果发送方等待一段时间后, 还是没收到 ACK 确认报文, 就会启动超时重传. 这个等待的时间为重传超时时间(RTO, Retransmission TimeOut).
然而, RTO 的值不是固定的, 这个时间总是略大于连接往返时间(RTT,Round Trip Time). 假设报文发送过去需要5秒, 对方收到后发送确认报文回来也需要5秒, 那么RTT就为10秒, 那这RTO就要比10秒要略大一些. 那么超过RTO之后还没有收到确认报文就认为报文丢失了, 就要重传.
流量控制
利用滑动窗口和报文段的发送时机来进行流量控制.
拥塞控制
发送方维持一个拥塞窗口cwnd, 发送窗口 = 拥塞窗口.
慢开始
: cwnd = 1, 然后每经过一个传输轮次就翻倍 拥塞避免
: 让cwnd缓慢增大, 每经过一个传输轮次就+1 慢开始门限ssthresh
:
-
当cwnd < ssthresh, 使用慢开始算法
-
当cwnd > ssthresh, 使用拥塞避免算法
-
当cwnd = ssthresh, 随意
拥塞控制
只要判断网络出现拥塞, 把ssthresh设为当前发送拥塞窗口的一半(不能小于2), 并把cwnd设为1, 重新执行慢开始算法.
除了慢开始和拥塞避免算法外, 还有一组快重传和快恢复算法 :
快重传
: 接收方及时发送确认, 而发送方只要一连收到三个重复确认, 马上重传
快恢复
: 当发送方一连收到三个重复确认时, ssthresh减半, cwnd设为ssthresh.
TCP三次握手
TCP三次握手建立连接和四次挥手断开连接是面试爱问的知识点.
TCP三次握手
Q : 为什么要三次握手, 两次不可以吗?
A : 试想一下, A第一次发送请求连接, 但是在网络某节点滞留了, A超时重传, 然后这一次一切正常, A跟B就愉快地进行数据传输了. 等到连接释放了以后, 那个迷失了的连接请求突然到了B那, 如果是两次握手的话, B发送确认, 它们就算是建立起了连接了. 事实上A并不会理会这个确认, 因为我压根没有要传数据啊. 但是B却傻傻地以为有数据要来, 苦苦等待. 结果就是造成资源的浪费.
更加接地气的解释就是 : A打电话给B
第一次握手 : 你好, 我是A, 你能听到我说话吗
第二次握手 : 听到了, 我是B, 你能听到我说话吗
第三次握手 : 听到了, 我们可以开始聊天了
三次握手其实就是为了检测双方的发送和接收能力是否正常, 你说呢?
TCP四次挥手
TCP四次挥手
Q : 为什么要四次挥手, 而不是两次, 三次?
A :
首先, 由于TCP的全双工通信, 双方都能作为数据发送方. A想要关闭连接, 必须要等数据都发送完毕, 才发送FIN给B. (此时A处于半关闭状态)
然后, B发送确认ACK, 并且B此时如果要发送数据, 就发送(例如做一些释放前的处理)
再者, B发送完数据之后, 发送FIN给A. (此时B处于半关闭状态)
然后, A发送ACK, 进入TIME-WAIT状态
最后, 经过2MSL时间后没有收到B传来的报文, 则确定B收到了ACK了. (此时A, B才算是处于完全关闭状态)
PS : 仔细分析以上步骤就知道为什么不能少于四次挥手了.
Q : 为什么要等待2MSL(Maximum Segment Lifetime)时间, 才从TIME_WAIT到CLOSED?
A : 在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
更加接地气的解释 :
第一次挥手 : A告诉B, 我没数据发了, 准备关闭连接了, 你要发送数据吗
第二次挥手 : B发送最后的数据
第三次挥手 : B告诉A, 我也要关闭连接了
第四次挥手 : A告诉B你可以关闭了, 我这边也关闭了
应用层
===
应用层协议最著名的就是HTTP, FTP了, 还有一个重要的DNS
域名系统(DNS, Domain Name System)
=============================
DNS 能将域名(例如, www.jianshu.com)解析成IP地址.
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NCGrt6Hh-1715845531045)]
[外链图片转存中…(img-ozkZrY1i-1715845531048)]
[外链图片转存中…(img-P56ucTAE-1715845531049)]
[外链图片转存中…(img-mcrbWxs8-1715845531050)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!