原稿:语雀 · 计算机网络 · 原目录:Web & 浏览器 › 计算机网络
有时候感觉自己不是能写出《劝退宝典》的人,很多东西已经完全忘干净了🆒
网络协议栈
所有各层协议合称协议栈,因特网协议栈有5层,ISO/OSI模型有7层
- PDU(Protocol Data Unit):协议数据单元,是指对等层次之间传递的数据单位

因 特 网 协 议 栈 | 应用层 | 支持网络程序,是网络程序及其应用层协议存留处
| ![]() ![]() |
传输层 | 在程序端点间传输应用层message
| ||
网络层 | 将称为数据报(datagram)的网络层分组从一台主机移动到另一台
| ||
链路层 | 在相邻网络节点间转递数据,其上的分组为帧(frame)
| ||
物理层 | 负责将frame中的bit运输到相邻网络元素
| ||
I S O | 表示层 | 使通信的app可解释交换数据的含义 | |
会话层 | 提供数据交换和定界与同步功能,包括建立check point和恢复 |
TCP——面向连接的传输
TCP 概览
报文段 | ![]() |
组成 | ![]() |
两台host之间的网络元素(routers,switchers)没有为连接分配cache和变量 | |
特点 |
|
TCP 连接管理
- 三次握手

第一次——客户端请求连接: 客户端随机初始化序号(client_isn),置于 TCP 首部的 seq 字段中,同时把 SYN 标志位置为 1 。把第一个 SYN 报文发送给服务端,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态 | SYN=1 seq=client_isn |
第二步——服务端确认 & 请求连接: 服务端收到客户端的 SYN 报文后,随机初始化序号(server_isn)填入 TCP 首部 seq 中,设置 ACK=1 ,ack=client_isn + 1,接着把 SYN 标志置为 1。把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态 | SYN=1 ACK=1 seq=server_isn ack=client_isn+1 |
ACK 和 ack:前者用于标注当前报文段的性质(SYN、ACK、FIN),后者用于向发送方确认已经收到的分组 | |
第三步——客户端确认 & 传输数据: 客户端收到报文后需要发送确认,ACK=1,ack=server_isn + 1 ,seq=client_isn + 1 ,最后把报文发送给服务端,连接已经建立,这次报文可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 。服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态 | ACK=1 seq=client_isn+1 ack=server_isn+1 |

第一次——客户端请求断开: 开始双方都处于 ESTABLISHED 状态。当客户端想要断开连接:客户端发出连接释放报文段,置 FIN=1,seq=u,进入FIN-WAIT-1状态 | FIN=1 seq=u |
第二次——服务端确认请求: 服务器收到客户端报文后,发出确认报文段:ACK=1,ack=u+1,seq=v,进入CLOSE-WAIT状态。客户端收到服务器确认结果后,进入FIN-WAIT-2状态。 | ACK=1 ack=u+1 seq=v |
第三次——服务端请求断开: 当服务器完成所有发送后,发送连接释放报文段:FIN=1,ACK=1,ack=u+1,seq=w,服务器进入LAST-ACK(最后确认态) | FIN=1 ACK=1 ack=u+1 seq=w |
第四步——客户端确认请求: 客户端收到请求,发送确认报文段:ACK=1,ack=w+1,seq=u+1,进入TIME-WAIT(时间等待)。经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态 | ACK=1 ack=w+1 seq=u+1 |
【问题1】为什么是三次握手,不能仅有两次? 假如不采用三次握手,那么只要 server 发出确认,新的建立就连接了,但当该 ACK 错误/冗余时,client 不会理睬 server的确认信息,也不会向服务端发送任何数据。但是server认为新的连接已经建立起来了,并一直等待 client 发来数据,这样,server的很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生, server 会因为收不到确认的报文,就知道 client 并没有建立连接 【问题2】为什么连接的时候是三次握手,关闭的时候却是四次握手? 因为当 server 收到 client 的 SYN 连接请求报文后,可以直接发送 SYN+ACK 报文。但是关闭连接时,当 server 收到 FIN 报文时,可能当前仍处于传输状态,并不会立即关闭 SOCKET ,只能先回复一个 ACK 报文,只有 server 确认所有的报文都发送完,才能发送 FIN 报文,因此不能一起发送。故需要四步握手。 【问题3】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态? 必须认为网络是不可靠的,有可能最后一个 ACK 丢失。所以 TIME_WAIT 状态就是用来重发可能丢失的 ACK 报文。2MSL 就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client 推断 ACK 已经被成功接收,则结束 TCP 连接。 |
可靠数据传输
网络层的 IP 服务不可靠,TCP 需要在不可靠之上建立可靠数据传输服务:确保一个进程从其接收缓存中读出的是无损、有序、非冗余的数据流。
rdt 实现的主要机制有:
|
GBN |
|
SR |
|
TCP 流量控制
参考链接:TCP协议的滑动窗口具体是怎样控制流量的? - wuxinliulei的回答 - 知乎
背景 | 由于TCP在 sender/receiver 都具有buffer,为了避免处理速度不一致导致 receiver buffer溢出,数据丢失,需要进行流控,使得两端速度相一致 |
实现 | ![]() |
TCP 让 sender 维护一个接收窗口(receiver window),用于提示 receiver 还有多少 buffer 可用,且全双工通信使得两端发送方各自维护一个窗口,对于发送方,即发送窗口 | |
场景 | A发送文件给B:B为连接分配RcvBuffer,B上进程定期从中读取数据,定义变量:
为了不溢出,必须保证(rwnd标识接收窗口) LastByteRcvd-LastByteRead≤RcvBuffer rwnd = RcvBuffer-[LastByteRcvd-LastByteRead] |
TCP 拥塞控制
背景 | 拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信死锁 拥塞控制是链路上的控制(堵车发生在路上);流量控制是S/R端的控制 | ![]() |
慢启动 |
| |
拥塞 避免 |
| |
快速 恢复 |
| |
UDP——无连接传输
特征 |
| ![]() |
用于 |
| |
对比 | TCP
| UDP
|
DNS解析
域名系统(Domain Name System,DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。本地DNS协议作为应用层协议,基于运输层的UDP之上,使用53端口
DNS server分层

迭代 DNS 查询
场景:纽约大学计算机系主机cis.poly.edu想知道主机gaia.cs.umass.edu的IP地址,且已知NYU计算机系的本地DNS服务器dns.poly.edu
| ![]() |
递归 DNS 查询
| ![]() |
实际应用中,caching 技术的存在使得迭代式 DNS 查询被广泛使用,caching 技术能把任何映射缓存在本地,比如 dns.poly.edu 从 RD/TLD/AD 得到的映射结果都会被保存在 local DNS server,此时内网中
- 一台host查询不同域名:第一次要转换a.edu完成后,第二次查询b.edu的IP地址,负责edu的TLD IP地址结果已经在本地,可直接从中查询下级权威server IP
- 两台host查询相同域名:内网第一台host查询a.edu后本地server缓存其IP,第二台host查询a.edu,可直接返回结果
通常在向 DNS 根服务器查询前会搜索以下缓存:
|
HTTP
参考链接:从输入URL到页面加载的过程?如何由一道题完善自己的前端知识体系!
用户和服务器之间的信息传递依赖http request和http response,前端页面的加载也是这样,因此http协议是前端学习中重要的部分
HTTP 报文结构
报文一般包括了:通用头部、请求/响应头部、请求/响应体,通用头部格式如下
Request Url: 请求的web服务器地址
Request Method: 请求方式(Get、POST、OPTIONS、PUT、HEAD、DELETE、CONNECT、TRACE)
* GET 获取资源
* POST 传输资源
* PUT 更新资源
* DELETE 删除资源
* HEAD 获得报文首部
Status Code: 请求的返回状态码,如200代表成功
Remote Address: 请求的远程服务器地址(会转为IP)
Referrer Policy: 来源页策略

GET/POST 对比
GET
POST
语义
从指定的资源请求数据
向指定的资源提交要被处理的数据
传输
缓存








