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

Linux内核UDP收包为什么效率低?能做什么优化?

现在很多人都在诟病Linux内核协议栈收包效率低,不管他们是真的懂还是一点都不懂只是听别人说的,反正就是在一味地怼Linux内核协议栈,他们的武器貌似只有DPDK。...不过你得先把内核协议栈的UDP性能优化到接近DPDK,再把这种鄙视当后话来讲才更酷。 由于UDP的处理非常简单,因此实现一个能和DPDK对接的UDP用户态协议栈则并不是一件难事。...当然,Linux内核协议栈无法摆脱这两点问题,也就回答了本文的题目中的第一个问题, “Linux内核UDP收包为什么效率低?” 。 不同的上下文异步操作同一份数据,锁是必不可少的。...如果busy poll总能执行,它总是能拉取到自己下一个需要的数据包,那么这基本就是DPDK的效率了,然而和DPDK一样,这并不是一个统一的解决方案,轮询固然对于收包有收益,但中断是不能丢的,用CPU的自旋轮询换取收包效率...,这买卖代价太大,毕竟Linux内核并非专职收包的。

3.2K61

Linux内核UDP收包为什么效率低?性能怎么优化(超详细讲解)

现在很多人都在诟病Linux内核协议栈收包效率低,不管他们是真的懂还是一点都不懂只是听别人说的,反正就是在一味地怼Linux内核协议栈,他们的武器貌似只有DPDK。...不过你得先把内核协议栈的UDP性能优化到接近DPDK,再把这种鄙视当后话来讲才更酷。 由于UDP的处理非常简单,因此实现一个能和DPDK对接的UDP用户态协议栈则并不是一件难事。...当然,Linux内核协议栈无法摆脱这两点问题,也就回答了本文的题目中的第一个问题, “Linux内核UDP收包为什么效率低?” 。 不同的上下文异步操作同一份数据,锁是必不可少的。...如果busy poll总能执行,它总是能拉取到自己下一个需要的数据包,那么这基本就是DPDK的效率了,然而和DPDK一样,这并不是一个统一的解决方案,轮询固然对于收包有收益,但中断是不能丢的,用CPU的自旋轮询换取收包效率...,这买卖代价太大,毕竟Linux内核并非专职收包的。

1.9K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    linux内核发包工具,Linux内核发包工具pktgen测试方案说明「建议收藏」

    简介 pktgen是Linux内核里包含的一个高性能发包工具,主要用来测试网络性能。一般情况下,使用pktgen就可以满足千兆网卡的测试需要。...而从我测试来看,应该可以得到一个结论:CPU越好,每秒钟能发出的包数目越多,越有可能达到线速,在我的测试环境下,发包大概能达到4Mpps。...eth6发包eth7收包,并且eth7发包eth6收包shell脚本 pktgen_eth6_eth7.sh #!...以上两种测试在小包情况下发包只能达到4Mpps左右,要提高发包速率,采用多核多线程处理,代码如下(仍是从eth6发包eth7收包) pktgen_multicore.sh #!...9” set UDP source port max. pgset “udp_dst_min 9” set UDP destination port min, If udp_dst_max

    8.6K10

    这个点,在面试中答出来很加分!

    来多少就发多少,但是能发多少,得看你的发送缓冲区还剩多少空间。 举个例子,假设A线程想发123数据包,B线程想发456数据包。...那么问题又来了,那UDP呢?会有一样的问题吗? 我们跟TCP对比下,大家就知道了。 TCP不能用多线程同时读和同时写,是因为它是基于数据流的协议。 那UDP呢?它是基于数据报的协议。...至于什么时候发数据,发多少数据,发的数据是刚刚应用层传进去的一半还是全部都是不确定的,全看内核的心情。在接收端收的时候也一样。...所以从这个角度来说,UDP 写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有 TCP 的问题。...UDP 写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有 TCP 的问题。

    45120

    socket是并发安全的吗

    来多少就发多少,但是能发多少,得看你的发送缓冲区还剩多少空间。 举个例子,假设A线程想发123数据包,B线程想发456数据包。...那么问题又来了,那UDP呢?会有一样的问题吗? 我们跟TCP对比下,大家就知道了。 TCP不能用多线程同时读和同时写,是因为它是基于数据流的协议。 那UDP呢?它是基于数据报的协议。...至于什么时候发数据,发多少数据,发的数据是刚刚应用层传进去的一半还是全部都是不确定的,全看内核的心情。在接收端收的时候也一样。...所以从这个角度来说,UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。...UDP写数据报的行为是"原子"的,不存在发一半包或收一半包的问题,要么整个包成功,要么整个包失败。因此多个线程同时读写,也就不会有TCP的问题。

    1.9K10

    UDP-用户数据报协议1.介绍2.udp网络程序-发送数据udp网络程序-发送、接收数据echo服务器广播用代码给飞秋发信息收消息_没绑定端口号收消息_绑定端口多线程聊天

    1.介绍 UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。...UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。...多线程聊天 ''' 收和发互相不影响: 这是两个独立的功能,可以考虑两个线程 ''' from socket import * from threading import * import os...print("\r>" % (str(recvInfo[1]), recvInfo[0].decode('gbk'),os.linesep),end='') # 发...例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。 \r 默认表示将输出的内容返回到第一个指针,这样的话,后面的内容会覆盖前面的内容

    1.4K40

    Python—网络编程Socket

    tcp:send发消息,recv收消息 udp:sendto发消息,recvfrom收消息 part2: tcp是基于数据流的,而udp是基于数据报的 send(bytes_data):发送数据流,数据流...bytes_data若为空,自己这段的缓冲区也为空,操作系统不会控制tcp协议发空包 sendinto(bytes_data,ip_port):发送数据报,bytes_data为空,还有ip_port,...if判断,空消息就break掉通信循环)  *对于Windows/Linux系统:如果一端断开了链接,那另外一端的链接也跟着完蛋recv将不会阻塞,收到的是空(解决方法:服务端通信循环内加异常处理,捕捉到异常后就...break掉通讯循环) 2.udp协议 (1)如果收消息缓冲区里的数据为"空",recvfrom也会阻塞 (2)支部会udp协议的客户端sendinto一个空数据并不是真的空数据(包含:空数据+地址信息...和Linux系统上数据直接丢失,在Windows系统上发送的比接受的大直接报错 *只有sendinto发送数据没有recvfrom收数据,数据丢失   PS:     1.你单独运行上面的udp的客户端

    64620

    传输层协议——UDP

    操作系统动态分配的端口号,客户端程序的端口号,就由操作系统从这个分为分配的 2. netstat netstat 是一个用来查看网络状态的重要工具 输入 netstat -nltp n :拒绝显示别名,能显示数字的全都转化为数字...UDP协议 UDP协议端格式 有效载荷一定是上层——应用层 给的,上层通过系统调用 把数据拷过来的 UDP报头的宽度是0-31,表示报头所对应的字节数 (4字节) 1. 报头和有效载荷如何分离?...,指向结构体中的源端口号、目的端口号 、udp长度、校验和 UDP的特点 无连接:知道 对端的IP和端口号 就直接传输,不需要连接 不可靠:若网络故障段无法发送对方,UDP协议也不会给应用层返回任何错误信息...面向数据报:不能够灵活的控制读写数据的次数和数量 面向数据报的理解 因为UDP有自己固定的报头长度8字节,所以UDP能够知道自己的有效载荷多长 不靠上层,在底层就自动知道报文和有效载荷的长度 所以就能保证向上交付的...一定是独立的、完整的 有效载荷 不用自己处理,只要发的是完整的,收的就是完整的,对方发几次,收几次 由底层交上来,独立的报文,称为面向数据报 即应用层给UDP多长的报文,UDP原样发送,既不拆分,也不会合并

    22910

    EasyNVR平台级联到EasyCVR,视频播放一会就无法播放是什么原因?

    有用户反馈,EasyNVR作为下级平台,级联到EasyCVR时,EasyNVR平台能正常播放视频内容,但是EasyCVR却无法正常播放视频。针对该情况,技术人员立即通过抓包排查。...在数据包里查看上下级信息作对比,在下级EasyNVR平台的数据里包里发现,当请求流时,下级已经发流,而在上级数据包里查看,却是并未发流。2)于是我们排查上级EasyCVR平台为何显示未发流。...先查看收流端口(UDP 50426),再查看公网收流端口是否开通,此时发现公网收流端口UDP只开放了30个,区间在50000-50030。...3)从平台配置中查看到UDP端口的收流范围在50000-50500,那么这里就将问题明确了。因为上级EasyCVR平台请求播放端口是随机的,端口只开放了30个,所以上级抓包中未收到流。...将UDP端口范围改成50000-50030,EasyCVR平台即恢复了正常播放。

    25340

    HTTP之TCP三次握手及四次挥手

    TCP协议是传输层的协议,除了TCP协议之外,应用层还是UDP协议。相对比,UDP协议不可靠,TCP丢包之后会重新传输,UDP不会,而且UDP是无序的。...两者之间还是有很多区别的,UDP也有自己的优点,比如传输速度快。现在大部分都是由TCP协议。...TCP三次握手: 三次握手主要的目的是为了确认两个应用层都具备收和发的能力。...第一次握手,发送方发送SYN=1、SEQ=X,证明了发送方能发数据; 第二次握手,接收方发送SYN=1、ACK=X+1、SEQ=Y,ACK确保了接收方能收数据,SYN确保了接收方能发数据; 第三次握手,...所以这就是为什么需要三次握手而不是两次四次五次,大于三次浪费,少于三次不能保证双方同时具备收和发。

    35610

    深入理解kubernetes(k8s)网络原理之五-flannel原理

    ,先会创建一个pause容器,然后用pause容器的网络命名空间为入参(类似:/var/run/docker/netns/xxxx,用docker inspect nginx|grep Sandbox能获取到...当我们创建vxlan设备时,vxlan的设备驱动会注册一个UDP的socket,端口默认为4789,然后为这个udp的socket的接收流程注册一个vxlan的接收函数;当linux协议栈的收包流程走到...-> udp_queue_rcv_skb,在这里,如果是vxlan设备创建的端口收的包,会给vxlan_rcv处理 static int udp_queue_rcv_skb(struct sock *...gcells->cells || skb_cloned(skb) || netif_elide_gro(dev)) //非NAPI收包处理,linux虚拟网络设备接收如果需要软中断触发通常会走这里...我们继续用上面的场景举例,说明一下udp模式下的数据包发送流程: pod1发送给pod2的数据给会被主机路由引导通过tun设备(flannel.1)发送; flanneld进程从打开的/dev/net/

    3.9K02

    jvm可达性分析算法_对点网络

    网卡能做的事(TCP/UDP组包校验和分段,IP添加包头校验与分片)尽量往网卡做,网卡不能做的也尽量迟后分片(发送)或提前合并片(接收)来减少在网络栈中传输和处理的包数目,从而减少数据传输和上下文切换所需要的...发数据 TSO(TCP分段,TCP Segmentation Offload)在TCP处做,UFO(UDP分片,UDP Fragmentation Offload)因为UDP不支持分段所以移到下层的IP...收数据 LRO(Large Receive Offload),TSO是发,LRO是收。将多个TCP分段聚合成一个skb结构,以减小上层协议栈的skb的开销。...GRO(Generic Receive Offloading),GSO是发,GRO是收。...这样也就进了IP层的ip_finish_output_gso,如果硬件支持,则由硬件调用linux内核中的UDP GSO函数(当有GSO时,由 UDP协议栈提供UDP分片逻辑而不是IP分片逻辑,这使得每个分片都有完整的

    1.8K30

    Udp协议Socket编程

    Socket编程接口 ✈️浅谈Tcp/Udp网络协议   TCP与UDP协议都属于传输层协议,不同的是TCP给上层提供可靠性服务,而UDP并不能提供可靠性服务。   ...所以有些人说客户端不能绑定套接字,并不是一个完整的说法,正确的说法是 客户端必须得绑定套接字,不过这一步是OS帮助我们完成的。OS在客户端第一次发数据的时候对套接字进行绑定。   ...我们要知道,所有的服务器本质都是要解决输入输出的问题,为了能体现网络的层状结构,所以不能让网络通信与业务进行强耦合,所以我们可以借助functional来处理业务与网络通信之间的关系。   ...在Udp服务当中,_socket是全双工的。通俗一点说就是 可以同时进行收消息和发消息。...GetInstance()->Enqueue(t); }   那么消息转发模块基本上完成了,但是由于我们这个小项目全程在终端上进行的,所以在客户端页面上需要下点功夫,我们希望将来客户端在收到消息的时候能显示是谁发的消息

    10410

    图解Linux网络包接收过程

    好了,大概了解了网卡驱动、硬中断、软中断和ksoftirqd线程之后,我们在这几个概念的基础上给出一个内核收包的路径示意: 图2 Linux内核网络收包总览 当网卡上收到数据以后,Linux中第一个工作的模块是网络驱动...相信你这次能彻底理解ethtool的工作原理了吧?...这个命令之所以能查看网卡收发包统计、能修改网卡自适应模式、能调整RX 队列的数量和大小,是因为ethtool命令最终调用到了网卡驱动的相应方法,而不是ethtool本身有这个超能力。...这块相对比较简单,剩下大部分的戏份都是由Linux内核其它模块来表演了。 首先在开始收包之前,Linux要做许多的准备工作: 1....这还是简简单单的UDP,如果是TCP,内核要做的工作更多,不由得感叹内核的开发者们真的是用心良苦。 理解了整个收包过程以后,我们就能明确知道Linux收一个包的CPU开销了。

    5K73

    Python进阶之网络编程

    网卡信息 查看网卡信息 Linux:ifconfig windows:ipconfig ensxx:用来与外部进行通信的网卡; lo:环回网卡,用来进行本地通信的; linux关闭/开启网卡:sudo...大部分都是知名端口; 范围从0~1023; 动态端口 不固定分配,动态分配,使用后释放的端口号; 范围1024~65535; socket socket的概念 socket是进程间通信的一种方式,能实现不同主机间的进程间通信...send_addr = recv_data[1] # print("%s 发送了:%s" % (str(send_addr), recv_msg.decode("utf-8"))) # linux...() if __name__ == "__main__": main() udp接发数据总结 发送数据的流程: 创建套接字 发送数据 关闭套接字 接收数据的流程: 创建套接字 绑定本地自己的信息...,别人接收,别人不能回复消息,比如广播; 半双工: 两个人都能发消息,但是在同一时间只能有一个人发消息,比如对讲机; 全双工: 两个人都能发消息,能同时发,比如打电话; udp使用同一套接字收且发数据

    83720

    不为人知的网络编程(十):深入操作系统,从内核理解网络包的接收过程(Linux篇)

    这篇文章将用图解的方式,从操作系统这一层来深度理解一下网络包的接收过程(因为能直接看到内核源码,本文以Linux为例)。 按照惯例来借用一段最简单的代码开始思考。...Linux内核网络收包总览: 如上图所示:当网卡上收到数据以后,Linux中第一个工作的模块是网络驱动。网络驱动会以DMA的方式把网卡上收到的帧写到内存里。...这个命令之所以能查看网卡收发包统计、能修改网卡自适应模式、能调整RX 队列的数量和大小,是因为ethtool命令最终调用到了网卡驱动的相应方法,而不是ethtool本身有这个超能力。...首先在开始收包之前,操作系统要做许多的准备工作(以Linux为例): 1)创建ksoftirqd线程,为它设置好它自己的线程函数,后面指望着它来处理软中断呢; 2)协议栈注册,linux要实现许多协议,...理解了整个收包过程以后,我们就能明确知道Linux收一个包的CPU开销了: 1)首先第一块是用户进程调用系统调用陷入内核态的开销; 2)其次第二块是CPU响应包的硬中断的CPU开销; 3)接着第三块是ksoftirqd

    2.2K31

    python高级编程第五讲:socket编程-udp

    IP地址 目的:用来标记网络上的一台电脑 1.1 windows和Linux查看网卡信息 1 Linux中 ifconfig 2 windows中 ipconfig 1.2 IP地址的分类 ip v4...4.1 socket的使用 1.创建套接字 2.使用套接字收/发数据 3.关闭套接字 4.2 udp发送程序 import socket def main(): udp_socket = socket.socket...而且同一端口,不能用两次。 也就是说当进行发送的时候,没有绑定发送方的端口时,程序会自动分配一个动态的端口。...4.5 UDP简单聊天器 功能: 1.创建套接字 套接字是可以同时收发数据的 2.发送数据 3.接收数据 import socket #定义发送的程序 def udp_send(udp_socket..."",7790)) while True: udp_send(udp_socket) udp_recv(udp_socket) udp_socket.close

    93620

    python基础之socket编程

    使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。...收不到data报错,程序会中断,其他客服端的信息就传就不进来 data=conn.recv(1024) # if not data:break #针对linux...phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加 phone.bind(('127.0.0.1',8080)) 发现系统存在大量TIME_WAIT状态的连接,通过调整linux...而UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,这一点和TCP是很不同的。怎样定义消息呢?...tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,而udp是基于数据报的,即便是你输入的是空内容(直接回车),那也不是空消息,udp协议会帮你封装上消息头

    2.9K100

    【Linux】:Socket编程UDP(EchoServer(聊天)| DictServer(中译英字典)| ChatServer(简单聊天室))

    client_udp 先写出我们要实现的大概框架,将之前我们实现的 日志封装 Log.hpp【Linux】:日志策略 + 线程池(单例模式) 以及 互斥量封装【【Linux】:多线程(互斥 && 同步...Linux -> Linux 通信验证 将我们运行生成的 client_udp 文件打包到当前主机的桌面上,然后用另外一个 Linux 用户进行打开解包安装如下: ​ 由于此时的文件默认没有可执行,因此我们还需要给其加上权限...​ 验证如下: ​ 现在我们已经能实现 udp 编程了,然后我们再对我们的代码进行调整 InetAddr.hpp #pragma once #include #include...,然后再转发对应的信息,但是有个问题,这里不仅要一个人收消息,后面还要我们自己去转发给所有人,此时收消息转消息都是同一个人,UDP 数据一旦过大,服务器可能就没时间接收数据了,而且我们前面也说过 UDP...该类的析构函数是虚拟的,以确保在删除派生类对象时能正确调用析构函数。 2.

    6400
    领券