首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么tcp_transmit_skb不删除写队列中的skbuff,而udp_send_skb删除

在回答这个问题之前,我想先解释一下TCP和UDP的基本概念。

TCP(传输控制协议)和UDP(用户数据报协议)是互联网协议族中的两种常用传输层协议。它们都用于在网络上传输数据,但在一些关键方面有所不同。

TCP是一种面向连接的协议,它提供可靠的、有序的数据传输。它通过建立连接、数据分段、确认和重传等机制来确保数据的可靠性。TCP适用于对数据传输的可靠性要求较高的场景,如文件传输、网页浏览等。

UDP是一种无连接的协议,它提供不可靠的、无序的数据传输。UDP不需要建立连接,数据被封装成数据报直接发送,不提供确认和重传机制。UDP适用于对数据传输的实时性要求较高、对可靠性要求较低的场景,如音视频传输、实时游戏等。

现在回到问题本身,为什么tcp_transmit_skb不删除写队列中的skbuff,而udp_send_skb删除呢?

首先,我们需要了解TCP和UDP在数据传输过程中的一些特点。

TCP使用滑动窗口机制来控制发送方和接收方之间的数据流量。发送方将数据分割成多个TCP段,并将它们放入发送队列中。接收方通过发送确认消息来告知发送方已成功接收到数据。一旦发送方收到确认消息,它将从发送队列中删除相应的数据。

相比之下,UDP是一种无连接的协议,没有滑动窗口机制。UDP发送方将数据封装成数据报,并直接发送给接收方。接收方收到数据报后,将其解析并处理。

基于上述特点,我们可以得出以下结论:

  1. TCP的发送队列是用来存储待发送的数据段的,而不是完整的数据报。因此,在发送数据段之后,发送方需要保留这些数据段,以便在需要重传时使用。如果在发送数据段后立即删除它们,将无法进行重传操作。
  2. UDP不需要进行重传操作,因为它没有确认和重传机制。一旦数据报发送出去,发送方就不再需要保留它们。因此,UDP发送方在发送数据报后可以立即删除它们。

综上所述,tcp_transmit_skb不删除写队列中的skbuff,而udp_send_skb删除的原因是因为TCP需要保留待发送的数据段以进行重传操作,而UDP不需要进行重传操作,因此可以立即删除发送的数据报。

请注意,以上回答是基于一般情况下的理解,具体实现可能会因不同的操作系统、网络协议栈或应用程序而有所不同。对于具体的实现细节,建议参考相关文档或代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Linux内核网络udp数据包发送(二)——UDP协议层分析

数据位于发送队列,直到 udp_sendmsg 确定是时候调用 udp_push_pending_frames 来完成 skb,后者会进一步调用 udp_send_skb。...pending = 0; release_sock(sk); 我们来看看每个情况: 如果出现错误(错误为非零),则调用 udp_flush_pending_frames,这将取消 cork 并从 socket 发送队列删除所有数据...一些类型错误计数并不是只出现在一种计数可能是出现在多个计数。...调优:socket 发送队列内存大小 发送队列(也叫“队列”)最大值可以通过设置 net.core.wmem_max sysctl 进行修改。...正如我们所看到 ,UDP 数据报传输速度很快,通常不会在发送队列花费太多时间。 6.

5.5K51

25 张图,一万字,拆解 Linux 网络包发送过程

(T 是 transmit 缩写,R 表示 receive) 意不意外,惊惊喜??? 所以这就是开篇问题 1 一部分原因(注意,这只是一部分原因)。...问1:在服务器上查看 /proc/softirqs,为什么 NET_RX 要比 NET_TX 大多? 传输完成最终会触发 NET_RX,不是 NET_TX。...将来在发送时候,这两个环形数组相同位置指针将都将指向同一个 skb。这样,内核和硬件就能共同访问同样数据了,内核往 skb 里数据,网卡硬件负责发送。 ?...所以内核做法就是每次调用网卡发送时候,实际上传递出去是 skb 一个拷贝。等收到 ACK 再真正删除。 第二件事是修改 skb TCP header,根据实际情况把 TCP 头设置好。...为啥我说是基本完成,不是全部完成了呢?因为传输层需要保证可靠性,所以 skb 其实还没有删除。它得等收到对方 ACK 之后才会真正删除,那个时候才算是彻底发送完毕。

2.5K52

25 张图,一万字,拆解 Linux 网络包发送过程

(T 是 transmit 缩写,R 表示 receive) 意不意外,惊惊喜??? 所以这就是开篇问题 1 一部分原因(注意,这只是一部分原因)。...问1:在服务器上查看 /proc/softirqs,为什么 NET_RX 要比 NET_TX 大多? 传输完成最终会触发 NET_RX,不是 NET_TX。...将来在发送时候,这两个环形数组相同位置指针将都将指向同一个 skb。这样,内核和硬件就能共同访问同样数据了,内核往 skb 里数据,网卡硬件负责发送。...所以内核做法就是每次调用网卡发送时候,实际上传递出去是 skb 一个拷贝。等收到 ACK 再真正删除。 第二件事是修改 skb TCP header,根据实际情况把 TCP 头设置好。...为啥我说是基本完成,不是全部完成了呢?因为传输层需要保证可靠性,所以 skb 其实还没有删除。它得等收到对方 ACK 之后才会真正删除,那个时候才算是彻底发送完毕。

2K21

kubernetes 雪崩了: 从k8s到linux内核

而我们在容器化推进过程,就遇到了很多有意思故障,今天我们就来分析一个“雪崩”案例。...arp项 所以arp hash table里面存储条目是全局 dev:可以到达neighbour设备,是dev设备指针值,此时在内核态,所以可以看作是设备唯一标识ip:L3层目标地址(下一跳地址...,linux对ARP大小是有限制。...那么上层应用层很可能会进行不断重试,也会有其他流量调用内核发送数据,最终只要数据接收方ARP记录不在ARP表,都会导致进行垃圾回收,垃圾回收需要加写锁后再对ARP表进行遍历,这个遍历虽然耗时不长,...但是持锁时间 * 回收次数 导致持总体时间很长,这样就导致大量锁竞争(自旋),导致CPU暴涨,从而引发故障。

10810

能将三次握手理解到这个深度,面试官拍案叫绝!

如果想了解更多 listen 内部操作细节可以看之前一篇文章《为什么服务端程序都需要先 listen 一下?》 二、客户端 connect 客户端通过调用 connect 来发起连接。...**如果队列不满,那么就申请创建新 sock 对象。 5.2 删除半连接队列 把连接请求块从半连接队列删除。...request_sock **prev) { reqsk_queue_unlink(&inet_csk(sk)->icsk_accept_queue, req, prev); } reqsk_queue_unlink 把连接请求块从半连接队列删除...服务器响应第三次握手 ack 所做工作是把当前半连接对象删除,创建了新 sock 后加入到全连接队列,最后将新连接状态设置为 ESTABLISHED。...服务器响应 ack 时,把对应半连接对象删除,创建了新 sock 后加入到全连接队列,最后将新连接状态设置为 ESTABLISHED。

41710

面试如何保证数据一致性问题

),同时更新缓存和数据库 Write behind(异步缓存写入),他读操作和读穿透一样,但是操作和穿透有很大一点不同,就是他直接更新数据库,仅仅更新缓存,等到一定时间再去异步更新数据库,他对于一致性要求很低...provider) 读写异步模式,实现比较复杂,有数据不一致问题,但是性能好 Cache-Aside Pattern(旁路缓存模式)一些问题,首先我们为什么删除缓存不是更新缓存,那肯定是有原因其实他有三点不好原因...在并发情况下,线程A比线程B先更新数据库,但是由于某些原因,线程A比线程B晚更新缓存,就会导致缓存数据还是老数据,有了脏数据,删除就不会有这种情况 对于频繁场景,缓存就会频繁更新,浪费性能..., 对于频繁场景,缓存值经过大量计算得到,但是没有用几次,就会被更新的话,也是一种性能浪费 但是就有人问了,那为什么不先删除缓存,再更新数据库呢,我们来一个读写并发操作,看图说话 我们看到...,不管是使用双删策略,还是Cache-Aside Pattern模式,如果第二步删除失败,都可能带来数据不一致问题, 因此我们就可以在删除时候重复删除,当我们删除失败时候,我们可以把删除key放入到消息队列

87731

【原创】Java并发编程系列31 | 阻塞队列(上)

这样可以对各个模块业务功能进行解耦,生产者将“生产”出来数据放置在数据容器消费者仅仅只需要在“数据容器”中进行获取数据即可,这样生产者线程和消费者线程就能够进行解耦,只专注于自己业务功能即可...(设置容量,默认为Integer.MAX_VALUE) 锁takeLock保证删除数据安全性,队列为空时读操作线程阻塞并加入takeLock锁notEmpty条件等待队列。...(设置容量,默认为Integer.MAX_VALUE) 锁takeLock保证删除数据安全性,队列为空时读操作线程阻塞并加入takeLock锁notEmpty条件等待队列。...* 为什么队列还没有满,但是添加元素线程却在阻塞状态呢? * 因为添加元素和删除元素不是用同一个锁,所以添加元素和删除元素是可以同时进行。...* 当队列还有元素时,为什么会有读线程在阻塞呢? * 因为添加元素和删除元素不是用同一个锁,所以添加元素和删除元素是可以同时进行

40810

网卡收包流程

net_device代表是一种网络设备,既可以是物理网卡,也可以是虚拟网卡。在sk_buff中有一个net_device * dev变量,这个变量会随着sk_buff流向改变。...图3. softnet_data与接口层 和网络层之间关系 下面只内核配置成使用NAPI情况,只TSEC驱动。内核版本 linux 2.6.24。 NAPI相关数据结构 ?...2.6内核“下半部”处理机制: 1) 软中断请求(softirq)机制(注意不要和进程间通信signal混淆) 2) 小任务(tasklet)机制 3) 工作队列机制...图4.net_rx_action主要执行流程 3.5 DMA 8237A 在网卡收包涉及到DMA操作,DMA主要作用是让外设间(如网卡和主内存)传输数据不需要CPU参与(即不需要CPU使用专门...4.网卡多队列 网卡多队列是硬件一种特性,同时也需要内核支持,腾讯公司使用Intel 82576是支持网卡多队列,而且内核版本要大于2.6.20。

9.8K217

数据库缓存一致性问题

删除缓存再更新数据库 问题: 两个并发操作,一个更新操作,一个查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把旧数据读出来放到缓存,然后更新了数据库,于是缓存数据还是老数据。...实际上数据库操作会比读操作慢得多,而且还要锁表,读操作必需在操作前进入数据库操作,而又要晚于操作更新缓存,所有的这些条件都具备概率基本并不大。...Write Back套路,一句说就是,在更新数据时候,只更新缓存,更新数据库,而我们缓存会异步地批量更新数据库。...1.请求更新数据库 2.缓存因为某些原因,删除失败 3.把删除失败key放到消息队列 4.消费消息队列消息,获取要删除key 5.重试删除缓存操作 ---- 读取biglog...以mysql为例 可以使用阿里canal将binlog日志采集发送到MQ队列里面,然后通过ACK机制确认处理这条更新消息,删除缓存,保证数据缓存一致性 ----

37930

同步类容器和并发类容器区别_jdk提供用于并发编程同步器有

vector.remove(i); 将下标为9元素删除了,在删除过程因为有锁,所以之前那个线程无法执行vector.get(i);处于阻塞状态,等这个线程把下标为9元素删除了之后获取到锁再执行。...这样做好处是可以并发不需要加锁,因为当前容器不会添加任何元素,所以也是一种读写分离思想。但正是因为时复制,所以不能保证数据实时性,只能保证最终一致性。...array引用之后才释放锁,从而保证操作线程安全,针对读操作没有任何锁。...根据CopyOnWirte容器实现原理可知,CopyOnWirte容器保证读写分离,十分适合读多场景,但不适合写多场景。 3.3、线程安全队列 在并发编程我们有时候需要使用线程安全队列。...本站仅提供信息存储空间服务,拥有所有权,承担相关法律责任。如发现本站有涉嫌侵权/违法违规内容, 请发送邮件至 举报,一经查实,本站将立刻删除

22330

美团二面:Redis与MySQL双一致性如何保证?

操作缓存时候,到底是删除缓存呢,还是更新缓存? 日常开发,我们一般使用就是Cache-Aside模式。...有些小伙伴可能会问, Cache-Aside在写入请求时候,为什么删除缓存不是更新缓存呢? ? Cache-Aside写入流程 我们在操作缓存时候,到底应该删除缓存还是更新缓存呢?...Cache-Aside缓存模式,有些小伙伴还是会有疑问,在请求过来时候,为什么是先操作数据库呢?为什么不先操作缓存呢? 假设有A、B两个请求,请求A做更新操作,请求B做查询读取操作。 ?...接下来我们再来分析这种删除缓存失败情况,如何保证一致性。 数据库和缓存数据保持强一致,可以嘛? 实际上,没办法做到数据库与缓存绝对一致性。 加锁可以嘛?并发期间加锁,任何读操作写入缓存?...删除缓存重试流程 请求更新数据库 缓存因为某些原因,删除失败 把删除失败key放到消息队列 消费消息队列消息,获取要删除key 重试删除缓存操作 读取biglog异步删除缓存 重试删除缓存机制还可以吧

97520

线性表--顺序队列 循环队列 双端队列(十三)

进行插入操作端称为队尾,进行删除操作端称为队头。队列没有元素时,称为空队列。 2.队列数据元素又称为队列元素。在队列插入一个队列元素称为入队,从队列删除一个队列元素称为出队。...因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列元素才能最先从队列删除,故队列又称为先进先出(FIFO—first in first out)线性表。 ?...)49继续加1,而是应该将rear重置为0,才可解决问题,所以采取取膜算法也是可以,就是将最大长度重置为0,而其他数和取取模最后结果是一样,只是为了方便,一遍会采取取膜,(49+1)%=0,...在实际使用,还可以有输出受限双端队列(即一个端点允许插入和删除,另一个端点只允许插入双端队列)和输入受限双端队列(即一个端点允许插入和删除,另一个端点只允许删除双端队列)。...如果限定双端队列从某个端点插入元素只能从该端点删除,则该双端队列就蜕变为两个栈底相邻栈了。这种双端队列看起来比栈和队列更灵活,但是实际应用中远不及栈和队列常用,就不在讨论。

75220

【云原生进阶之PaaS中间件】第一章Redis-2.4缓存更新机制

1.1.1 请求为什么更新数据库后是删除缓存不是更新缓存?         注意看上面的图片,当有两个请求线程,线程一比线程二先执行,反而是线程二先执行完。...这时候,缓存保存是A数据(老数据),数据库保存是B数据(新数据),数据不一致了。 1.1.2 请求时,为什么更新数据库,然后再删除缓存?         ...如果采用请求,先删除缓存,再更新数据库就会出现如上图情况,线程B读到是老数据,并且缓存也保存是老数据。 1.1.3 请求时,先更新数据,后删除缓存一定没有问题吗?         ...(删除失败key放到消息队列)这种机制会造成大量业务代码入侵。 1.2.3 读取biglog异步删除缓存         通过binlog日志,将要删除key发送到消息队列。...1.4.2.1 为什么定期删除只扫描部分设置了过期时间key         因为扫描全部key会非常多,很影响性能。

21930

为什么我们做分布式要用 Redis ?

2、使用 Redis 常见问题 缓存和数据库双一致性问题 缓存雪崩问题 缓存击穿问题 缓存并发竞争问题 3、单线程 Redis 为什么这么快 这个问题是对 Redis 内部机制一个考察。...为什么我们做分布式使用Redis? Redis-client 在操作时候,会产生具有不同事件类型 Socket。在服务端,有一段 I/O 多路复用程序,将其置入队列之中。...然后,文件事件分派器,依次去队列取,转发到不同事件处理器。 4、Redis 数据类型及使用场景 一个合格程序员,这五种类型都会用到。...在大并发请求下,CPU 要将时间应用在处理请求,不是删除 Key,因此没有采用这一策略。 定期删除+惰性删除如何工作 定期删除,Redis 默认每个 100ms 检查,有过期 Key 则删除。...(推荐) 6、Redis 和数据库双一致性问题 一致性问题还可以再分为最终一致性和强一致性。数据库和缓存双,就必然会存在不一致问题。前提是如果对数据有强一致性要求,不能放缓存。

55930

分布式之redis复习精讲

引言 为什么这篇文章? 博主《分布式之消息队列复习精讲》得到了大家好评,内心诚惶诚恐,想着再出一篇关于复习精讲文章。...然后,文件事件分派器,依次去队列取,转发到不同事件处理器。...怎么删,这个问题思考过么?还有,你数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,有思考过原因么? 回答: redis采用是定期删除+惰性删除策略。 为什么不用定时删除策略?...定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,不是删除key,因此没有采用这一策略....接下来系统A抢到锁,发现自己valueA时间戳早于缓存时间戳,那就不做set操作了。以此类推。 其他方法,比如利用队列,将set方法变成串行访问也可以。总之,灵活变通。

64540

分布式之redis复习精讲

作者:孤独烟 出处: http://rjzheng.cnblogs.com/ 引言 为什么这篇文章?...然后,文件事件分派器,依次去队列取,转发到不同事件处理器。...怎么删,这个问题思考过么?还有,你数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,有思考过原因么? 回答: redis采用是定期删除+惰性删除策略。 为什么不用定时删除策略?...定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,不是删除key,因此没有采用这一策略....接下来系统A抢到锁,发现自己valueA时间戳早于缓存时间戳,那就不做set操作了。以此类推。 其他方法,比如利用队列,将set方法变成串行访问也可以。总之,灵活变通。

52930

Redis专题(1):构建知识图谱

思考:很明显,小明同学在面试过程关于Redis表现和回答肯定是比较失败。Redis是我们工作每天都会使用到东西,为什么一到面试却变成了丢分项呢?...那么,Redis为什么这么快呢? 绝大部分请求是纯粹内存操作,非常快速; 使用了很多查找操作都特别快数据结构进行数据存储,Redis数据结构是专门设计。...其实Redis还是有很多缺点,这些缺点平常我们该如何克服呢? 四、Redis存在问题及解决方案 4.1 缓存数据库一致性问题 问题:一致性问题是分布式系统很常见问题。...但我们删除缓存时候也可能出现某些问题,所以需要将要删除缓存key放到消息队列中去,不断重试,直到删除成功为止。...现在我们有了定期删除 + 惰性删除过期策略,就可以高枕无忧了吗?并不是这样,如果这个key一直访问,那么它会一直滞留,也是不合理,这就需要我们内存淘汰机制了。

1.1K70

面试官:缓存一致性问题怎么解决?

,由于sleep时间大于线程2读数据+缓存时间,所以缓存被再次删除 如果还有其他线程来读取缓存的话,就会再次从数据库读取到最新值 ?...这个就更明显问题了,更新数据库成功,如果删除缓存失败或者还没有来得及删除,那么,其他线程从缓存读取到就是旧值,还是会发生不一致。 ? 解决方案 消息队列 这是网上很多文章里都有写过方案。...引入消息中间件之后,问题更复杂了,怎么保证消息丢失更麻烦 就算更新数据库和删除缓存都没有发生问题,消息延迟也会带来短暂不一致性,不过这个延迟相对来说还是可以接受 进阶版消息队列 为了解决缓存一致性问题单独引入一个消息队列...这样做好处是,不用你自己引入,侵入到你业务代码,中间件帮你做了解耦,同时,中间件这个东西本身就保证了高可用。 当然,这样消息延迟问题依然存在,但是相比单纯引入消息队列做法更好一点。...因为活动并不频繁发生改变,而且对于活动来说,短暂不一致性并不会有什么大问题。 为什么删除不是更新缓存? 我们以先更新数据库,再删除缓存来举例。

89021

为什么 Redis 立刻删除已经过期数据?

延迟队列:也就是把对象放到一个延迟队列里面。当从队列里取出这个对象时候,就说明它已经过期了,这时候就可以删除。懒惰删除:是指每次要使用对象时候,检查一下这个对象是不是已经过期了。...Redis 定期删除要比我这里讲复杂很多,毕竟 Redis 是一个追求高性能中间件,所以肯定要有复杂机制控制住定期删除开销。为什么立刻删除?答案就是做不到,或者即便能做到,代价也太高。...延迟队列本身开销很大,尤其是在 key 很多情况下。修改过期时间需要调整延迟队列各个 key 顺序。...对于 RDB 来说,一句话总结就是主库不读,从库原封不动。也就是说,在生成 RDB 时候,主库会忽略已经过期 key。在主库加载 RDB 时候,也会忽略 RDB 已经过期 key。...从库则是整个 RDB 都加载进来,因为从库在加载完 RDB 之后,很快就能从主库里面收到删除指令,从而删除这个过期 key。AOF 是之前我们就提到过 Append Only File。

2K31
领券