目录
- 计算机网络八股(三)
- 传输层
- 1:说一下tcp的头部?
- 2:tcp三次握手的过程说一下?
- 拓展linux中查看tcp状态:
- 3:tcp为什么需要三次握手建立连接?
- 4:tcp三次握手,如果客户端发送的第三次发送的确认包丢失了怎么办?
- 拓展:服务端发送第二个报文后处于什么状态?
- 5:三次握手和accept有什么关系,accept做了什么?
- 6:客户端发送的第一个syn服务端没有收到怎么办?
- 7:服务端收到了syn报文,但是回复的syn-ack报文丢失了怎么办?
- 8:假设客户端重传了syn报文,服务端又接收了重复的syn报文怎么办:
- 9:第一次握手客户端发送syn报文,服务端回复ack报文,这个过程服务端内部发生了什么?
- 10:当有大量的syn包发送给服务器会发生什么?
- 拓展:如何避免syn攻击?
- 11:tcp四次挥手的过程说一下?
- 12:为什么四次握手的中间两次不能合并成一次?
- 13:第二次握手和第三次握手可以合并嘛?
- 14:如果第三次握手一直没法会发生什么?
- 15:在第二次握手和第三次握手之间,主动断开的那一方能干什么?
- 16:断开连接时,客户端的fin报文丢失,服务端的状态是什么?
- 17:为什么四次挥手后要等待2msl?
- 18:服务端出现大量timewait有哪些原因?
- 19:tcp和udp的区别?
- 拓展:udp和tcp的应用场景?
- 20:tcp为什么可靠传输?
- 21:怎么用udp实现http?
- 21:怎么用udp实现http?
计算机网络八股(三)
传输层
1:说一下tcp的头部?
tcp的头部包括源端口号和目标端口号;
还包括序列号和确认应答号。还要一些状态位;
序列号:在tcp建立连接时,会生成一个随机数作为序列号随着syn包发送出去,此后没发送依次数据这个序列号就会加1,这个是用来解决包乱序的问题;
确认应答号:表示下一次期望收到的数据的序列号,收到确认应答号可以任务,确认应答号之前的数据已经被成功接收,用来解决丢包的问题;
常见的状态位:
ack:为1表示确认应答;
rst:为1表示因为异常需要强制断开链接;
syn:为1表示希望建立连接
fin:为1表示期望断开连接;
2:tcp三次握手的过程说一下?
刚开始服务端和客户端都处于closed状态;
1:首先服务端先变更成listend状态;
2:第一次握手,客户端请求连接,发送syn报文,报文中的序列号为客户端生成的随机数,状态位中syn为1,然后客户端状态变更为syn-sent;
3:第二次握手,服务端接收到请求,发送syn,ack报文,报文中序列号为服务端随机生成的,确认应答号为客户端序列化加1,然后状态位中syn和ack都置为1,服务端的状态变更为syn-rcvd;
4:第三次握手,客户端接收到服务端的syn-ack报文,发送ack报文,报文中确认应答号为服务端序列号加1.然后状态位ack为1,然后客户端处于established状态,第三次握手可用携带客户端到服务端的数据;
5:服务端收到后也变为established状态;
拓展linux中查看tcp状态:
netstat -napt
3:tcp为什么需要三次握手建立连接?
1:避免重复历史连接的初始化:比如客户端发送了syn报文,然后syn报文因为网络阻塞了,这时客户端又宕机了,重启之后重新发送syn报文,这个适合原先阻塞的syn报文提前到达,然后服务端返回syn-ack报文,客户端接收后发现和自己发送的不一样会发送rst报文断开连接;如果是二次握手:那么服务端就已经建立连接了,浪费了资源;
2:三次握手才能同步客户端和服务端的序列号:客户端发送序列号,然后服务端确认序列号,发送自己的序列号,然后客户端确认服务端的序列号;
3:三次握手避免资源的浪费:两次握手只要客户端发送syn报文,服务端收到后都会建立连接,浪费了资源。如果客户端发送syn报文堵塞了,重复发送多个,那么就会建立很多冗余的连接;
4:tcp三次握手,如果客户端发送的第三次发送的确认包丢失了怎么办?
tcp第三次握手发送报文后进入了连接状态,但是丢失了,而且ack报文不会重传;
服务端没有收到ack报文此时还处在syn-rcvd状态如果长时间没有接受到ack报文,服务端就会认为自己发送的ack-syn报文丢失了,就会触发超时重传机制,因为ack报文不会重传,服务端重传达到最大重传次数的时候就会主动断开连接;
拓展:服务端发送第二个报文后处于什么状态?
5:三次握手和accept有什么关系,accept做了什么?
tcp完成三次握手后,会把连接存入全连接队列,调用accept就是把连接取出来提供给用户使用;
6:客户端发送的第一个syn服务端没有收到怎么办?
客户端发送了syn报文后,就会等待服务端的syn-ack报文,如果长时间没有收到syn-ack报文,客户端就会认为自己发的报文丢失了,从而触发超时重传机制,直到收到syn-ack报文或者达到最大重传次数;
7:服务端收到了syn报文,但是回复的syn-ack报文丢失了怎么办?
作为客户端,客户端发生了syn报文在等待syn-ack报文,但是syn-ack报文丢失了,客户端就会认为自己发送的syn报文丢失了,就会触发超时重传机制,重新发送syn报文,达到最大重传次数就会断开连接;
作为服务端,自己发送了syn-ack报文,等待ack报文,但是syn-ack报文丢失了,因为长时间没有收到ack报文,服务端就会认为自己发送的syn-ack报文丢失了于是就会触发超时重传机制,重新发送syn-ack报文,达到最大重传次数就会断开连接;
8:假设客户端重传了syn报文,服务端又接收了重复的syn报文怎么办:
会进行第二次握手,发送syn-ack报文
9:第一次握手客户端发送syn报文,服务端回复ack报文,这个过程服务端内部发生了什么?
当服务端接收到客户端的syn报文,在内核中服务端会将该连接放入半连接队列,并回复syn-ack报文,当完成三次握手,服务端收到ack报文时,会将连接从半连接队列取出加入到全连接队列,调用accept可以将连接从全连接队列取出提供给客户端程序使用;
当半连接或者全连接队列满了时,内核会自动丢弃连接,返回rst包;
10:当有大量的syn包发送给服务器会发生什么?
当有大量的syn包发送给服务端,会迅速占满半连接序列,导致后续的连接无法建立直接返回rst;
拓展:如何避免syn攻击?
1:tcp半连接队列的大小;
2:开启tcp-syn-cookies:开启之后在半连接队列满了之后也不会丢弃连接,而是计算出一个cookie值,放入第二次握手的序列号中,然后收到ack报文后就会将连接放入全连接队列,使用accept可以调用;
3:减少syn-ack的重传次数:因为半连接队列中的连接都是在等待ack报文,超时等待后会重发syn-ack报文,超过最大次数之后才会从半连接队列中去除,那么我们只需要减少最大重传次数就能加快连接从半连接队列中去除的速度,也就能提高半连接队列的接收能力;
11:tcp四次挥手的过程说一下?
1:首先客户端调用关闭连接函数,发送fin报文进入fin-wait1阶段;
2:然后客户端接受到fin报文后,会发送ack报文,并进入close-wait状态,客户端接收到ack报文会进入fin-wait2状态
3:如果服务端有数据要发送就会先将数据发送完然后调用连接关闭函数,然后发送fin报文进入last-ack阶段;
4:客户端接收fin报文之后会发送ack报文并且进入timewait状态,等待2msl之后进入closed状态;
5:服务端接收fin报文后进入closed状态;
12:为什么四次握手的中间两次不能合并成一次?
因为服务端接收了fin报文发送ack之后可能还有未发送的数据需要发送所以需要等数据发送完才能才能发送fin报文;
13:第二次握手和第三次握手可以合并嘛?
是不能合并的,但是可以合并传输,当没有数据传输并且开启tcp延迟确认机制后可以合并传输;
14:如果第三次握手一直没法会发生什么?
当客户端接收道服务端发送的ack后会进入finwait2阶段,此时客户端会等待第三次握手的fin报文;
如果客户端是使用shoutdown关闭的,客户端还有接收或者发送数据的能力,所以客户端会在finwait2阶段一直等待;
如果是使用close关闭的,客户端没有发送和接受数据的能力,所以会超时关闭,一般默认关闭时间是60秒;
15:在第二次握手和第三次握手之间,主动断开的那一方能干什么?
如果主动断开的那一方使用的是shoutdown关闭连接的,如果还有接受数据的能力,那么主动断开的那一方还能接受数据;
16:断开连接时,客户端的fin报文丢失,服务端的状态是什么?
客户端发送fin报文之后,进入fin-wait1状态,会等待服务端发送的ack报文,如果长时间接收不到ack报文,客户端就会认为fin报文丢失了于是就会重新发送fin报文,当达到最大重试次数之后,客户端会关闭连接;而此时服务端一直会处于连接状态;
17:为什么四次挥手后要等待2msl?
msl是报文最大生存时间:在ip报文中有ttl,ttl是ip数据包可以经过的最大路由数,每经过一个路由器ttl就会减1,当ttl为0时就会被丢弃,同时发送icmp报文进行通知;而msl就是要大于等于ttl减为0的时间;
客户端发送ack后可能会丢失,这时就会服务端因为没有收到ack就会触发超时重传机制,重新发送fin报文,然后客户端接收后再发送ack报文这样一来一回正好2msl;
也就是等待2msl是至少允许报文丢失一次;
ttl的值一般为64,而msl的值默认为30秒;
18:服务端出现大量timewait有哪些原因?
1:没有开启http长连接:
如果没有开启长连接,那么每次请求响应都会创建一个连接,而每个短链接的自动关闭都是由服务端进行的,所以服务端会出现大量timewait状态
2:http长连接超时:
当建立连接后,如果长时间没有发送数据那么就会自动断开连接,也是由服务端断开的;
3:http长连接请求达到上限:
http长连接请求有数量限制,如果达到上限会关闭连接,也是由服务端断开;
19:tcp和udp的区别?
1:连接:
tcp是面向连接的,进行数据传输之前要建立连接;
udp不是面向连接的,即刻可用发送数据;
2:服务对象:
因为tcp是面向连接的,所以只能进行一对一的两点通信;
udp可以1对1可以1对多也可以多对多
3:可靠性:
tcp可用保证数据可靠,完整,有序的到达;
udp尽最大努力保证数据到达,但是不保证完整性和可靠性,可以基于udp实现可靠的传输协议quic;
4:拥塞控制,超时重传:
tcp为了保证数据安全可靠的到达会有拥塞控制和超时重传机制;
udp却没有,即使网络已经很拥堵了,也不会影响udp传输效率;
5:首部开销:
tcp首部较长,除去选项之外,有固定20字节的开销,加上选项只会更大;
udp首部的长度是固定的,一般只有8字节;
6:分片:
tcp报文在传输层进行分片,超过mss就会分片,接收后在传输层组装;
udp报文在ip层进行分片,超过mtu就会进行分片,接收后在ip层组装;
7:传输方式:
tcp是流式传输的,没有边界,但是保证有序和完整;
udp是一个包一个包发送的,有边界,但是不保证有序和完整;
拓展:udp和tcp的应用场景?
tcp:http,https,还有ftp文件传输;
udp:dns,snmp;直播,广播通信;
20:tcp为什么可靠传输?
基于一下几点才能保证tcp是可靠传输的:
1:连接管理:通过三次握手建立连接,四次挥手释放连接;
2:序列号:每次发送数据都会加上序列号,保证数据的有序,防止数据重复
3:确认应答号:接收到数据后使用确认应答号确认之前传输的数据被正确接收,保证数据不会丢包。
4:超时重传:超时重传的情况有两种:一种是数据包丢失,一直接收不到ack包就会触发超时重传;一种是确认包丢失:当收到重复的数据包时就会直接丢弃,并且重发ack包;
5:流量控制:因为接收端处理数据的能力是有限的,为了确保不会丢包,就要使用流量控制,接收端和发送端都会维护一个流量窗口,根据流量窗口的大小来发送数据;
6:拥塞避免:拥塞避免就是当网络堵塞时,减少发送端发送的数据;通过拥塞窗口来实现;拥塞避免的方法有:慢开始,拥塞避免,拥塞发生,快重传和快恢复;
21:怎么用udp实现http?
udp是不可靠的传输协议,但是可以基于udp实现类似于tcp的可靠传输协议如quic协议。比如http3.0就是基于quic实现的;
1:连接迁移:实现快速的网络切换;
2:重传机制;
3:前向纠错:在接收端修复丢失的数据;
4:拥塞控制;
免就是当网络堵塞时,减少发送端发送的数据;通过拥塞窗口来实现;拥塞避免的方法有:慢开始,拥塞避免,拥塞发生,快重传和快恢复;
21:怎么用udp实现http?
udp是不可靠的传输协议,但是可以基于udp实现类似于tcp的可靠传输协议如quic协议。比如http3.0就是基于quic实现的;
1:连接迁移:实现快速的网络切换;
2:重传机制;
3:前向纠错:在接收端修复丢失的数据;
4:拥塞控制;