【面试】彻底理解 TCP 及面试常问

这个问题真的是烂大街了,但是真正问起来有很多细节的东西需要注意,被腾讯面试官问的我开始怀疑人生了。

计算机网络体系结构

在介绍 TCP/IP 之前需要简单介绍计算机网络体系结构,当然这个也是面试中经常会问到的。

总的来说体系结构的划分有三种:

  1. 五层协议
  • 应用层

为特定应用程序提供数据传输服务,例如 HTTP、SMTP、FTP、DNS 等,数据单位为报文(位于应用层的信息分组)

  • 运输层

提供的是进程间的通用数据传输服务,在应用程序端点之间传送应用层报文。包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段(运输层分组);用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。

  • 网络层

主机间提供数据传输服务,运输层协议是为主机中的进程提供数据传输服务。网络层把运输层传递下来的报文段或者用户数据报封装成分组。

  • 数据链路层

网络层针对的还是主机之间的数据传输,而主机之间可以有链路,链路层就是为相同链路的主机提供服务。数据链路层将网络层传下来的分组封装成帧

  • 物理层

考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。

  1. OSI

相比于五层协议多了表示层和会话层,用途如下:

  • 表示层:数据压缩、加密以及数据描述,这使得应用程序不必担心在各台主机中数据内部格式不同的问题
  • 会话层:建立及管理会话
  1. TCP/IP

只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层。

TCP/IP

TCP 特性

  • TCP 是一种面向连接的、可靠的字节流服务
  • 在一个 TCP 连接中,仅有两方进行通信,广播和多播不能用于 TCP
  • TCP 使用校验和,确认和重传机制来保证可靠传输
  • TCP 给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复
  • TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制

注意: TCP 并不能保证数据一定会被接收方收到,因为这是不可能的,总会出现数据的丢失,只不过 TCP 能够保证的是传送的数据可以得到确认,就是说即使没有到达,可以有重传机制来保证,如果到达了还有确认机制来保证数据传输的正确性。因此准确的说 TCP 也不是 100% 可靠的协议,所能提供的是数据的可靠递送或故障的可靠通知。

三次握手与四次挥手

下面为 TCP 状态码列表,以 S 指代服务器,C 指代客户端,S&C 表示两者,S/C 表示两者之一:

LISTEN S

服务器等待从任意远程TCP端口的连接请求。侦听状态。

SYN-SENT C

客户在发送连接请求后等待匹配的连接请求。通过connect()函数向服务器发出一个同步(SYNC)信号后进入此状态。

SYN-RECEIVED S

服务器已经收到并发送同步(SYNC)信号之后等待确认(ACK)请求。

ESTABLISHED S&C

服务器与客户的连接已经打开,收到的数据可以发送给用户。数据传输步骤的正常情况。此时连接两端是平等的。这称作全连接。

FIN-WAIT-1 S&C

(服务器或客户)主动关闭端调用close()函数发出FIN请求包,表示本方的数据发送全部结束,等待TCP连接另一端的ACK确认包或FIN&ACK请求包。

FIN-WAIT-2 S&C

主动关闭端在FIN-WAIT-1状态下收到ACK确认包,进入等待远程TCP的连接终止请求的半关闭状态。这时可以接收数据,但不再发送数据。

CLOSE-WAIT S&C

被动关闭端接到FIN后,就发出ACK以回应FIN请求,并进入等待本地用户的连接终止请求的半关闭状态。这时可以发送数据,但不再接收数据。

CLOSING S&C

在发出FIN后,又收到对方发来的FIN后,进入等待对方对己方的连接终止(FIN)的确认(ACK)的状态。少见。

LAST-ACK S&C

被动关闭端全部数据发送完成之后,向主动关闭端发送FIN,进入等待确认包的状态。

TIME-WAIT S/C

主动关闭端接收到FIN后,就发送ACK包,等待足够时间以确保被动关闭端收到了终止请求的确认包。【按照RFC 793,一个连接可以在TIME-WAIT保证最大四分钟,即最大分段寿命(maximum segment lifetime)的2倍】

CLOSED S&C

完全没有连接。

  1. 三次握手

三次握手协议指的是在发送数据的准备阶段,服务器端和客户端之间需要进行三次交互,详细过程如下:

  • A 向 B 发送请求报文,发送包含一个 SYN 包,以及一个 seq 号,初始化为 x
  • B 接收到连接请求报文,如果同意连接,就会向 A 发送确认报文,包括 SYN = 1,ACK = 1,确认号为 x + 1,而也会选择一个随机的序号 y
  • A 收到 B 的确认报文以后,还要向 B 发出确认,确认号为 y + 1,序号为 x + 1,B 收到以后就简历连接

三次握手原因:

第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端的连接确认。而对于客户端来说存在超时重传机制,就是在超过一个重传时间还没有收到确认的话,就会重新请求连接,但是第一次发送的滞留的连接请求还会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接,如果有三次握手客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。

这里可能涉及到 SYN 攻击

  • 什么是 SYN 攻击?

在三次握手过程中,服务器发送 SYN-ACK 之后,收到客户端的 ACK 之前的 TCP 连接称为半连接(half-open connect)。此时服务器处于 SYN_RCVD 状态。当收到 ACK 后,服务器才能转入 ESTABLISHED 状态。

SYN 攻击指的是,攻击客户端在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造 SYN 包将长时间占用未连接队列,正常的 SYN 请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。

SYN 攻击是一种典型的 DoS/DDoS 攻击。

  • 如何检测

检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。

netstat -n -p TCP | grep SYN_RECV
复制代码
  • 如何防御

SYN攻击不能完全被阻止,除非将TCP协议重新设计。我们所做的是尽可能的减轻SYN攻击的危害,常见的防御 SYN 攻击的方法有如下几种:

缩短超时(SYN Timeout)时间、增加最大半连接数、过滤网关防护、SYN cookies技术

  1. 四次挥手

建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的,详细过程如下:

  • A 发送连接释放报文,FIN = 1
  • B 收到之后发出确认,此时 TCP 处于半关闭状态,就是说 B 能向 A 发送数据但是 A 不能向 B 发送数据,这时候 B 会进入 CLOSE-WAIT 状态,并会将未传输完毕的数据继续传送给客户端。
  • 当 B 数据传输完成以后,会发送连接释放报文,FIN = 1,
  • A 收到之后会发出确认,并进入 TIME-WAIT 状态,等待 2MSL(最大报文存活时间)后释放连接,B 在收到 A 的确认之后会释放连接

TIME-WAIT

客户端收到服务端连接释放 FIN = 1 以后,不是直接 CLOSED,还需要等待一个时间段 2MSL,这么做有两个原因:

  • 确保最后一个确认报文能够到达,如果 B 没有收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了防止这种情况的发生。
  • 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中小时,使得下一个新的连接不会出现旧的连接请求报文

参考资料

TCP三次握手及四次挥手详细图解

TCP 协议

传输控制协议 维基百科

TCP 百度百科

CS-Notes TCP 的三次握手

转载于:https://juejin.im/post/5c9cc4a75188252d89137b89

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值