TCP/UDP的常见面经问题

# TCP连接的建立过程

1. 三次握手

为什么要进行三次握手。

握手是为了让双方了解数据开始时的序列号,而三次是让双方达成共识的最小次数

三次握手的过程:

1. 客户端发送(SYN=1,ISN=A);//SYN_SEND

2. 服务端发送(ACK=1,SYN=1),(ack=A+1,ISN=B);//这个时候服务端知道了客户端的序列号,并且通知客户端这个事实。

3. 客户端发送(ack=B+1,seq=A+1);//SYN-SEND->ESTABLISHED,通知服务端,客户端已经了解了服务端的序列号。

三次握手结束后,客户端和服务端都保证了双方相互知道了自己的序列号,也就是数据传输的起点。

如果进行两次握手:

1. 客户端(连接主动方)传递(SYN=1,ACK=0,seq=A);

2. 服务端返回(SYN=1,ACK=1,ack=A+1,seq=B)

这时结束,那么只有客户端被通知了自己的信息已经被服务端知晓,但是服务端却无法知道自己的序列号是否被客户端知晓。

如果进行四次握手

1. 客户端:(SYN=1, ISN=A)

2. 服务端:(ACK=1, ack=A+1)

3. 服务端:(SYN=1, ISN=B)

4. 客户端(ACK=1,ack=B+1)

明显2和3可以重合。

 

半连接:服务器没有收到客户端的回应,无法从SYN-RECEIVE->ESTABLISH

1. 可能是服务端的SYN-ACK丢失了。

2. 可能是客户端的ACK丢失了。

这时,服务端会维护一个半连接的队列,等待超时重传。

 

2. 四次挥手

假设是客户端主动放弃连接

1. 客户端:发送FIN // FIN_WAIT

2. 服务端:发送ACK //CLOSE_WAIT,这时,客户端了解服务端已经关闭了连接

3. 服务端:发送FIN  //LAST_ACK

4. 客户端:发送ACK  //TIME_WAIT->(After 2MSL)CLOSE

 

半打开和半关闭:

半打开:连接中有一端的突然关闭

半关闭:

A发送FIN,B收到后发送ACK,但是B不继续发送FIN,导致A无法完全关闭连接。

 

为什么要等待2MSL

1. 防止服务端没有收到ACK

2. 等待网络中的重复数据的消失(MSL:MAX SEGMENT LIFETIME)

 

# TCP的Congestion Control

TCP通过两种方式来判断传输环境,Duplicate ACK和Time Out。当发生Duplicate ACK的时候,说明传输过程中,有个别的报文没有达到目的地,需要重新发送。 如果发生Time Out,说明网络环境非常差。

TCP在控制阻塞窗口的时候有两个重要参数,ssthresh(门槛),cwnd(窗口大小)。

当TCP处于Slow Start阶段时:

每收到一个ACK,cwnd指数增加,也就是 cwnd = (1,2,4,8.....)。

当cwnd > ssthresh,cwnd变成线性增加,也就是进入Congestion Control阶段。

当发生Timeout或者DuplicateACK时,

1. 如果使用的是Tahoe:cwnd=1,ssthresh=cwnd/2。

2. 如果使用的是Reno且是DuplicateACK时,cwnd=cwnd/2,也就是说,没有慢启动阶段,直接过度到Congestion Control。

 

滑动窗口

TCP连接通过控制滑动窗口的大小来控制传输速率。根据网络状况,滑动窗口的大小会有变化。

 

posted @ 2020-03-20 17:04  AcodingDog  阅读(325)  评论(0编辑  收藏  举报