讲讲几道关于 TCP/UDP 通信的面试题

TCP

(1)TCP 的 accept 发生在三次握手的哪个阶段?

如下图connect和accept的关系:

accept过程发生在三次握手之后,三次握手完成后,客户端和服务器就建立了tcp连接并可以进行数据交互了。这时可以调用accept函数获得此连接。

(2)connect返回了可以认为连接成功了吗?

connect返回成功后,三次握手就已经完成了。已完成的链接会被放入一个队列中,accept的作用就是从已连接队列中取出优先级最高的一个链接,并将它绑定给一个新的 fd,服务端就可以通过这个新的 fd 来 recv 和 send 数据了。

(3)三次握手过程中可以携带数据么?

第三次握手的时候,可以携带。前两次握手不能携带数据。如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。第三次握手的时候,客户端已经处于ESTABLISHED状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。

(4)等待2MSL的意义,如果不等待会怎样?

如果不等待,客户端直接跑路,当服务端还有很多数据包要给客户端发,且还在路上的时候,若客户端的端口此时刚好被新的应用占用,那么就接收到了无用数据包,造成数据包混乱。所以,最保险的做法是等服务器发来的数据包都死翘翘再启动新的应用。那,照这样说一个 MSL 不就不够了吗,为什么要等待 2 MSL?

  • 1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端
  • 1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达

这就是等待 2MSL 的意义。

SYN Flood 攻击

(1)SYN Flood 攻击原理SYN Flood 属于典型的 DoS/DDoS 攻击。其攻击的原理很简单,就是用客户端在短时间内伪造大量不存在的 IP 地址,并向服务端疯狂发送SYN。对于服务端而言,会产生两个危险的后果:

  • 处理大量的SYN包并返回对应ACK, 势必有大量连接处于SYN_RCVD状态,从而占满整个半连接队列,无法处理正常的请求。
  • 由于是不存在的 IP,服务端长时间收不到客户端的ACK,会导致服务端不断重发数据,直到耗尽服务端的资源。

(2)如何应对 SYN Flood 攻击?

  • 增加 SYN 连接,也就是增加半连接队列的容量。
  • 减少 SYN + ACK 重试次数,避免大量的超时重发。
  • 利用 SYN Cookie 技术,在服务端接收到SYN后不立即分配连接资源,而是根据这个SYN计算出一个Cookie,连同第二次握手回复给客户端,在客户端回复ACK的时候带上这个Cookie值,服务端验证 Cookie 合法之后才分配连接资源。

(3)TCP Fast Open

注意: 客户端最后握手的 ACK 不一定要等到服务端的 HTTP 响应到达才发送,两个过程没有任何关系。第一次握手时server会计算出cookie传给客户端并缓存,之后的握手客户端会携带cookie进行SYN。如果cookie不合法直接丢弃,如果合法,就可以直接发送http响应。(4)TFO 的优势TFO 的优势并不在与首轮三次握手,而在于后面的握手,在拿到客户端的 Cookie 并验证通过以后,可以直接返回 HTTP 响应,充分利用了1 个RTT(Round-Trip Time,往返时延)的时间提前进行数据传输,积累起来还是一个比较大的优势。

(5)序列号回绕怎么办?

现在我们来模拟一下这个问题。序列号的范围其实是在0 ~ 2 ^ 32 - 1, 为了方便演示,我们缩小一下这个区间,假设范围是 0 ~ 4,那么到达 4 的时候会回到 0。

假设在第 6 次的时候,之前还滞留在网路中的包回来了,那么就有两个序列号为1 ~ 2的数据包了,怎么区分谁是谁呢?这个时候就产生了序列号回绕的问题。那么用 timestamp 就能很好地解决这个问题,因为每次发包的时候都是将发包机器当时的内核时间记录在报文中,那么两次发包序列号即使相同,时间戳也不可能相同,这样就能够区分开两个数据包了。附:timestamp是 TCP 报文首部的一个可选项,一共占 10 个字节,格式如下:

kind(1 字节) + length(1 字节) + info(8 个字节)

其中 kind = 8, length = 10, info 有两部分构成: timestamp和timestamp echo,各占 4 个字节。

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

能不能说说 Nagle 算法和延迟确认?

(1)Nagle 算法试想一个场景,发送端不停地给接收端发很小的包,一次只发 1 个字节,那么发 1 千个字节需要发 1000 次。这种频繁的发送是存在问题的,不光是传输的时延消耗,发送和确认本身也是需要耗时的,频繁的发送接收带来了巨大的时延。而避免小包的频繁发送,这就是 Nagle 算法要做的事情。具体来说,Nagle 算法的规则如下:

  • 当第一次发送数据时不用等待,就算是 1byte 的小包也立即发送。
  • 后面发送满足下面条件之一就可以发了:数据包大小达到最大段大小(Max Segment Size, 即 MSS)之前所有包的 ACK 都已接收到

(2)延迟确认试想这样一个场景,当我收到了发送端的一个包,然后在极短的时间内又接收到了第二个包,那我是一个个地回复,还是稍微等一下,把两个包的 ACK 合并后一起回复呢?延迟确认(delayed ack)所做的事情,就是后者,稍稍延迟,然后合并 ACK,最后才回复给发送端。TCP 要求这个延迟的时延必须小于500ms,一般操作系统实现都不会超过200ms。不过需要主要的是,有一些场景是不能延迟确认的,收到了就要马上回复:

  • 接收到了大于一个 frame 的报文,且需要调整窗口大小
  • TCP 处于 quickack 模式(通过tcp_in_quickack_mode设置)
  • 发现了乱序包

两者一起使用会怎样?前者意味着延迟发,后者意味着延迟接收,会造成更大的延迟,产生性能问题。

TCP的Keep Alive和HTTP的Keep Alive的区别

TCP keepalive

  • 在双方长时间未通讯时,如何得知对方还活着?如何得知这个TCP连接是健康且具有通讯能力的?
  • TCP的保活机制就是用来解决此类问题的
  • 保活机制默认是关闭的,TCP连接的任何一方都可打开此功能。
  • 若对端正常存活,且连接有效,对端必然能收到探测报文并进行响应。此时,发送端收到响应报文则证明TCP连接正常,重置保活时间计数器即可。
  • 若由于网络原因或其他原因导致,发送端无法正常收到保活探测报文的响应。那么在一定探测时间间隔(tcp_keepalive_intvl)后,将继续发送保活探测报文。直到收到对端的响应,或者达到配置的探测循环次数上限(tcp_keepalive_probes)都没有收到对端响应,这时对端会被认为不可达,TCP连接随存在但已失效,需要将连接做中断处理。

HTTP keep-alive

  • keep-alive机制:若开启后,在一次http请求中,服务器进行响应后,不再直接断开TCP连接,而是将TCP连接维持一段时间。在这段时间内,如果同一客户端再次向服务端发起http请求,便可以复用此TCP连接,向服务端发起请求,并重置timeout时间计数器,在接下来一段时间内还可以继续复用。这样无疑省略了反复创建和销毁TCP连接的损耗。

TCP队头阻塞和HTTP队头阻塞

1. TCP队头阻塞TCP数据包是有序传输,中间一个数据包丢失,会等待该数据包重传,造成后面的数据包的阻塞。(停止等待)2. HTTP队头阻塞http队头阻塞和TCP队头阻塞完全不是一回事。http1.x采用长连接(Connection:keep-alive),可以在一个TCP请求上,发送多个http请求。有非管道化和管道化,两种方式。非管道化,完全串行执行,请求->响应->请求->响应…,后一个请求必须在前一个响应之后发送。管道化,请求可以并行发出,但是响应必须串行返回。后一个响应必须在前一个响应之后。原因是,没有序号标明顺序,只能串行接收。管道化请求的致命弱点:

  • 会造成队头阻塞,前一个响应未及时返回,后面的响应被阻塞
  • 请求必须是幂等请求,不能修改资源。因为,意外中断时候,客户端需要把未收到响应的请求重发,非幂等请求,会造成资源破坏。

由于这个原因,目前大部分浏览器和Web服务器,都关闭了管道化,采用非管道化模式。无论是非管道化还是管道化,都会造成队头阻塞(请求阻塞)。解决http队头阻塞的方法:1. 并发TCP连接(浏览器一个域名采用6-8个TCP连接,并发HTTP请求)2. 域名分片(多个域名,可以建立更多的TCP连接,从而提高HTTP请求的并发)3. HTTP2方式http2使用一个域名单一TCP连接发送请求,请求包被二进制分帧**(多路复用)**不同请求可以互相穿插,避免了http层面的请求队头阻塞。但是不能避免TCP层面的队头阻塞。

UDP

UDP如何实现可靠传输?

传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。最简单的方式是在应用层模仿传输层TCP的可靠性传输。下面不考虑拥塞处理,可靠UDP的简单设计。

  • 添加seq/ack机制,确保数据发送到对端
  • 添加发送和接收缓冲区,主要是用户超时重传。
  • 添加超时重传机制。

详细说明:发送端发送数据时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。发送端收到了ack包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据。

原文作者:一起学嵌入式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/114928.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

像linux 一样清理Windows C盘

像 linux 有命令 du -sh 查看文件夹大小 但是windows 可就没有这个命令了,就算有命令,也不能扫描子目录里面的文件 但是windows 可以借助 软件来清理,和linux 一样 文件上面是目录,下面是文件所占用空间大小的图,咋…

通过参数化可变形曲线直接从 X 射线投影数据计算分割研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

虚拟机Ubuntu20.04 网络连接器图标开机不显示怎么办

执行以下指令: sudo service network-manager stop sudo rm /var/lib/NetworkManager/NetworkManager.state sudo service network-manager start

MySQL 特殊语法时间格式以及Greadb连接

一、时间语法 DATE_FORMAT和to_char() select to_char(now(),%Y-%m-%d %H:%i:%s) from dual; select DATE_FORMAT(now(),%Y-%m-%d %H:%i:%s) from dual; 2.to_date() 和STR_TO_DATE(#{date},%Y-%m-%d ) select to_date(now(),yyyy-mm-dd hh24:mi:ss) from dual;

LeetCode——栈的压入、弹出序列

这里我用下面的例子子来讲解一下模拟栈的实现。 例子1:pushed [1,2,3,4,5] popped [4,5,3,2,1] 思路:第一步:我们先创建一个栈,然后将pushed的数据压进去 第二步:判断! 当压入栈的数据和popped第一个数据…

本地启动若依微服务版本

前置工作: 1.导入sql文件 2.安装完nacos 3.安装完redis 启动步骤: 1.开启nacos,在bin目录下 startup.cmd -m standalone 注意:在这之前要配置nacos持久化,修改conf/application.properties文件,增加支持…

MR混合现实石油化工课堂情景实训教学演示

MR(混合现实)技术是一种结合了虚拟现实(VR)和增强现实(AR)优势的新型技术,在教育领域具有广阔的应用前景。在石油化工课堂中,MR混合现实情景实训教学的应用可以大大提高学生的学习效…

抖音短视频账号矩阵seo分发系统--开发源代

1.抖音矩阵号/抖音短视频SEO矩阵系统开发及开发者思路分享: 短视频获客系统开发原型支持短视频智能批量剪辑、短视频多账号管理定时发布,短视频排名查询及优化,智能客服私信回复等,那么短视频seo系统开发时需要开发哪些功能呢?今天…

实现基于栈的表达式求值计算器(难度4/10)

本作业主要考察:解释器模式的实现思想/栈结构在表达式求值方面的绝对优势 C数据结构与算法夯实基础作业列表 通过栈的应用,理解特定领域设计的关键作用,给大家眼前一亮的感觉。深刻理解计算机语言和人类语言完美结合的杰作。是作业中的上等…

winform嵌入浏览器 webView2

1、项目引用nuget 2、winform窗体中初始化 var webView new WebView2();webView.Source new Uri(url);webView.Dock DockStyle.Fill;//接收js调用c#函数的消息webView.WebMessageReceived CoreWebView2_WebMessageReceivedAsync; this.panel1.Controls.Add(…

成集云 | 飞书审批同步金蝶云星空 | 解决方案

源系统成集云目标系统 方案介绍 飞书员工报销审批通过后,审批单据内容和审批状态实时同步金蝶云星空 飞书是字节跳动于2016年自研的新一代一站式协作平台,将即时沟通、日历、云文档、云盘和工作台深度整合,通过开放兼容的平台,…

2023年创新药行业研究报告

第一章 行业概况 1.1 定义 根据《英国医学杂志》的定义,创新药物被定义为”完全或部分新的活性物质或生物实体,或者这些实体的组合,通过药理或分子机制对抗疾病,缓解症状,或预防疾病,以及作为可以改善病人…

Graylog 更改显示的时区(Display timezone)

每个 Graylog 用户都可以配置他们的显示时区。 这会更改用于查看日志消息的时区,但不会更改日志消息的原始时区。 默认情况下,Graylog 显示 UTC 格式的所有时间戳(也就是 0:00)。就像是下面这样 非Admin账户要更改时区&#xff1…

Elasticsearch 7.6 - Springboot应用基础操作篇

ES 7.6 - JAVA应用基础操作篇 环境准备依赖配置 实体类准备使用说明索引/映射操作创建索引和映射索引和映射相关查询删除索引 文档操作插入数据更新数据删除数据批量操作 文档查询根据ID查询根据字段精准查询根据字段分词查询控制返回字段范围查询组合查询排序分页高亮搜索聚合…

Vue插槽实现商品列表-编辑渲染

商品列表 文章目录 商品列表核心步骤创建组件 1. MyTag组件详细步骤双击显示,自动聚焦失去焦点,隐藏输入框回显标签信息回车修修改内容,同时隐藏输入框 MyTable组件详细步骤1-动态的设置整个表格的数据 : props2-实现自定义结构-插…

HBase集群环境搭建与测试

🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…

Java反射机制,动态代理,hook以及在Retrofit源码中的应用

1.反射的基础知识: Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及…

如何判断自己的qt版本呢?

如何判断自己的qt版本呢? 前情提要很简单,按照如下图所示,即可查看当前打开的qtCreator的版本如何打开5.15.2版本的qtCreator呢?安装教程 前情提要 我的电脑已经安装了qt5.14.1,然后我又安装了qt5.15.2,我想尝试一下同一台电脑能否适应两个版本的qt? 当我安装完成qt5.15.2后…

2023-08-31 LeetCode每日一题(一个图中连通三元组的最小度数)

2023-08-31每日一题 一、题目编号 1761. 一个图中连通三元组的最小度数二、题目链接 点击跳转到题目位置 三、题目描述 给你一个无向图,整数 n 表示图中节点的数目,edges 数组表示图中的边,其中 edges[i] [ui, vi] ,表示 ui…

兔鲜儿 - 用户模块

目录 兔鲜儿 - 用户模块​ 会员中心页(我的)​ 静态结构​ 猜你喜欢分页加载 会员设置页 设置页分包和预下载 静态结构 退出登录 会员信息页 个人信息页准备工作 静态结构 获取会员信息​ 渲染会员信息 更新会员头像 更新表单信息​ 兔鲜儿 - 用户模块​ 在用户…