1.首先明确一下协议存在的必要性。
计算机之间的传输媒介是光信号和电信号,通过频率和强弱来表示0和1这样的信息。要想传递不同的信息来达到双方互相交流的目的,就要约定好双方的数据格式。这种数据格式就是“协议”。
2.TCP/IP五层模型:
1.物理层:负责光/电信号的传递方式
2.数据链路层:负责设备之间的数据帧的传送和识别(以太网协议)
3.网络层:负责地址管理和路由选择(IP协议)
*4.传输层:负责两台主机之间的数据传输,它们之间的传输协议就是TCP协议,能够保证数据可靠的从源主机发送到目标主机(TCP、UDP协议)
*5.应用层:负责应用程序间的沟通(HTTP、FTP)(我们的网络编程主要就是针对应用层
3.数据包封装和分用
应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部,称为封装。首部中载有一些类似首部有多长、荷载有多长、上层协议是什么等信息。
数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,根据首部中的“上层协议字段”将数据交给对应二点上层协议处理,这就是分用。
4.应用层的HTTP协议
HTTP协议格式:
请求格式:
1.首行
a) 方法(GET/POST/HEAD/PUT...)
b)url(服务器上对某个资源定位的标志)
c)版本号(HTTP/1.1)
2.协议头(header)
每一行是一个键值对
键和值之间用“:”分割
Content_Length:表示body部分的长度
Content-Type:表示body部分的数据格式
UA:表示操作系统和浏览器的型号
Referer:表示当前页面是从哪个页面跳转过来的
Cookie:浏览器存储数据的一种重要方式 具体内容都是由对应产品的程序员自行决定,一般会包含用户身份标识(session id)
3.空行
header部分结束的标记
4.协议正文(body)
数据种类非常多,也可能为空(GET请求一般为空,POST请求一般有数据)
响应格式:
1.首行
a)版本号
b)状态码(标识这次请求是否失败,以及原因)
c)状态码描述信息
2.协议头
每一行是一个键值对
3.空行
header的结束标记
4.协议正文
协议有很多种情况
Content-Type:描述body部分的数据格式
Content-Length:描述body的长度
Q:GET方法和POST方法的区别?
A:数据是放在query_string还是body中
5.传输层
传输层主要关注的是点对点之间的传输,只需要关注发送者和接收者,中间的传输过程一概不管。
5.1 UDP协议
三个特性:
1.无连接 知道对端的IP和端口号就直接进行传输,不需要建立连接
2.不可靠 没有确认机制,没有重传机制
3.面向数据报
报文格式(长度最多64k):16位源端口号 16位目的端口号 16位UDP长度 16位UDP校验和(比较简短,和内容相关联 就相当于自个记七种耦合的方法)
缺点:UDP报文长度最多64K ,这就限制了应用层协议的数据长度,一旦数据长度超过了UDP的表示范围,就会出现问题
5.2 TCP协议
三个特性:
1.有连接
2.可靠传输 发送者能感知到失败
3.面向字节流
TCP最核心的机制:1.可靠传输 2.尽量提高传输效率
十大特点
一、确认应答(可靠的核心机制)
序号,是按照每个字节的方式来编号的
确认序号,表示当前序号之前的数据已经正确收到了
二、超时重传(和确认应答相辅相成)
如果对方没有确认应答,那么隔一定的时间之后就要重复传输这样的数据。间隔时间采取比较悲观的态度。
达到一定次数还没有回应,就断开和对方的通信链接
如果应答数据包丢失,同样会超时重传
三、连接管理
建立连接的意义:
双方先试探下对方是否适合和我进行通信
双方协商重要数据,比如序号从几开始
都是全双工(双向通信)
中间件:一些特定功能的服务器,这些服务器程序和业务无关,数据库就是中间件
消息队列是一种特殊的队列,引入了类型概念
四、滑动窗口(提高传输效率)
窗口的含义是:不等待ACK的情况下最多发多少数据
滑动的含义是:每次收到ACK数据的同时,就继续往后发下一组数据
如果窗口越大,传输效率越高
窗口也不能无限大。如果窗口太大,可能会影响到可靠性
如果出现丢包怎么办?
ACK丢了:部分ACK丢了不要紧,可以通过后续的ACK进行确认
数据包丢了:接受方会发出连续多次的确认应答,发送方收到重复应答后,就知道数据包丢了,会进行重发
滑动窗口中如果丢包,采用快速重传的方式来进行重传。重传时只重传真正丢了的数据
五、流量控制
窗口越大,传输效率越高,但是窗口也不能无限大。如果窗口太大,接收端处理不过来
生产速度超过了消费速度,接收缓冲区的内容就会越积越多,达到一定程度,缓冲区满了,此时再传输的数据就会丢包
使用接受缓冲区空余空间的大小,用这个指标衡量接收端的处理能力。
通过这个指标控制发送端的窗口大小(发送速度)
接收端的缓冲区空余空间大小,作为TCP协议报头中的窗口大小,这个值就是发送端的滑动窗口大小的一个建议值
TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是 窗口字段的值左移M位
六、拥塞控制
滑动窗口的窗口大小不能无限大。即使接收端处理速度很快,也可能因为网络环境不佳导致数据丢包
最终的滑动窗口大小是由流量控制和拥塞控制共同决定的
拥塞窗口:拥塞控制机制所建议的窗口大小,从一个比较小的数字开始。如果网络通畅,放大窗口大小;如果网络丢包,缩小窗口大小。
滑动窗口的最终值就是 流量控制的窗口 和 拥塞窗口 的较小值
慢开始:刚开始传输的时候拥塞窗口设置的小一些,然后呈指数增长,设置阈值,当达到阈值后,按照线性方式增长
七、延时应答(提高传输效率)
在可靠性的基础上尽量提高窗口大小。
也是和滑动窗口以及流量控制相关
流量控制中需要在ACK中反馈接收缓冲区剩余空间的大小
此时采取的策略是:收到数据不立刻返回ACK,而是等一会。等的过程中,程序就能多消费一些缓冲区中的数据,从而导致反馈的窗口大小就要更大一些。
八、捎带应答(使四次挥手变成三次)
建立在延时应答的基础上
内核反馈ACK的实际和程序反馈响应的时机合二为一。通过同一个数据报同时带上两方面的信息
九、面向字节流
粘包问题:由于面向字节流读取数据方式没有具体的约定,很难从接收缓存区中直接获取到一个完整的应用层数据报
解决粘包问题只能从应用层入手:只要在应用层协议设定的时候明确包的边界就可以了
确认边界的两种方法:1.指定分割符 2.指定包的长度
十、异常情况
1.程序异常结束(没啥影响,四次挥手正常完成)
2.系统关机(没影响,本质上要强制关闭所有程序)
3.主机掉电/拔网线
3.1掉电的是接收方,发送方会触及超时重传,尝试重新建立连接,彻底释放连接
3.2掉电的是发送方,接收方如果一直收不到数据,达到一定时间,就会给对方发送一个“心跳包”,若无心跳就会尝试重新建立连接,如果连接建立失败,彻底释放连接
6.三次握手与四次挥手
三次握手:双方各自向对方提出连接请求并得到回应 A请求——>B回应并请求——>A回应
客户端向服务器发请求:SYN(同步报文段)
服务器向客户端返回信息:ACK(确认报文段)+SYN
客户端向服务器:ACK
ACK是由操作系统内核发送的 SYN也是由操作系统内核发送
三次握手中涉及到的状态变化:
1.LISTEN状态(服务器的一个状态) 类似于手机开机并且信号良好
2.ESTABLISHED(客户端和服务器都能进入的状态) 电话拨通后对方接听了
四次挥手:双方各自向对方发送FIN,再各自向对方发送ACK,中间两次可能合并
ACK是由操作系统内核发送的 FIN是由用户代码控制的,执行到socket对象的关闭方法的时候,才会发送FIN
四次挥手的状态转换:
1.CLOSE_WAIT状态:收到第一个FIN的一方进入CLOSE_WAIT,是为了等待代码中调用 关闭 方法
如果发现服务器上出现大量CLOSE_WAIT状态,意味着代码有bug,忘记调用close方法了
2.TIME_WAIT:主动断开链接的一方将进入TIME_WAIT状态,存在的意义是为了一旦最后一个ACK丢包,可以进行重传FIN
TIME_WAIT会存在一定的时间,在超出这个时间后,TIME_WAIT才会消失,释放对应的链接
MSL表示互联网上任何两点之间传输数据的最大时间。
网络层
Q:IP协议做什么?
A:地址管理和路由选择
主机:配有IP地址,但是不进行路由控制的设备
路由器:即配有IP地址,又能进行路由控制
节点:主机和路由器的统称
IP地址分为两个部分,网络号和主机号。网络号可以保证相互连接的两个网段具有不同的标识,主机号是每台主机具有唯一性的标识,在同一网段内主机之间具有相同的网络号,但主机号绝对不同