一. 复习 - 网络原理
1. 层次划分(TCP / IP)
应用层 -> 传输层 -> 网络层 -> 数据链路层
2. 局域网内,数据链路如何通信:
数据的广播的特性(MAC 地址) / 冲突域
3. 局域网内,应用层 和 应用层之间如何通信
- 从上往下:不断封装
- 从下网上:不断解包、不断分用
4. 跨局域网的情况下,应用层 和 应用层如何通信:
5. 路由设备:
划分局域网,网关的作用
二. 复习 http 协议
应用层的最主要的一个协议
1. URL 的概念:
资源的唯一标识地址
2. 请求:
客户端发送的就是请求
3. 响应:
服务端发送的就是响应
4. C/S:
Client 是请求资源方,Server 是提供资源方。(相对的)
5. 请求格式:
这个图有个错误,空行是属于请求头的内容,详情参照响应格式的响应头
常见的方法:
默认方法为 GET
常见的方法是 GET 和 POST:区别:GET 没有请求体,POST 有请求体
6. 相应格式:
常见的状态码:三位数
1xx | 不常见 | 不常见 |
---|---|---|
2xx | 请求成功 | 200 |
3xx | 资源需要跳转 | 301/ 302/307 |
4xx | 客户端错误 | 403 / 404 / 405 |
5xx | 服务器错误 | 500/502/504 |
三. 复习socket编程
代码见我的GitHub
关于udp和tcp的 cs 套接字
四. TCP/IP 协议(传输层 + 网络层 + 数据链路层)
1. 传输层:端到端
端口 + IP
在网络上(不考虑私网):
- IP 的作用是唯一标识一台主机,主机拥有唯一的一个 IP 地址,主机可以拥有多个 IP 地址(主机里边有多个网卡)
- Port 的作用是标识主机上的唯一一个进程,一个进程可以拥有多个port,而一个port 只能属于一个进程
- 一组 IP + port 可以标识网络上的一台唯一的主机 和 该主机上的唯一一个进程
- 五元组(先不管协议):远端 + 本地
源 IP + 源端口号 + 目的 IP + 目的端口号 + 协议号
可以标识网络网络上唯一一个端对端的通信通道 - 五元组工具演示
- 常见的端口划分策略
- 建议 1024 以下的端口留给知名的一些服务用(well know),只是建议,例如:MySQL 的端口是 3306.导致监听 1024 以下的端口时,一般需要管理员。
- 常见的端口:
其他:MySQL 服务器,使用 3306 端口;
DNS 服务器,使用 53 端口。
两个问题
- 一个进程是否可以绑定多个端口号?
- 可以
- 一个端口号是否可以被多个进程绑定?
- 不行,但是有特例
2.UDP 协议
-
特性:
- 不可靠的:没有确认机制、没有重传机制;如果因为网络故障该段无法发送到对方,UDP 协议层也不会给应用层返回任何错误信息
- 面向报文:不能灵活的控制读写数据的次数和数量
- 无连接:知道目标的 IP 地址和 端口号就直接传输,不需要建立连接
-
UDP 首部
解包用的是 UDP 长度,分用用的是 源端口号
源端口号,还是
校验和
验证数据的正确性(数据在传输过程中没有发生错误变化)
若是数据发生错误怎么办?直接丢弃
- 其他知识
- UDP 没有发送缓冲区(指的是 UDP 传输层上),即UDP 不保存数据,收到数据,进行加工(套上UDP首部),就直接发送
- UDP 的发送成功代表数据已经到达了 网络层,但不代表对方收到
- UDP 有接收缓冲区
- 应用层 receive 是堵塞的
- UDP 的socket 能读能写,所以是全双工的
- 基于UDP 的应用层协议
- NFS: 网络文件系统
- TFTP: 简单文件传输协议
- DHCP: 动态主机配置协议
- BOOTP: 启动协议(用于无盘设备启动)
- DNS: 域名解析协议
- DNS(Domain Name Service)域名解析服务
即 把 www.baidu.com 变成 172.16.34.44
- DHCP:动态申请IP
DHCP / Local DNS / Gateway(网关) ------- 都是家里的路由器
3. TCP 协议:
- 3.1 TCP首部
- 目的端口用来分用,首部长度用来解包
不太重要的字段:
URG:urgent 紧急1 + 配合 16 位的紧急指针 使用
PSH:push,在发送数据时,因为有缓冲区,可以用 psh,建议别缓冲这份数据
校验和:检查数据正确性
3.2TCP 的特点:
- 可靠性:为了保证可靠性而实现一些机制
- 有连接
- 面向流
3.3 确认应答机制:
- 可靠性的第一种表述:作为一个发送方,希望知道我的数据接受方是否收到。
32位的 序号(Sequence Number,SN) 就是编号
32位的确认序号(Acknowledge Sequence Number,ASN)就是确认编号
发送的每个数据都带着 SN
如果数据中的 ACK 被置为1,标识该 TCP 包蛋确认含义(发送数据和确认含义公用的)
ASN 可以计算出收到哪些序号
- 其中,一个 TCP 的通信过程中,只有第一个 Segment 的 ACK 没有置为 1,其他全部含有 ACK 含义.
- ASN 的细节含义:希望发送端发送的下一个字节序号
- 可靠性的第二种表述:保证数据是按序收到的
汽车按照1,2,3的序号按照不能的路线发送,在到达最终结果时的顺序为:2,1,3.
TCP 利用 SN 和 ASN 可以保证 数据是按序收到的,如上例,2在1号车前边到达时,TCP可以利用SN序号,让接收方在接收了 1号车之后,在接收2号车.
SN的第二个作用
3.4 超时重传机制
向接收方发送数据,但在一定时间后,并没有收到来自接收方的确认信息
- 可能是对方没有收到我的数据,接收方之前没有收到,所以可以接收此次的重复传递
- 对方收到数据,但对方发来的应答,我没有收到,接收方重复接收,但因为有序号,所以可以直接丢弃,也没有问题
超时重传的含义:
- 超时:指的就是超过了这个估计时间
- 重传:把没有收到应答的数据重新发送一次
一定时间:估计我的话传到对方的时间 + 对方应答传回来的时间
SN的第三个作用:去掉重复包
3.5可靠性的含义:
第 0 层含义:数据不会出现错误。 By 校验和
第 1 层含义:确保发送的数据,对方有收到 By 确认应答(SN/ASN/ACK)
第 2 层含义:确保发送的数据,对方是按序收到 By SN
SN 的第三个作用:接收方可以通过 SN 去重
其中,基于确认重传机制,对于 TCP 连接中的所有 segment 都需要应答,除了 ACK 本身(应答(无数据)不需要应答回复)
3.6 TCP 的发送缓冲区 和 接收缓冲区
-
为什么要有发送缓冲区
其中一个原因,就是我发送的数据有可能需要重传,所以 TCP 需要暂时把这些数据保存到发送缓冲区
-
为什么要有接收缓冲区?
a)因为数据可能是无序到达的;b)数据到达后,应用层不是马上取走
对于 TCP 来说: -
发送成功:os.write(…);成功,代表知识数据被写入到 TCP 协议栈的发送缓冲区了,并不代表数据发送到网络上,更不代表对方已经收到
-
接收方:is.read(…);如果接收缓冲区中有准备好( 有数据,并且不能有空洞 / 数据按序接收完 ),的数据,直接返回;如果没有数据,则会一致阻塞,知道数据准备好。
-
byte[] buf = new byte[1024]; int len = is.read(buf,1024); 从应用层角度,应用层准备好了 1024 的课件,最多可以接收 1024 字节的数据,应用层不一定读到 1024 字节的数据,实际读到的数据长度是 len。
3.7 连接管理 —— 以可靠性为基础
确认应答 / 超时重传 / 发送缓冲区 + 接收缓冲区 都是 以 一条通信通道(五元组)为单元进行组织管理
例如:在 61.35.38.244 这个主机上的两个进程,他们都有各自的确认应答、有各自的缓冲区,互不干扰
问题:
- 为什么需要 TCP 连接?
因为这套机制是以不同五元组描述的通道分别管理的。- 什么是连接(Connection)
1) 抽象层面上:五元组唯一标志的一条通信通道
2)OS 层面:一个 Connection 对象,描述五元组信息 + 各种管理信息(SN / ASN + 缓冲区信息)
3)OS 通过 List / Map 把 Connection 对象组织起来
3.8 连接管理( 主要是 TCP 协议栈的视角,结合应用层代码理解 )
前提知识:理解 socket
1)套接字:OS 提供的用于应用层 和 网络协议栈进行通信的一套标准接口。
2)套接字上会绑定响应的连接,进行通信
TCP server:ServerSocket ss = new ServerSokcet(8888);
a) 新建 socket
b)绑定本地 ip + 本地 端口
c)监听(listen)
3.8.1 TCP 三次握手建立连接
三次握手要注意到的标志位:
SYN:表示建立连接,进行信息的同步
ACK:确认应答用的,表示确认之前收到的 segment ,配合确认编号(ASN)使用,空的ack不需要应答
练习题:
答案:
TCP 的状态转换
和应用层代码结合
总结常见的面试题
- 描述三次握手的过程?
- 标志位:SYN + ACK
- 状态转移
- SN + ASN
- 结合应用层代码
- 为什么是三次?
- 为什么不能两次?
C 发 SYN,S 回 ACK,S 发 SYN,C 回 ACK。不满足确认应答 - 为什么不想四次?
能少尽量少,因为 S 回 ACK 和 S 发 SYN 肯定是同时的,所以合并了
- 为什么不能两次?
- 建立连接的目的是什么?
- 为什么要有连接?
- 什么是连接?
- 建立连接主要是为了同步 ISN(初始序列号)
- 为什么 ISN 序列号必须是随机的?如果 ISN 都是 0,是不是就不需要同步了?
ISN 如果是确定的,可能会被伪造 segment 进行攻击
3.8.2 四次挥手