首页
学习
活动
专区
工具
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 之后才会真正删除,那个时候才算是彻底发送完毕。

1.9K21

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

如果想了解更多 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。

40910

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

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

86731

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

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

40210

数据库缓存一致性问题

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

37830

网卡收包流程

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

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

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

22130

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

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

74420

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

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

95720

【云原生进阶之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会非常多,很影响性能。

20230

分布式之redis复习精讲

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

64140

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

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

55430

分布式之redis复习精讲

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

52830

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

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

1.1K70

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

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

88721

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

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

1.9K31

为什么分布式一定要有Redis?

Redis 和数据库双一致性问题 如何应对缓存穿透和缓存雪崩问题 如何解决 Redis 并发竞争 Key 问题 为什么使用 Redis 我觉得在项目中使用 Redis,主要是从两个角度去考虑:性能和并发...性能 如下图所示,我们在碰到需要执行耗时特别久,且结果频繁变动 SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存读取,使得请求能够迅速响应。...在服务端,有一段 I/O 多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列取,转发到不同事件处理器。...在大并发请求下,CPU 要将时间应用在处理请求,不是删除 Key,因此没有采用这一策略。...接下来系统 A 抢到锁,发现自己 valueA 时间戳早于缓存时间戳,那就不做 set 操作了,以此类推。 其他方法,比如利用队列,将 set 方法变成串行访问也可以。总之,灵活变通。

38520
领券