计算机网络基础
1. 计算机网络体系结构
- OSI七层:物理层,数据链路层,网络层,传输层,会话层,表示层,应用层
- 五层:物理层,数据链路层,网络层,传输层,应用层
- TCP/IP:网络接口层,网际层,传输层,应用层
TCP/UDP
TCP与UDP的特点比较
- TCP(传输控制协议)是面向连接的,提供可靠的交付,有流量控制,拥塞控制,提供全双工通信,面向字节流,每个tcp连接只能是一对一的
- UDP(用户数据报协议)是无连接的,尽可能的交付,面向报文.
TCP连接的建立与断开
TCP的三次握手
- 双方处于
CLOSED
状态,服务端主动监听,进入LISTEN
状态 - 客户端发出连接请求报文(SYN=1),并设置序列号seq为x,客户端进入
SYN-SEND
状态 - 服务端收到请求,发出报文(SYN=1,ACK=1),同时设置seq为y,ack为x+1,服务端进入
SYN-RCVD
状态 - 客户端收到服务端发来的确认报文,发出确认报文(ACK=1),设置seq为x+1,ack为y+1,客户端进入
ESTABLISHED
状态,该报文已经可以携带数据了,前两个报文都不能携带数据. - 服务端收到确认报文,进入
ESTABLISHED
状态
三次握手的原因
使用三次握手的目的是为了建立可靠的通信连接,需要确认自己和对方的发送和接受能力正常
第一次握手:客户端无法确认信息,服务端接受到报文,可以确认自己的接受能力和对方的发送能力正常
第二次握手:客户端收到确认报文,因此确认自己的发送和接受能力正常,以及对方的发送和接受能力正常
第三次握手:服务端收到确认报文,确认对方的接受能力和自己的发送能力正常
客户端 | 服务端 | |||||||
---|---|---|---|---|---|---|---|---|
自己接受 | 自己发送 | 对方接受 | 对方发送 | 自己接受 | 自己发送 | 对方接受 | 对方发送 | |
一次 | × | × | × | × | √ | × | × | √ |
二次 | √ | √ | √ | √ | √ | × | × | √ |
三次 | √ | √ | √ | √ | √ | √ | √ | √ |
第三次握手的原因
假设客户端发出的第一个连接请求在网络中延迟了.客户端选择重发连接请求,该连接请求被确认,双方建立连接,然后完成数据传输后释放连接.此时第一个延迟的连接请求到达服务端,服务端又建立一次连接,向客户端发出确认报文,客户端丢弃该报文,服务端一直在等待客户端发送数据,浪费资源.
而在三次握手的情况下,第一个延迟的报文在服务端发送确认报文,等待客户端报文时,因为一直等不到会认为这次连接请求取消.涉及到下面的确认报文丢失的情况.
TCP握手异常的情况
-
客户端第一个
SYN
丢了因为第一个SYN丢了,服务端没有收到,也就不会发送确认报文,因此客户端重发SYN
-
服务端收到
SYN
,发送的确认报文SYN-ACK
丢了对于客户端,因为没有收到确认报文SYN-ACK,会重发
对于服务端,引文没有收到确认报文ACK,会重发
-
客户端收到确认报文
SYN-ACK
,发送的确认报文ACK
丢了该情况下,客户端已经进入了
ESTABLISHED
连接状态,认为连接正常.此时服务端会重发确认报文ACK,但由于客户端认为连接已经建立了,可能会发送数据包,因此该数据包中应带上确认序列号ack,这样的话服务端在收到该数据包可以正常进入连接状态.而且本身TCP的第三次连接中就是可以携带数据的.
-
考虑极端情况,客户端故意不发送确认报文
ACK
也不发送数据包服务端会处于
SYN-RCVD
状态,一直尝试重发确认报文SYN-ACK
直到尝试上限,因此存在SYN-Flood攻击,使服务端存在大量的半连接状态的连接,影响正常的请求.
TCP的四次挥手
- 双方都处于
ESTABLISHED
连接建立的状态 - 客户端主动请求断开连接,发送请求报文(FIN=1),并设置序列号为u,客户端进入
FIN-WAIT-1
状态 - 服务端收到断开连接的请求,发出确认报文(ACK=1),设置seq为v,ack=u+1,服务端进入
CLOSE-WAIT
状态 - 此时表示客户端已经没有数据要发送了,但服务端可能还有数据要发送给客户端,客户端仍要接受,客户端接受到确认报文后,进入
FIN-WAIT-2
状态 - 当服务端的数据发送完毕后,服务端发送确认报文(FIN=1,ACK=1),设置seq为w,ack为u+1,服务端进入
LAST-ACK
状态 - 客户端收到确认报文后,发送确认报文(ACK=1),设置seq为u+1,ack为w+1,客户端进入
TIME-WAIT
状态 - 服务端接受到确认报文后进入
CLOSED
状态 - 客户端等待2MSL时间后,进入
CLOSED
状态
四次挥手的原因
主要在于服务端接受到客户端的断开连接请求后,先发送一个ACK确认报文,因为服务端可能还有数据需要发送,当书服务没有数据需要发送时,才发送FIN报文来断开服务端到客户端的连接
客户端的TIME-WAIT状态
设置该状态等待2MSL时间的原因:
- 客户端发送的最后一个确认报文可能服务端没有接受到,因此服务端会重发报文(FIN=1,ACK=1).因此客户端可以在这个等待时间内收到该重发的报文,然后再发送确认报文(ACK=1),并重启计时器
- 有足够的时间来保证本次连接中的所有报文都在网络中消失,不会影响后面新的连接
TCP挥手的异常情况(待填坑)
-
客户端第一个
FIN
丢失客户端选择重发,直到重发次数上限,然后断开连接
服务端在一段时间后没有收到任何数据,断开连接
-
服务端的确认报文
ACK
丢失客户端因为没有接受到确认报文,会重发FIN
服务端进入
CLOSED-WAIT
状态,可能会发出FIN,ACK报文,如果该报文客户端接受到了,会进入TIME-WAIT
状态 -
客户端收到服务端的
ACK
,然后服务端关闭了客户端因为处在
FIN-WAIT-2
状态,一直在等待服务端发送FIN,ACK包,当客户端等待的时间超出系统设置的超时时间后,直接关闭,进入CLOSED
状态 -
客户端收到服务端的
ACK
,然后客户端关闭了服务端此时处于
LAST-ACK
状态,尝试重发FIN,ACK包.当超过一定时间后,服务端主动断开.或者是收到客户端的RST包,也会主动断开连接 -
服务端的
FIN,ACK
丢失
TCP如何保证可靠传输
- 将应用数据分割成合适的数据块大小,并对其进行编号排序
- 通过首部数据校验和来验证数据的正确性,如果校验有差错,将丢弃该报文,且不对其进行接受确认
- 流量控制:TCP连接的双方都有缓冲空间,TCP接收端只允许发送端发送接收端缓冲区能接受的数据,当接收方来不及接受数据时,会提示发送方降低发送速率.
- 拥塞控制:当网络拥塞时,需要减少数据的发送
- 超时重传:如果在等待的时间内没有接受到该数据包的确认,将重发该数据包
1.首部校验和
发送方,起始的数据校验和为0,将首部部分和数据部分转换为16机制,然后全部相加,如果和大于ffff,则将高位部分与地位部分反复相加,直到小于ffff.然后对这个结果取反,就是发送方的校验和.
对于接收方,同发送方的计算步骤,如果计算结果为ffff,则表示数据正确.
2.拥塞控制
当网络出现拥塞时,数据包会出现丢失的情况,这时TCP需要重传数据包,如果不做拥塞控制,会继续增大网络的拥塞情况,直到整个网络死锁
因此TCP通过拥塞窗口来控制发送数据
- 慢开始:为避免大量数据输入网络,引起拥塞,应该从小到大逐渐增加发送窗口大小,初始值为1,逐次加倍
- 拥塞避免:设置一个发送窗口上限值,当以倍数增加超过该上限值时,把发送窗口的增加该为每次增加1
- 快重传与快恢复:接收方应该对已收到的有序报文段进行确认,如果收到非有序的报文段,应该立即发送重复确认.当发送方收到3个重复确认时,会认为发送的数据丢失了,然后立即重传这些丢失的数据.这就是快重传.接下来不会进行慢开始,而是执行拥塞避免算法,这就是快恢复.
3.ARQ协议
停止等待ARQ协议
- 每发完一个分组就停止发送,等待对方的接受确认.如果在一定时间内,没有收到确认,就认为分组丢失,然后重传.直到收到了确认才会发送下一个分组
- 对于接受方,如果接收到了重复的分组,应该丢弃它,然后发送确认.
- 确认丢失:发送方发送了数据,接受方接受了该数据,然后发送确认,但该确认丢失了.发送方因为在一定时间内没有收到确认,因此重传分组.接受方再次接受到该分组,是个重复的分组,因此丢弃然后发送确认.
- 确认迟到:发送方发送了数据,接受方接受了该数据,然后发送确认,但该确认在网络中延迟了.发送方因为没有收到确认,因此选择重传该分组,接受方接受了该重复分组,丢弃然后发送确认.第二次的确认发送方先接受到,然后发送方继续发送接下来的分组,然后发送方接受到第一次的重复确认,直接丢弃.
连续ARQ协议
- 发送方维持一个发送窗口,位于该窗口内的数据都可以连续发送出去,而不需要等待对方的确认.接受方对最后一个按序到达的分组进行确认,表示该分组之前的分组都已经收到.
- 如果发送方接只接受到了前一部分的确认,需要回退重新发送后面的数据.