网络基础
OSI 七层协议
1. 物理层
定义了机器之间通信标准:网线类型,接口类型,各种介质的传输数率。该层为上层协议提供了一个传输数据的可靠的物理媒体。
这一层传输比特流(二进制数据),进行数模转换和模数转换。

2. 数据链路层
数据链路层在物理层提供的服务的基础上向网络层提供服务,其最基本的服务是采用差错检测、差错控制和流量控制等方法,向网络层提供高质量的数据传输服务。
在这一层的数据是帧,工作的设备是网卡、网桥、交换机。
常见的协议有 HDLC、PPP、SLIP 等。

3. 网络层
将网络地址翻译成对应物理地址(封装和解析),通过路由选择算法为通信子网选择最适当的传输路径(发送方 -> 接受方),以及实现拥塞控制、网络互连等功能。这一层的数据是数据包,工作的设备有路由器、交换机、防火墙。
主要由 IP、ICMP 两个协议组成。

4. 传输层 *
保证海量文件传输数据的准确性,传输层定义了传输数据的协议和端口号,用来对数据进行分割,传输,重组。传输层向高层屏蔽了下层数据通信的细节。这一层的数据是数据报文。
常见的协议有 TCP 和 UDP 等。

5. 会话层
会话层作用是负责建立和断开通信连接(数据流动的逻辑通路),以及数据的分割等数据传输相关的管理。
常见的协议有 ADSP、RPC 等。

6. 表示层
将应用处理的信息转换为适合网络传输的格式,或者将来自下一层的数据转换为上层能处理的格式。它主要负责数据格式的转换。具体来说,就是讲设备固有的数据格式转换为网络标准格式。
常见的协议有 ASCII、SSL/TLS 等。

7. 应用层
它的作用是为应用程序提供服务并规定应用程序中通讯相关的细节 (传输的形式),也就是为应用提供服务。
常见的协议有 HTTP,FTP,TELNET、SMTP 等。

TCP/IP
是 OSI 的实现。四层模型。不仅仅是 TCP 和 IP 协议,是一系列网络协议的总称(协议簇),如:HTTP, FTP, SMTP, DNS, UDP 等等。

应用层
对应七层协议的会话,表示,应用

传输层
对应七层协议的传输

网络层
对应七层协议的网络

链路层
对应七层协议的物理,数据链路

TCP 报文头部结构


由图可知,TCP 报文头部至少需要 20 字节长度。

源端口,目标端口
标识出目标端口,目标 IP,源端口,源 IP,就可以确定一个连接的唯一性。IP 层处理两个 IP 元组,而 TCP 层处理其余两个元组。这两个端口长度分别为两字节。

序列号
报文段第一个字节的序列号。占用四个字节。一次通信过程中,第一次序号值被初始化为一个随机值 ISN,后续的序号值将在此基础上加上该报文段所携带数据的第一个字节在整个字节流中的偏移 X,即 ISN+X。

确认号
ACK,四个字节。作为收到另一方发送的报文后的响应。值是收到对方的序号值 + 1。告知对方下一个期望接收的序列号,小于 ACK 的所有字节已经全部收到。

头部长度
4bits,表示 tcp 头部有多少个 32bits 字。4bits 最多表示 15 个数,所以头部最大可以表示 1532bits,即 154bytes,四字节。

八位标志位
常见的标记位有 SYN,ACK,FIN,RST,PSH。
含义?

窗口大小
两字节。是 TCP 流量控制的一个手段,这里说的窗口是指接收通告窗口,它告诉对方本端的 tcp 接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。

校验和
占用两个字节,防止传输过程中数据包有损坏,如果遇到校验和有差错的报文,TCP 直接丢弃之,等待重传。

紧急指针
它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。发送紧急数据时会用到。

可选项
最后一个选项字段是可变长的可选信息,最多包含 40 字节的数据。典型的 tcp 头部选项结构:

 

常用的可选项有以下几个:

TimeStamp: TCP 时间戳,后面详细介绍。
MSS: 指的是 TCP 允许的从对方接收的最大报文段。
SACK: 选择确认选项。
Window Scale: 窗口缩放选项。
TCP 三次握手
IP 无连接通信协议,不会占用两个正在通信计算机的通信线路。通过 IP 协议,数据被分割为小的独立的包,进行传输,但是无法保证数据包传输的可靠性,所以需要 TCP 保证传输的准确性。

所以三次握手是为了用于建立连接时保证可靠性和初始化流控制机制的信息,包括 初始化 Socket、序列号以及窗口大小。

三次握手才可以阻止重复历史连接的初始化
通过初始化序列号可以保证对重复的数据包进行去重、丢包重传、重排序
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

三次握手过程:
服务端开启某个端口,进入 LISTEN 状态,开始监听。
客户端主动发起连接,发送连接请求报文 SYN,完成后进入 SYN-SENT 状态
服务端接收到信息,发送回 SYN 和确认报文 ACK,进入 SYN-RCVD 状态;如果服务端未发送确认信息,则客户端重传包。
客户端接收到返回的信息,将 ACK 发送给服务端,进入 ESTABLISHED 状态,建立连接。
为什么不是两次?
如果第一次握手时客户端发送的报文滞留在网络没有到达客户端,那么客户端将重传报文从而建立连接。过程结束后,滞留的包到达服务端,此时服务端只需回传接收到的包就可以默认建立连接,但是之前客户端已经通过重传建立过连接了,从而造成了资源的浪费。

为什么不是四次
三次握手已经可以确定建立连接了,四次虽然可以,但是没有必要。如果是将服务端的 SYN 和 ACK 报文拆分成两次发送,这和一次的效果是相同的,也没有必要。

SYN Flood 攻击
首先我们需要明白什么是半连接队列和全连接队列。
服务端建立监听之后,收到客户端发送的 SYN 包,进入 SYN-RCVD 状态,并向客户端发送 ACK。此时这个连接被推入 SYN 队列,就是半连接队列。
当第三次握手时客户端发返回给服务端 ACK,两端建立连接,等待被具体应用取走前,进入 TCP 维护队列,就是全连接队列。

问题产生:
SYN Flood 攻击就是客户端伪造大量不存在的 IP 地址,向服务端不断发送 SYN 报文。随后服务端返回 ACK,大量连接处于半连接队列,造成服务端无法正常处理连接请求。
又由于伪造的 IP 地址不存在,服务端长时间收不到客户端的 ACK,使其不断重发数据,会耗尽服务端资源。

解决办法:

增加 SYN,即增加半连接队列的容量
减少 SYN+ACK 重试次数,避免大量超时重发
利用 SYN Cookie 技术,在服务端接收到 SYN 后不立即分配连接资源,而是根据这个 SYN 计算出一个 Cookie,连同第二次握手回复给客户端,在客户端回复 ACK 的时候带上这个 Cookie 值,服务端验证 Cookie 合法之后才分配连接资源。
TCP 四次挥手
断开一个 TCP 连接时的整个流程。

假设客户端主动关闭,客户端向服务端发出 FIN 报文,进入 FIN-WAIT-1 状态。此时客户端半关闭状态,只能接收报文。
服务端收到 FIN 报文,向客户端发送 ACK 确认,进入 CLOSED-WAIT 状态。客户端收到报文,进入 FIN-WAIT-2 状态。
服务端发送 FIN 报文,进入 LAST-ACK 状态
客户端收到服务端发来的 FIN 后,自己变成了 TIME-WAIT 状态,然后发送 ACK 给服务端。收到 ACK 后,服务端关闭。
此后客户端需要等待 2 个 MSL (Maximum Segment Lifetime,报文最大生存时间),在这段时间内如果客户端没有收到服务端的重发请求,那么表示 ACK 成功到达,挥手结束,否则客户端重发 ACK。
为什么最后有 TIME-WAIT 状态
保证有足够时间让被动关闭端收到 ACK
1 MSL 确保发送的 ACK 有足够时间到被关闭端
1 MSL 确保如果规定时间内对端未收到 ACK,有足够时间重传 FIN
避免新旧连接混在一起
为什么四次挥手断开连接
因为服务端在接收到 FIN, 往往不会立即返回 FIN, 必须等到服务端所有的报文都发送完毕了,才能发 FIN。因此先发一个 ACK 表示已经收到客户端的 FIN,延迟一段时间才发 FIN。这就造成了四次挥手。

如果是三次挥手会有什么问题?
等于说服务端将 ACK 和 FIN 的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为 FIN 没有到达客户端,从而让客户端不断的重发 FIN。

出现大量 CLOSED-WAIT 状态的原因?
服务器端收到客户端发送的 FIN,TCP 协议栈会自动发送 ACK,链接进入 close_wait 状态。但如果服务器端不执行 socket 的 close () 操作,状态就不能由 close_wait 迁移到 last_ack,则系统中会存在很多 close_wait 状态的连接。
解决办法就是要检测出对方已经关闭的 socket,然后关闭它。

TCP 可靠性
数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时 TCP 发送数据端超时后会重发数据;
对失序数据包重排序:既然 TCP 报文段作为 IP 数据报来传输,而 IP 数据报的到达可能会失序,因此 TCP 报文段的到达也可能会失序。TCP 将对失序数据进行重新排序,然后才交给应用层;
丢弃重复数据:对于重复数据,能够丢弃重复数据;
应答机制:当 TCP 收到发自 TCP 连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;
超时重发:当 TCP 发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段;
流量控制:TCP 连接的每一方都有固定大小的缓冲空间。TCP 的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP 使用的流量控制协议是可变大小的滑动窗口协议
UDP
一个面向无连接的传输协议。
不维护连接状态,支持同时向多个客户端传输相同消息
数据包包头 8 字节,较小
吞吐量只受限于数据生成速率,传输速率和机器性能
不保证可靠交付,无需维持复杂的链接状态表
面向报文,不对应用程序提供的报文信息进行拆分或合并
TCP 和 UDP 区别
面向连接 vs 无连接
可靠性:TCP 可靠,丢包重传;UDP 不可靠。
有序性:TCP 利用序列号保证了数据的有序性(数据到达会排序)
速度:TCP 创建连接,速率较慢;UDP 较快
TCP 流模式,UDP 报文模式
TCP 和 UDP 应用场景
TCP
当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如 HTTP、HTTPS、FTP 等传输文件的协议,POP、SMTP 等邮件传输的协议。
在日常生活中,常见使用 TCP 协议的应用如下:
浏览器,用的 HTTP;邮件,用的 POP、SMTP;文件传输

UDP
当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用 UDP。
比如,日常生活中,常见使用 UDP 协议的应用如下:语音,视频

TCP 的流量控制
简单说就是通过接收端缓存区大小,控制发送端的发送。如果接收端缓存区已满,发送端就无法进行发送。

TCP 的滑动窗口
保证 TCP 可靠性
保证 TCP 流控特性
分为两个窗口,接受窗口和发送窗口