您的位置:首页 > 理论基础 > 计算机网络

看完这篇TCP,和面试官扯皮就没问题了

2020-03-17 07:22 561 查看

前记

上周我投递出了简历,岗位是java后端开发工程师。这周阿里面试官给我进行了面试。面试过程中他问了HTTP与TCP的区别。

无论什么技术岗位,计算机网络几乎是每场面试的必问内容,在面试中出现的次数非常非常多,所以我面试之前也有所准备。看到csdn上介绍HTTP的博客比较多,TCP的比较少,于是今天结合面试问题先详细讲一讲TCP

TCP连接管理

这部分之所以放在最前面,因为太重要!太重要!!太重要了!!!

TCP连接建立:三次握手

  • 第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号。
  • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

TCP连接关闭:四次挥手

  • 第一次挥手:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态

  • 第二次挥手:服务器收到客户端的后,发出ACK=1确认标志和客户端的确认号ack=u+1,自己的序列号seq=v,进入CLOSE-WAIT状态

  • 第三次挥手:客户端收到服务器确认结果后,进入FIN-WAIT-2状态。此时服务器发送释放FIN=1信号,确认标志ACK=1,确认序号ack=u+1,自己序号seq=w,服务器进入LAST-ACK(最后确认态)

  • 第四次挥手:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待)。客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态

TCP段结构


  1. 源端口、目标端口:计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两个进程需要通信。源端口、目标端口是用 16 位表示的,可推算计算机的端口个数为 2^16 个。

  2. 序列号:表示本报文段所发送数据的第一个字节的编号。在 TCP 连接中所传送的字节流的每一个字节都会按顺序编号。由于序列号由 32 位表示,所以每 2^32 个字节,就会出现序列号回绕,再次从 0 开始。那如何区分两个相同序列号的不同 TCP 报文段就是一个问题了,后面会有答案,暂时可以不管。

  3. 确认号:表示接收方期望收到发送方下一个报文段的第一个字节数据的编号。也就是告诉发送发:我希望你(指发送方)下次发送的数据的第一个字节数据的编号是这个确认号。也就是告诉发送方:我希望你(指发送方)下次发送给我的 TCP 报文段的序列号字段的值是这个确认号。

  4. TCP 首部长度:由于 TCP 首部包含一个长度可变的选项部分,所以需要这么一个值来指定这个 TCP 报文段到底有多长。或者可以这么理解:就是表示 TCP 报文段中数据部分在整个 TCP 报文段中的位置。该字段的单位是 32 位字,即:4 个字节。

  5. URG:表示本报文段中发送的数据是否包含紧急数据。URG=1,表示有紧急数据。后面的紧急指针字段只有当 URG=1 时才有效。

  6. ACK:表示是否前面的确认号字段是否有效。ACK=1,表示有效。只有当 ACK=1 时,前面的确认号字段才有效。TCP 规定,连接建立后,ACK 必须为 1。

  7. PSH:告诉对方收到该报文段后是否应该立即把数据推送给上层。如果为 1,则表示对方应当立即把数据提交给上层,而不是缓存起来。

  8. RST:只有当 RST=1 时才有用。如果你收到一个 RST=1 的报文,说明你与主机的连接出现了严重错误(如主机崩溃),必须释放连接,然后再重新建立连接。或者说明你上次发送给主机的数据有问题,主机拒绝响应。

  9. SYN:在建立连接时使用,用来同步序号。当 SYN=1,ACK=0 时,表示这是一个请求建立连接的报文段;当 SYN=1,ACK=1 时,表示对方同意建立连接。SYN=1,说明这是一个请求建立连接或同意建立连接的报文。只有在前两次握手中 SYN 才置为 1。

  10. FIN:标记数据是否发送完毕。如果 FIN=1,就相当于告诉对方:“我的数据已经发送完毕,你可以释放连接了”

  11. 窗口大小:表示现在运行对方发送的数据量。也就是告诉对方,从本报文段的确认号开始允许对方发送的数据量。

  12. 校验和:提供额外的可靠性。具体如何校验,参考其他资料。

  13. 紧急指针:标记紧急数据在数据字段中的位置。

  14. 选项部分:其最大长度可根据 TCP 首部长度进行推算。TCP 首部长度用 4 位表示,那么选项部分最长为:(2^41. 1)*41. 20=40 字节。

TCP可靠数据传输

  1. TCP在IP层提供的不可靠服务基础上实现可靠数据传输服务
  • 流水线机制
  • 累积确认机制
  • TCP使用单一重传计时器(超时和收到重复ACK会触发重传)
  1. 快速重传机制: 在定时器超时之前即进行重传。如果发生超时,将超时时间间隔加倍。

  2. TCP重传示例

TCP流量控制

利用滑动窗口实现流量控制。如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。

步骤

  1. 接收方为TCP连接分配buffer(速度匹配机制)
  2. 接收窗口(RcvWindow) = buffer中的可用空间 = RcvBuffer – [LastByteRcvd – LastByteRead]
  3. Receiver将RcvWindow告知Sender(如果RcvWindow会怎么样)
  4. Sender限制自己已经发送的但还没收到ACK的数据

TCP拥塞控制

别看放在最后,因为是压轴的知识点,很重要!

慢启动和拥塞避免

慢启动

慢启动指先把拥塞窗口cwnd设置为一个最大报文段MSS的数值,在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值,在每经过一个往返时间RTT,拥塞窗口wcnd就加倍。

慢启动的“慢”并不是指cwnd的增长速度慢,而是指在TCP开始发送报文段时先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是探测一下网络的拥塞情况)

拥塞避免算法

让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。

步骤

当cwnd < ssthresh时,使用上述的慢启动算法;
当cwnd > ssthresh时,停止使用慢启动算法而改用拥塞避免算法;
当cwnd = ssthresh时,即可使用慢启动算法,也可以使用拥塞避免算法;

快速重传和快速恢复

快速恢复

快速重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有达到对方)而不要等到自己发送数据时才进行捎带确认。

快重传算法规定,发送方只要一连收到3个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计数器时间到期。

快速恢复

  1. 当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限ssthresh减半。这是为了 预防网络发生拥塞。请注意:接下去不执行慢开始算法。

  2. 与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。

参考:http://blog.chinaunix.net/uid-26548237-id-3966297.html

总结

咱们玩归玩,闹归闹,别拿面试开玩笑。

TCP的知识点多,话题性自然也多。,面试官问的问题往往都是有关联性的,一旦问到了,大家一定要回答全面,不要丢三落四,回答到点上。TCP的三次握手、四次挥手是最常问的内容,在面试中出现的次数非常非常多,大家面试前要把HTTP、TCP等计算机网络的基础打牢。

如果有收获?希望老铁们来个三连,点赞、收藏、转发

创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客

  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
天才程序媛 发布了102 篇原创文章 · 获赞 837 · 访问量 11万+ 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐