TCP/IP协议二十问
1. 什么是TCP网络分层?
TCP网络分层一般分为五层:
- 应用层(HTTP):组装数据包
- 传输层(TCP):增加TCP头部,包含端口号等信息
- 网络互联层(IP):增加IP头部,包含IP地址等信息
- 网络访问层(ARP):增加以太网头部,包含MAC地址等信息
- 物理层
分层的好处
- 各层独立:限制了依赖关系的范围,各层之间使用标准化的接口,各层不需要知道上下层是如何工作的,增加或者修改一个应用层协议不会影响传输层协议;
- 灵活性:比如路由器不需要应用层和传输层,分层以后路由器就可以只用加载更少的几个协议层
- 易于测试和维护:提高了可测试性,可以独立的测试特定层,某一层有了更好的实现可以整体替换掉;
- 能促进标准化:各层职能清晰,方便标准化;
2. TCP的三次握手?为什么不是两次或者四次?
- 客户端向服务端发送SYN,seq = x;
- 服务端向客户端发送SYN,seq = y, ACK = x+1;
- 客户端向服务端发送ACK = y+1;
两次不行
- 如果只做两次无法确定服务端的接收能力;
- 两次握手后建立连接,有可能导致由于时延产生的多次连接建立,导致资源浪费;
四次不行
三次足够,没必要资源浪费;
3. TCP的四次挥手?为什么不能是三次?
- 客户端向服务端发送FIN,seq = x+2,ACK = y+1;
- 服务端向客户端发送ACK = x+3;
- 服务端发送完剩余数据后,再向客户端发送FIN,seq = y+1;
- 客户端向服务端发送ACK = y+2;
三次不行
导致服务端的ACK和FIN将延迟发送,如果延迟时间过长,客户端将再次重发断开请求,导致资源浪费。
4. 为什么SYN/FIN不包含数据却要消耗一个序列号?
凡是需要对端确认的,一定消耗TCP报文的序列号;
5. 什么是半连接队列?什么是SYN Flood攻击?
客户端大量伪造IP发送SYN包,服务端回复的ACK+SYN去到了一个【未知】的IP地址,势必会造成服务端大量的连接处于SYN_RCVD状态,而服务器的半连接队列大小也是有限的,如果半连接队列满,也会出现无法处理正常请求的情况。
6. TCP快速打开的原理?
TCP快速打开(TCP Fast Open,TFO)
TFO是在原来TCP协议上的扩展协议,它的主要原理就在发送第一个SYN包的时候就开始传数据了,不过他要求当前客户端之前已经完成过【正常】的三次握手。
快速打开分为两个阶段:请求 Fast Open Cookie 和 真正开始 TCP Fast Open
TCP Fast Open 的优势
可以利用握手去除一个往返的RTT
可以防止SYN-Flood攻击之类的
7. TCP报文中的时间戳有什么用?
TCP Timestamps Option由四部分构成:
类别、长度、发送方时间戳、回显时间戳
- 用于计算RTT
- 防止序列号的回绕问题,即使使用的序列号相同,也可以通过时间戳来对不同的包进行区分。
8. TCP的超时重传时间是如何计算的?
超时重传时间:Retransmission TimeOut, 简称RTO
经典解决方法
适用于RTT较小的情况,SRTT,smoothed round trip time。
利用最新一次的RTT对SRTT时间进行更新,
SRTT = α × SRTT + (1-α)× RTT
9. TCP流量控制?
把发送的数据放到发送缓冲区,把接收的数据放到接收缓冲区。通过实际接收缓冲区的大小,控制发送端的发送。
接收端会告知客户端自己接收窗口,也就是接收缓冲区中空闲的部分。
发送端的数据包的状态:
- 已发送且已确认
- 已发送未确认的
- 未发送但接收端可以接受的(接收端有空间接受)
- 未发送且不可以发送(接收端没空间接收)
发送端速度较慢:存在大量待发送的字节;
发送端速度较快:存在大量待确认的字节;
10. TCP的keep-alive原理?
定时发送探测包来探测连接的对端是否存活,但是keepalive默认设置的时间过长,7200s没有实际意义,一般在应用层做心跳机制。
什么是心跳机制?
- 定时向服务端发送消息
- 能响应服务端的消息
长链接业务场景
- 游戏
- -即时通讯
在没有心跳包机制的情况下,网络若掉线,对方不可知;
如果客户端掉线,服务端不知道,还维持链接,就是额外的无效系统开销。
为什么需要心跳包:
- 在NAT、防火墙网络中装设备,保存信道记录;
- 及时发现对方网络断开,以便及时采取措施;
如何实现心跳包
- TCP层面的心跳包,只能够验证网络链接是否异常;
- 应用层层面的心跳包,验证服务接口是否异常;
为什么不采用TCP层面?
应用层的连接如果成功,那么TCP所在的传输层必定成功。
11. TCP中的端口号
源端口:本地端口
目标端口:服务器端口
最大65536个,所以是0-65535
常见端口:
端口号 | 服务 |
---|---|
22 | SSH |
80 | HTTP |
443 | HTTPS |
3306 | mysql |
Redis | 6379 |
MongoDB | 27017 |
12. TCP场景问题1
AB两个主机之间建立了一个TCP连接,A主机发给B主机两个TCP报文,大小分别是500和300,第一个报文的序列号是200,那么B主机接收两个报文后,返回的确认号是多少?500+300+200 = 1000
13. TCP场景问题2
收到IP数据包解析后,如何知道应该投递到上层中的哪个协议(是TCP还是UDP)?
IP报文头中有协议字段,TCP6,UDP17
14. TCP场景问题3
TCP提供了一种字节流服务,而收发双方都不保持记录的边界,应用程序应该如何提供他们自己的记录标识呢?
应用程序使用自己约定的规则来标识消息的边界,比如有一些使用回车+换行(“\r\n”),比如Redis的通信协议;
15. telnet 的用法
检查远端端口是否打开,其语法如下:
telnet [ip] [port]
16. netstat的用法
主要用于查询网络情况
如: netstat -a -lu -lt
17. tcpdump
用于抓包,例如可以查看三次握手和四次挥手等
18. wireshark
19. TCP和UDP的区别?
TCP是一个面向连接的、可靠的、基于字节流的传输层协议;
UDP是一个面向无连接的传输层协议;
-
面向连接:指的是客户端和服务端的连接,在通信前通过三次握手建立连接;
-
可靠性:
- TCP有状态:TCP会精准记录那些数据发送了,哪些数据已被接收,那些数据未被接收,并且保证数据包按序到达,不允许差错;
- TCP可控制:如果遇到丢包或者网络不佳,TCP会根据具体情况自行调整,控制自己的发送速度或者重发。
20. QQ的网络协议设计?
- 登录采用TCP协议和HTTP协议;
- 好友之间发消息可以采用UDP;
- 内网传文件可以采用P2P技术;
- 登录过程中,客户端client采用TCP协议向服务器发送消息;
- HTTP协议下载信息;
- 登录后通过TCP来保持在线状态;
- 和好友发消息客户端采用UDP协议,但是需要通过服务器转发,但是为了确保传输信息的可靠性,采用上层协议来保证可靠传输;
- 内网传输文件时采用P2P技术;