参加秋招前,计算机网络的一些复习笔记。
前言
由于大二期间(不懂事)没怎么听过计算机网络,以及后来的TCP/IP协议的课,现在网络原理基础非常薄弱。趁着暑假在校打多校联合训练的空隙,重拾计算机网络,并有针对性的对传输层、应用层以及网络层进行深入复习。
该篇博客主要记录复习过程中的一些知识点。侧重于协议原理和算法,对网络安全,以及偏底层的数据链路层等不作深入学习,如果有兴趣有时间再来填这个坑。
传输层
TCP 和 UDP 的应用场景
TCP是基于连接的可靠协议,适用于对数据准确性高、对速度要求相对低的场景,比如文件传输。
而UDP是无连接的,相对TCP来说更快,适用于对通讯速度相对更高、对数据准确性相对低的场景,如视频聊天。
传输层和应用层之间的联系
- 端口复用
- http = tcp + 80
- https = tcp + 443
- ftp = tcp + 21
- smtp = tcp + 25 //收邮件
- pop3 = tcp + 110 //发邮件
- rdp = tcp + 3389 //远程桌面
- dns = udp + 53 or tcp + 53
应用层协议和服务之间的关系
- 对外服务运行后,在TCP或UDP的某个端口保持侦听客户端请求。
- 用端口来定位服务,(比如80就说明要访问web服务)用IP地址来定位计算机。
UDP报文
- 目标端口、源端口、校验和
- 在网络层的时候还会添加伪首部:源地址、目标地址
- 数据包
TCP概述
- 可靠传输
- 流量控制
- 避免网络拥塞
- 字节流
- 全双工通信
- TCP的点到点连接,端点是套接字,端口号+IP地址就构成了套接字
停止等待协议
- 无差错情况:发(确认)->发(确认)->发(直到收到回复才会继续发送,否则停止等待)
- 超时重传:发(丢失)…等到超时阈值->重发(确认)->发(默认会丢,阈值内没收到回复认为没收到)
- 确认丢失:A发给B,B收到了,B发的确认A没收到,所以A认为要超时重传,此时B重复确认
- 确认迟到:A发给B,B收到了,B发的确认迟到了很久,A认为超时重传,B收到且回复,若此时迟到的回复也到了,A就忽略迟到的回复。
只要你没说你收到了,我就认为你没收到。利用这种确认重传的机制,在不可靠的网络传输上,实现了可靠的通信。
这种方法虽然简单,但是信道利用率太低。
流水线传输
- 通过连续发送多个分组,不必每次发出一个包都等待确认,提高信道利用率
- 接收方采用累计确认的方式,不必对每个包都回复,只需要回复下一个“要谁”。
TCP首部格式
源端口(2字节),目的端口(2字节)
序列号(4字节)//当前段的第一个字节在整个文件里是几个字节
确认号(4字节)//已收到结尾为y编号的段,现在请发序列号为y+1的段
数据偏移(4bit)//最多偏移40字节
固定首部有20字节
URG 紧急标识,置为1时不用排队
ACK 置为1时,确认号才有效,否则无效
SYN 用于连接请求时同步标识
RST 异常中断连接
FIN 终止连接标识
PSH 推送标识,接收方收到后直接推送给上层
通过SYN可以攻击服务器,一直请求连接,并使用不存在的源地址。
接收窗口确定发送窗口
- 接收缓存决定发送缓存的临界值,不能超,不然会导致接收方存不下(window size)。
- MSS 表示一个数据包最多的数据字节,再多就处理不了。
滑动窗口技术实现流量控制
- 以字节为单位的滑动窗口技术
- 不再stop.wait模式,只要窗口内还有字节就继续发送,窗口内的内容在被确认收到前不可删除
- 接收方收到数据包后,累计确认,不需要一条一条回复
- 接收方收到{1,2,3,4,5,6}和{10,11,12},只需要 选择确认 就行,让发送方发送{7,8,9}
- 超时重传时间的选择:$ newRTTs = (1-a)\times oldRTTs + a\times newRTT $
避免拥塞
慢启动,初始化时拥塞窗口设为1,窗口单位使用报文段
设置慢启动门限,拥塞窗口大小按指数级增长
到达门限后,改变增长方式为线性增长
出现丢包(判断拥塞),计算新的慢启动门限,为拥塞大小的一半
重新慢启动,指数增长到新的门限后线性增长
无法完全避免,只能减轻或尽量避免
快重传,接收方认为{1,2}到了{4}也到了,说明3可能丢了,这时候避免长时间等待,迅速回复3个确认,表示尽快重传{3},而不要等到超时重传
如果发送方连续收到3个确认,说明网络其实没太拥塞:快恢复
直接将拥塞窗口大小设置为门限,然后直接做线性增长(拥塞避免,加法增加)
那么重新慢启动就只在网络超时的情况下使用
TCP三次握手的过程
- TCP做到的其实是:数据的尽力传送和故障的可靠通知,并不能保证一定送达。
- 第一次握手,(ACK=0 seq=x SYN=1 ),进入SYN_SENT状态;
- 第二次握手,(ACK=1 SYN=1 seq=y ack=x+1 ),进入SYN_RCVD状态;
- 第三次握手,(ACK=1 ack=y+1)established状态。
两次握手足以完成信息交换和确认畅通,为什么需要第三次握手呢?
- 避免网络延迟带来资源浪费
TCP四次挥手的过程
- 第一次挥手,客户端主动(FIN=1,seq=u),等待服务器确认;
- 第二次挥手,服务器回复(ack=u+1, ACK=1,seq=v)此时服务器可能还有数据没法送完,客户端还要接收;
- 第三次挥手,服务器已经发完,(FIN=1,ACK=1,seq=w,ack=u+1) ,释放TCP连接;
- 第四次挥手,客户端(ACK=1,seq=u+1,ack=w+1),断开连接。
应用层
DNS域名解析系统
网络通信本质是识别IP地址的,但IP地址很难记,于是有了DNS服务器,对域名解析成IP地址然后返回给主机。
解析过程
- 在浏览器输入域名,操作系统首先会在host文件里查看有没有该域名的地址映射;
- 然后查看本地DNS解析缓存里有没有这个域名的地址映射;
- 如果都没有,就找到TCP/IP参数设置的首选DNS服务器,向DNS服务器进行查询;
- DNS服务器底下找不到,那么就采取询问根服务器的方式,根服务器就会告诉首选DNS服务器,这个顶级域名是谁来管理的,重复以上过程,直到找到域名;
- 转发模式:问上一层,上一层不知道就再问上一层,直到返回结果。
DHCP
动态主机配置,自动分配IP地址。
- 发现本机没有任何IP地址设定,发送广播请求DHCP服务器分配个地址;
- DHCP服务器收到广播后回复一个地址;
- 客户机对收到的回应选择一个进行请求;
- 服务器确定请求以及约定租约;
HTTP超文本传输协议
万维网提供分布式服务
统一资源定位符 URL:协议,域名或IP地址,端口,资源目录等
基于TCP/IP
无状态的,对于事物处理没有记忆力,遇到需要前置信息时需要重传
客户端发送请求,服务器进行响应
简单快速,只需传送请求方法和路径,http服务器程序规模小,通信速度快
无状态的解决策略:keep-alive方法,设定只要不主动断开,就等到阈值达到才断开。
http请求
请求行,消息报头,请求正文
请求行:请求方法 统一资源标识符 HTTP版本 回车换行
GET 请求获取统一资源标识符资源(直接放URL里)
POST 在标识资源后附加新数据(打包传输)
http响应
状态行,消息报头,响应正文
状态行:HTTP版本,响应状态代码,状态代码的文本描述
1 | 1xx 提示信息,请求已接收,继续处理 |
http报头
这个点在
https://mmfunnytree.github.io/2019/07/15/androidStudy/#more
的网络通信部分有见过,通过对connection的状态进行设置,如no-cache,accept等
1 | connection.setRequestProperty("content-Type","application/json"); |
还有实体报头啥的(请求和响应都可以传送实体,这里申明资源信息)
https
http的消息明文传输:
窃听风险(eavesdropping):第三方可以获知通信内容。
篡改风险(tampering):第三方可以修改通信内容。
冒充风险(pretending):第三方可以冒充他人身份参与通信。
https希望做到:
所有信息都是加密传播,第三方无法窃听。
具有校验机制,一旦被篡改,通信双方会立刻发现。
配备身份证书,防止身份被冒充。
加密策略
对称加密就是直接用一组密钥对数据进行加密,如果黑客不知道密钥就没法解密。
缺点是:在多组客户端-服务器之间,维护的密钥数量庞大,维护成本大;容易泄露。
非对称加密就是用公钥加密,用私钥解密,服务器把公钥公布。
可能被黑客冒充服务器,发送假的公钥。
使用SSL证书:在握手的时候展示SSL证书,包括发布机构、期限、公钥、签名、所有人等。