计算机网络 #
一、网络体系结构 #
- 分层原因:独立(更容易实现和维护)、标准化的制定
- 表示层的作用:数据转化,比如加解密、压缩和解压缩。如视频
- 会话层的作用:会话控制
二、传输层 TCP、UDP #
1-1、三次握手 #
- 服务端首先处于LISTEN状态,等待客户端的连接请求。
- A 向 B 发送连接请求报文,SYN=1,ACK=0,选择一个初始的序号 x,发送完毕后,客户端就进入SYN_SENT状态
- B 收到连接请求报文,进行第二次握手,向 A 发送连接确认报文,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 y。然后服务端进入SYN-RCVD.
- A 收到以后,进行第三次握手,向 B 发出确认报文,ACK=1,确认号为 y+1,序号为 x+1。然后进入ESTABLISHED状态,当服务器端收到以后,也进入ESTABLISHED状态。
1-2、为什么是三次握手,不是两次? #
为了防止已失效的连接请求报文段突然又传送到了服务端,从而产生错误。
- 第一次握手请求,滞留,连接释放以后的某个时间到达。
- 服务端以为是新的连接请求,发确认报文,同意建立连接。
- 假设不采用“三次握手”,只要服务端确认了,新的连接就建立了。
- 但事实上客户端并没有,因此不会管服务端。但服务端一直等待数据,资源白白浪费。
从另外一个角度看,这个问题的本质是信道是不可靠的,但是通信的双方为了保证传输是可靠的,三次通信是理论上的最小值。例如TCP的可靠连接核心就是靠seq序列号来完成的。A会向B同步自己的初始序列号,B也会反过来向A同步自己的初始序列号,并且TCP规定,必须经过确认,也就是…
1-3、如果第三次握手报文丢了,会怎么样? #
如果第三次握手报文丢了,A发完后就进入Established状态,但B还是SYN-RCVD:
- 如果双方都没有数据要发送,则B会周期性超时重传;
- 如果A有数据要发给B,会发送 Data + ACK, B就会进入Established状态,并接受数据;
- 如果B有数据要发给A,发不了。同1.
2-1、四次挥手 #
- 第一次挥手。客户端向服务器端发送一个FIN报文,通知服务器,我已经没有数据要发送了,进入FIN_WAIT_1状态。
- 第二次挥手。服务端返回一个ACK报文,告诉客户端,我知道你已经没有东西要发送了,但我还要再确认一下我是不是还有东西要给你。然后服务器端进入CLOSE_WAIT状态。客户端接收到确认包之后进入FIN_WAIT_2状态。此时TCP 属于半关闭状态,B 能向 A 发送数据但是 A 不能向 B 发送数据。
- 第三次挥手。服务器判断自己也没有数据需要发送给客户端,就向客户端发送ACK和FIN消息,告诉客户端,好了,我也没有东西要给你了,你可以关掉这个连接了。然后服务器端就进入了LAST_ACK状态。
- 最后是第四次挥手。客户端发送确认报文。发送完以后,进入TIME_WAIT状态,等待 2 MSL以后,关闭连接,进入CLOSED状态。服务器端接收到确认包以后,也关闭连接,进入CLOSED状态。
2-2、为什么要四次挥手? #
是为了确保客户端和服务端双方都能通知对方释放连接。
其中第二次挥手之后,服务端进入 CLOSE-WAIT 状态:让服务器端把还没发送完的数据发送过去。等发送完之后,再发送 FIN 连接释放报文。
2-3、为什么要等2MSL时间? #
客户端进入TIME_WAIT状态,而不是直接进入 CLOSED 状态的原因是为了确保最后一个确认报文能够到达。如果客户端发送的第四次挥手的报文丢了, B 没收到 A 发送来的确认报文,那么就会重新发送第三次挥手的报文,等待一段时间就是为了处理这种情况的发生。
3、TCP怎么保证可靠传输? #
- 用三次握手、四次挥手,保证传输的信道是可靠的
- 采用连续ARQ协议,超时自动重传
- 滑动窗口进行流量控制
- 拥塞控制
- 校验和
- 序列号
4、知道超时重传机制吗? #
停止等待协议:过了timeout时间,还没收到ACK确认号,就重发。
具体来说:
- A维护一个计时器,如果出现分组差错或者分组丢失,就超时重传
- 如果应答丢失或者应答迟到,就丢弃/补上确认等等。
5、怎么进行流量控制的? #
流量控制:为了让接收方能来得及接收。用大小可变的滑动窗口进行流量控制。(连续ARQ协议)
接收方给发送方回ACK报文时,把窗口大小写进去。如果窗口为 0,则发送方不能发送数据。
滑动窗口:
- 发送窗口:已发送并确认、已发送未确认、待发送、不能发送
- 接受窗口:已确认并交付、允许接收的、不许接收的
6、怎么进行拥塞控制? #
拥塞控制:降低整个网络的拥塞程度的同时,最大可能性地利用带宽。TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
- 慢启动技术。如果连接建立好,一上来就给对端发大量的报文,可能无法到达,并造成网络拥塞。慢启动技术是开始会发很小的报文给对端,收到对端的ACK判断可达后,会不断加倍发送给的报文量。
- 直到到达一个门限值,就进入拥塞避免,每次只加1。如果出现超时,则门限值就变为超时的时候的拥塞变量的一半,重新回到满开始。
- 如果出现丢包问题,收到三个连续的重复的确认报文,无需等待,直接重传,就是快重传。
- 快恢复是说让门限值变为之前拥塞变量的一半,然后直接进入拥塞避免,拥塞变量即为门限值,每次加1.
发送方维护一个拥塞窗口变量。
- 初始为1,收到ACK,指数增长。
- 到门限值,进入拥塞避免,每次加1
- 出现超时,门限值变为超时的时候的拥塞变量的一半。cwnd重新回到慢开始
- 如果出现丢包问题,连续收到三个重复的确认报文,无需等待,直接重传。进行快重传和快恢复
- 快恢复时,门限值为之前拥塞变量的一半,拥塞变量为门限值,直接进入拥塞避免。
7、知道 TCP 的报文头吗? #
8、知道TCP的粘包和拆包吗? #
什么意思:一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送。
为什么会出现:
- 要发送的数据太少了,小于TCP发送缓冲区的大小->封装成一个大的数据包一次发送。或者接收端没有及时读取接收缓冲区的数据->一次读完
- 大于缓冲区 或 数据太大了->拆
解决:
- 发送端:数据包固定长度,
- 数据分为头部和尾部,头部大小固定,且声名数据的大小。
13、TCP 几种报文和确认机制 #
TCP看似复杂,其实可以归纳为以下5种报文:
- SYN
- Data (唯一携带用户数据)
- FIN
- Reset
- ACK
其中1、2、3分别为建立连接、数据传输、断开连接,这三种报文对方接收到一定要ACK确认,为何要确认,因为这就是可靠传输的依赖的机制。如果对方在超时时间内不确认,发送方会一直重传,直到对方确认为止、或到达重传上限次数而Reset连接。
4、5 为重置连接报文、确认ACK报文,这两种报文对方接收到要ACK确认吧?不需要!自然发送方也不会重传这2种类型的报文。
为何Reset报文不需要ACK确认?
因为发送Reset报文的一端,在发送完这个报文之后,和该TCP Session有关的内存结构体瞬间全部释放,无论对方收到或没有收到,关系并不大。 如果对方收到Reset报文,也会释放该TCP Session 的相关内存结构体。
如果对方没有收到Reset 报文,可能会继续发送让接收方弹射出Reset报文的报文,到最后对方一样会收到Reset 报文,并最终释放内存。 为何ACK报文不需要ACK确认?
这里的ACK报文,是指没有携带任何数据的裸ACK报文,对方收到这样的ACK报文,自然也不需要ACK。否则,对方为了ACK己方的ACK,那己方收到对方的ACK,也要ACK对方的ACK,这就是一个死循环,永无止息。所以为了避免这个死循环,一律不允许ACK对方的裸ACK报文。
14、介绍一下UDP? #
- 不可靠,只尽最大努力交付、无连接,效率高。
- 首部8字节:源、目的端口、校验和、长度
- 应用场景:音视频传输(涉及实时性,纠错没意义)
- 协议:DNS、DHCP、RIP
TCP和UDP的区别? #
- 可靠传输
- 面向连接
- 数据有序
- 重量级协议,速度较慢,效率较低
- 有流量控制和拥塞控制
- 首部20字节 VS 8字节
- 面向字节流VS面向报文,不合并,不拆分,保留原报文的边界。
UDP如何实现可靠传输? #
在应用层模仿TCP的可靠性传输。
- 添加seq/ack机制,确保数据发送到对端
- 添加发送和接收缓冲区,添加超时重传机制。
详细:
- 发送时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。
- 发送端收到了ack包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据。
目前有一些开源程序利用udp实现了可靠的数据传输:RUDP、RTP、UDT。
三、应用层:DNS协议 #
- 分布式数据库,主机域名和IP地址转换解析:
- 先检查浏览器缓存是否有这个域名,有就调IP地址
- 如果没有,查本地DNS缓存
- 如果没有,查本地DNS服务器
- 如果没有,本地服务器向根域名服务器发查询请求。返回:告诉要去查哪个顶级域名服务器
- 向顶级-发查请求,返回:告诉要去查那个权限域名服务器
- 向权限-发查请求,返回:对应的IP地址
- 本地-告诉主机对应的IP地址
- HTTP协议、FTP、邮件传输协议(SMTP,POP3)
四、网络层 #
主机之间的通信。选择合适的路由和交换节点。简单灵活,无连接,尽最大努力交付
IP 协议:IP地址=网络号+主机号
路由器属于网络层,用来识别IP地址根据IP地址转发数据包,有路由选择和分组转发的功能
交换机:链路层,用来识别MAC地址并根据MAC地址转发数据帧。
1、了解ARP协议吗? #
用来做IP地址和MAC地址的转换。每个主机有一个ARP高速缓存,存着本局域网里面的各个主机和路由器的IP地址和MAC地址的映射表。
- 在同一个局域网,主机A要向主机B发IP数据报,先查A的ARP缓存。有B的就把MAC地址写到MAC帧的首部
- 如果没有,A在局域网里广播一个ARP请求分组,所有主机都收到
- B看到了,向A单播自己的MAC地址。A收到后写入缓存
- 如果不在同一个局域网,换成路由器(的MAC),转发
2-1、ICMP协议之Ping的大概过程? #
测试主机间的连通性,流程:
- 主机A向B发送多个ICMP请求报文
- 根据B返回报文的时间 和 成功响应的次数,推出数据包往返时间和丢包率
2-2、ICMP协议之Traceroute了解过吗? #
用来跟踪一个分组从源点到终点的路径。
Traceroute 发送的 IP 数据报封装的是无法交付的 UDP 用户数据报,并由目的主机发送终点不可达差错报告报文。
- 源主机向目的主机发送一连串的 IP 数据报。第一个数据报 P1 的生存时间 TTL 设置为 1,当 P1 到达路径上的第一个路由器 R1 时,R1 收下它并把 TTL 减 1,此时 TTL 等于 0,R1 就把 P1 丢弃,并向源主机发送一个 ICMP 时间超过差错报告报文;
- 源主机接着发送第二个数据报 P2,并把 TTL 设置为 2。P2 先到达 R1,R1 收下后把 TTL 减 1 再转发给 R2,R2 收下后也把 TTL 减 1,由于此时 TTL 等于 0,R2 就丢弃 P2,并向源主机发送一个 ICMP 时间超过差错报文。
- 不断执行这样的步骤,直到最后一个数据报刚刚到达目的主机,主机不转发数据报,也不把 TTL 值减 1。但是因为数据报封装的是无法交付的 UDP,因此目的主机要向源主机发送 ICMP 终点不可达差错报告报文。
- 之后源主机知道了到达目的主机所经过的路由器 IP 地址以及到达每个路由器的往返时间。
3-1、路由选择之内部网关协议 RIP #
RIP 是一种比较简单的,基于距离向量的路由选择协议。距离即跳数,直接相连的路由器跳数为 1。跳数最多为 15,超过 15 表示不可达,也就是说限制了网络的规模。
大概过程:我和相邻路由器交换自己的路由表,经过好多次交换之后,我就知道到达本自治系统中任何一个网络的最短距离和下一跳路由器地址。若 3 分钟还没有收到相邻路由器的更新路由表,则把该相邻路由器标为不可达。
优点:配置简单,开销小。
不足:网络收敛慢,跳数最大为15,限制了网络的规模。
适用:小型网络,对收敛时间不在意(如做路由实验)
3-2、路由选择之 OSPF 协议 #
开放最短路径优先 OSPF,是为了克服 RIP 的缺点而开发出来的。
方法是洪泛法,毫无保留第将消息传递到本自治系统中的所有路由器(而RIP只知道邻居告诉自己的消息)。并且只有当链路状态发生变化时,路由器才会发送信息。优点:所有路由器都具有全网的拓扑结构图,并且是一致的;收敛很快。
不足:分享的信息太多、太精确了。也无法做路由过滤。
使用:自治系统内部
3-3、外部网关协议 BGP #
用于自治系统之间的通信。有强大的路由策略、路由过滤功能。比如运营商之间的路由过滤,对流量实现优化和调度。
并且可以容纳超大容量的路由条目,配置比较复杂。
基于TCP连接。
4、路由分组转发的流程是怎么样的? #
从数据报的首部提取目的主机的 IP 地址 D,得到目的网络地址 N。
- 如果我和 N 直连,就直接交付;
- 若有到达网络 N 的下一跳路由,则转给下一跳路由器;
- 若有默认路由,转给默认路由器;
- 报告转发分组出错。
五、数据链路层与物理层1、链路层的功能? #
链路之间的通信。为同一链路的主机提供数据传输服务
差错检测:循环冗余检验CRC
MAC地址:48位,唯一表示网卡
PPP协议2、物理层都有什么?
传输数据比特流
3种通信方式(单工,半双,全双)
带通调制:数字信号->模拟信号