两种交换方式
- 分组(packet)交换
不长期占用链路,将报文分组,所有分组由路由器按照目的地址丢到网络中,也就是用户不需要发送/接收分组时就不占用网络资源。 - 电路(circuit)交换
通信双方建立一条专用链路,不进行分组交换时这条链路也不能给别人用。
路由器与交换机
路由器(圆)工作在网络层(网络核心)
交换机(方)工作在链路层(网络边缘)
时延(delay)、丢包(lost)、吞吐量(throughput)
- 传播时延:两个路由器之间的时间
- 传输时延:经过一个路由器的时间
- 丢包:队列已满,分组丢失
- 吞吐量:分组来得快 还是 路由器处理得快?
时延计算
图源见水印 感谢知乎大佬!!!
类似于卡车过桥问题,传输时延是所有分组被发出所需的时间,就是第一个分组被发出到最后一个分组被发出之间的时间。结束传送的时间就是最后一个分组到达目的地的时间。
因为第一个分组到达目的地之前,最后一个分组之前的所有分组都在链路中传播着,时间被最后一个分组覆盖掉了,所以传播时延只需要关注最后一个分组。
最后一个分组在k条链路上的时延是kd。传输时延考虑的是所有比特被推出源地址的时间加上最后一个分组被k-1个路由器推出的时间之和。(处理时延应该与这个类似,但题目大多不考虑处理时延和排队时延。)
感觉竖着画会更清楚(图源https://blog.csdn.net/vavid317/article/details/125992380 )
因为只考虑传输时延和传播时延,所以每一次转发时所有分组都是一个接一个(无缝衔接地)被发出去的。可以看出只有第一次(从源主机)被发出时,时间是分组数个传输时延+1个传播时延,后续每经一次转发,时间都是1个传输时延+1个传播时延。
所以当有n个分组,m段链路,且传输时延是d1,传播时延是d2时,总时延 = n * d1 + (m - 1) * d1 + m * d2
其他指标
流量强度 I = (L * a) / R
L是分组长度,a是每秒到达几个分组,R是链路带宽。
带宽时延积 = R·tprop
带宽时延积表示的是任一时刻链路上具有的最大比特数。
比特宽度 bitWidth = 链路长度 / 比特数 = 链路长度 / (带宽 * 传播时延)
协议分层(layer)
物理层是第一层,应用层是第五层。自顶向下就是从应用层开始讲
- 物理层
数字信息->信号
把一个个比特从一个节点传到另一个节点 依据链路 - 链路层
单位:帧(frame)
找到物理层发来的一堆比特中的开始和结束标识,分成一个个帧继续传输。
需要依赖MAC地址 - 网络层
网络层是不可靠的。可能发生丢包等。
单位:数据报(datagram)
依赖IP地址
协议:IP协议
从一台主机移动到另一台主机 - 运输层
单位:报文段(segment)
协议:TCP,UDP
TCP:有拥塞控制机制,长报文划分为短报文(可以在网络层的不可靠服务基础上提供可靠服务给应用层)
UDP:不必要的事情绝对不做(向应用层提供的服务仍然是不可靠的)
运输层需要区分不同报文段要去向目的主机的哪一个应用(进程)。 - 应用层
单位:报文(message)
就是人直接接触到的层。
协议:HTTP,SMTP,FTP
TCP协议
面向连接的、可靠的、基于字节流的传输层协议。
面向连接:TCP只能是一对一的两点连接,不能像UDP一样支持一对多和多对多通信。且UDP是无连接的,也就是不会在通信之前建立连接。
字节流:TCP传输的数据没有“边界”,但可以保证有序。UDP按包发送,可能有丢包或乱序。
TCP首部有选项,可变长。UDP首部长度固定。
UDP校验和
(图是盗的,但这张图讲的超级清楚)
UDP首部有4个部分,每部分2字节,分别是:源端口号、目的端口号、数据报长度和校验和。
还有一个12字节长的伪首部,包括:源IP(4)、目的IP(4)、协议类型(本来只有1字节,但需要补上一个字节的0)、数据报长度(2字节,等于首部中的长度)。
发送方用0填充待填充的部分,然后把伪首部、首部和数据部分二进制求和再取反,结果填入检验和字段,然后去掉伪首部,发送。
接收方先填上伪首部(伪首部的信息都是接收方可以知道的),然后计算校验和,若全为1则无差错,有0则有差错。
注意:校验和能检测出所有的1位错误,但2位错误可能恰好被抵消而无法被检出。
为什么用的是反码,而不是补码或者原码?
- 不依赖系统的大端小端。发送方和接收方都不需要调用网络字节序转换的相关函数,因为利用反码求和时,交换16位数的字节顺序,得到的结果只有字节顺序相应发生变化;若是原码或补码,所得结果可能大不相同。
- 计算和验证校验和比较简单快速。IP报文传输过程中经常只对RTT进行-1操作,转发报文时就可以直接增加校验和,不用重新进行计算。(不过计算机都是用补码进行数据存储,为什么不是用补码更方便代码实现呢?这个问题还是不懂)
回退N步GBN
- GBN发送方响应以下三种事件
- 上层调用
如果窗口未满,发送;对于发送方,能发的最大分组数为N - (nextseqnum - base);如果窗口已满,发送方可能:返回数据给上层,隐式表示窗口已满;或缓存上层数据;或用同步机制,仅允许上层在窗口不满时调用。 - 接受ACK
- 超时
发送方只有一个计时器,计时对象是发送方的base,每当base+1,计时器重启。如果计时器超时,重传所有已发送但未确认的分组。
- GBN接收方
- 累积确认
- 只需要维护下一个按序接收的分组号。
- 只需要接收按序分组,对于失序到达的分组直接丢弃不必缓存。
选择重传SR
- SR发送方
- 接收上层数据
如果未满,直接发送;否则缓存数据或将其返回上层。 - 超时
每个分组都有自己的计时器,超时后只发送一个分组。 - 收到ACK
- SR接收方
- 收到[rcv_base - N, rcv_base - 1]的分组
发送ACK,说明这是已接收的旧分组(意为如果发送方收到这个ACK就不要再重传这个分组)。 - 收到[rcv_base, rcv_base + N - 1]的分组(即当前在窗口中的)
发送ACK。 - 其他情况
直接忽略该分组。
TCP拥塞控制
慢启动
每收到一个确认,cwnd增加1个MSS。也就是每经1个RTT,cwnd翻倍。
- 出现超时:cwnd设置为1,开始慢启动;cwnd阈值设为出现超时时的cwnd的一半
- cwnd等于ssthresh:进入拥塞避免模式
- 收到3个冗余ACK:快速重传,快速恢复
拥塞避免
每个RTT把cwnd增加1个MSS。
- 超时:cwnd设为1MSS,ssthresh设为超时时的一半
- 3个冗余ACK:进入快速重传
快速重传
- ssthresh = (收到3个冗余ACK时的cwnd / 2)
cwnd = ssthresh + 3 - 重新进入拥塞避免
快速恢复(与快速重传结合使用)
- 重传丢失的报文段(就是“快速重传”)
- 等待,每收到1个冗余ACK,cwnd增加1个MSS
- 收到新的(不是快速重传中重传的)ACK时,cwnd设置为快速重传中的ssthresh,再次进入拥塞避免
Reno & new Reno
区别主要在快速恢复阶段。Reno只要收到一个重传包的ACK,就会退出快速恢复,重新进入拥塞避免;new Reno会等到收到所有重传包的ACK后才退出快速恢复。
状态转换
- 慢启动过程:每一轮把cwnd翻一倍
- 若cwnd == ssthresh,转移到拥塞避免
- 若超时,ssthresh设成当前轮(已经翻了一番之后的)的cwnd的一半,cwnd设为1,重新开始慢启动
- 若出现3个冗余ACK,执行快速重传和快速恢复
- 拥塞避免过程:每一轮把cwnd+1
- 若超时,ssthresh设成当前轮(已经翻了一番之后的)的cwnd的一半,cwnd设为1,重新开始慢启动
- 若出现3个冗余ACK,ssthresh设成当前轮cwnd的一半,cwnd设成修改后的ssthresh+3,转入快速恢复
- 对于Tahoe:超时或3个冗余ACK都会直接重启慢启动
- 快速恢复过程:每收到1个冗余的ACK,把cwnd+1【这个+1是因为这个过程中在等待重传的ACK,前面的包还没被确认导致窗口被锁死不能向后滑动,如果不增大cwnd以营造窗口右滑的效果,会导致最后陷入”几乎不再发送新包“的状态】注意这里是指数型增,不是加性增
- 对于Reno:只要收到一个重传包的ACK,就把cwnd设为(转入快速恢复时的)ssthresh,并转入拥塞避免【降低cwnd是为了抵消上面为营造窗口滑动效果而每轮给cwnd加的1】
- 对于new Reno:收到所有重传包ACK后转入拥塞避免
- 若超时,ssthresh设成当前轮cwnd的一半,cwnd设为1,重新开始慢启动
- 若出现3个冗余ACK(此情况只对Reno有效,因为new Reno的目的就是在这个过程中解决完所有的冗余ACk问题所以会直接忽略),ssthresh设成当前轮cwnd的一半,cwnd设成修改后的ssthresh+3,重新执行快速恢复【存疑????没找到确切答案】
各种服务的默认端口
21 FTP
22 SSH
23 Telnet
25 SMTP
53 DNS
67 DHCP
80 HTTP
110 POP3
143 IMAP
3306 MySQL
6379 redis
迭代和递归(DNS查询)
迭代:你问我,我不知道,但我让你去问他;然后你再去问他,他也不知道,他让你问别人;你问别人,别人告诉了你。
递归:你问我,我不知道;所以我去问他,他也不知道;他再问别人,别人告诉他,他告诉我,我告诉你。
迭代中的查询者得到很多不同人的回答,越来越接近正确答案;递归中的查询者只得到一个最终答案的回答。
DNS的各种记录
- A记录:(主机名,IP地址)
- CNAME记录:(别名,规范名)
- NS记录:(域名,该域名的权威服务器名)
- MX记录:(域名,邮件服务器)
CIDR 无类别域间路由选择
IP地址分成网络号和主机号两部分。
子网掩码的作用是区分这两个部分。
例如a.b.c.d/x,x指示的就是子网掩码部分的位数。
子网掩码必然满足的规则:所有1连续,所有0连续,且所有1在所有0的左侧。
- 网络号:IP地址与子网掩码进行按位与
- 主机号:IP地址与子网掩码的反码进行按位与
- 广播地址:把网络号的从最右侧开始(32 - x)位全部填上1.广播地址用于向该子网的所有主机同时进行发送。
- 子网中的可用IP地址范围:网络号 + 1 ~ 广播地址 - 1
- 已知IP地址和子网掩码,计算一个网段被划分成了几个子网:
先看子网掩码有几个255;假设有2个255,说明这个掩码在B类范围内。B类网络默认用16位来表示可分配的IP地址(主机号部分)。然后再看这个掩码的第三段有几个1,假设有n个1,则这个网段被分成了\(2^n\)个子网。其他两类与此类似。每个子网都有一个广播地址。这些子网段中,去掉\(2^n\)个网络地址和\(2^n\)个广播地址,剩下的都是可用的主机地址。 - 路由聚合:路由聚合就是把一些子网聚合起来,减小路由表规模。需要把所有子网地址进行比较,找出高位所有连续相同的位数,从开始有不同的位置到最后一位全部填0.结果就是聚合后的IP。