我已经阅读了很多关于UDP数据包大小的文章,但是无法得出结论.
许多服务将最大的UDP数据包限制为512字节(如dns)
给定互联网上的最小MTU为576,IPv4标头的大小为20字节,UDP标头为8字节.这留下了548个可用于用户数据的字节
我是否能够使用大小为548的数据包而不会出现数据包碎片?或者是DNS的创建者知道什么,以及为什么他们将其限制为512字节.
我能安全地高于548字节吗?
我需要通过可能有损的网络将数据包从一个主机发送到另一个主机.为了最小化数据包延迟,我不考虑TCP/IP.但是,我希望最大化吞吐量uisng UDP.应该使用的UDP数据包的最佳大小是多少?
以下是我的一些注意事项:
网络中交换机的MTU大小为1500.如果我使用大数据包,例如8192,则会导致碎片.丢失一个片段会导致丢失整个数据包,对吧?
如果我使用较小的数据包,我将产生UDP和IP头的开销
如果我使用一个非常大的数据包,我可以使用的最大数据包是多少?我读到最大的数据报大小是65507.我应该使用什么缓冲区大小来发送这样的大小?这有助于提高我的吞吐量吗?
常见操作系统(例如Windows,Linux等)支持的典型最大数据报大小是多少?
更新:
数据的一些接收器是未实现TCP/IP堆栈的嵌入式系统.
我知道这个地方到处都是那些非常喜欢使用可用内容的人.但我希望能得到更好的答案,而不仅仅关注MTU.
要从python中的套接字读取数据,请调用socket.recv,它具有以下签名:
socket.recv(bufsize[, flags])
socket.recv的python文档模糊地陈述:
注意:为了最好地匹配硬件和网络现实,bufsize的值应该是2的相对较小的幂,例如4096.
问题:" 最符合硬件和网络现实 "是什么意思?将bufsize设置为非二次幂的实际影响是什么?
我已经看到许多 其他的 建议,使这个读取2的幂.我也很清楚,当数组长度为2的幂时通常有用的原因(长度上的位移/屏蔽操作,最佳FFT数组大小等),但这些是依赖于应用程序的.我只是没有看到它的一般原因socket.recv.当然不是python文档中具体建议的要点.我也没有看到底层python代码中的任何二次幂优化,使其成为特定于python的推荐
例如......如果您有一个协议,其中传入的数据包长度是完全已知的,那么显然最好只读取"最多"您正在处理的数据包所需的内容,否则您可能会吃掉下一个数据包那会很烦人.如果我正在处理的数据包只有42个字节待处理,我只会将bufsize设置为42.
我错过了什么?当我必须选择任意缓冲区/数组大小时,我通常(总是?)使长度为2的幂,以防万一.这只是多年来养成的习惯.python文档也只是习惯的受害者吗?
这不是python独有的,但由于我特意引用了python文档,我会将其标记为.
更新:我刚刚在我的系统上检查了内核级缓冲区的大小(或者至少我认为我做了......我做了cat /proc/sys/net/core/rmem_default)并且它是124928.不是2的强大. rmem_max是131071,也显然不是两个人的力量.
在研究这个问题时,我真的看不出两项建议的力量有什么好处.我准备将其称为虚假推荐......
我还添加tcp和C标签,因为他们也与此有关.
我有一个Java阅读器应用程序,它从Linux 64位平台(2.6.18)上的多播套接字读取.套接字大小已设置为2 MB.当读取器无法快速读取时,套接字"溢出",即从缓冲区中丢弃数据包.
我想知道的是Linux内核如何将数据包从套接字缓冲区中删除.我假设套接字缓冲区本身是FIFO缓冲区.但是,如果它已满,会发生什么?是否会丢弃下一个数据包(缓冲区内容不会改变)?或者新数据包会替换缓冲区中的旧数据包吗?如果是,哪个数据包(最老的?,最年轻的?,一个随机选择的数据包?)?
感谢您的任何见解.
哪一个做ioctl的FIONREAD回报,下一个数据包的长度,或缓冲区中的所有数据的长度?
假设UDP服务器在客户端1的数据包之后接收来自客户端1的2个数据包和来自客户端2的另外2个数据包.那么,什么是价值ioctl的FIONREAD,又是什么readfrom在这种情况下返回?
客户端1:v两个数据包
++ UDP Server有4个包< - FIONREAD?
客户端2:^两个数据包

我怎么能socket.ReadFromUDP事先知道长度?现在我有这样的事情.
buff := make([]byte, <unknownLength>)
for {
socket.ReadFromUDP(buff)
fmt.Println("Bytes read:", buff.Len())
}
Run Code Online (Sandbox Code Playgroud)
我试过这个,但它总是读取1024个字节.
buff := make([]byte, 1024)
for {
bytesRead, _, _ := socket.ReadFromUDP(buff)
fmt.Println("Bytes read:", bytesRead)
}
Run Code Online (Sandbox Code Playgroud)
我从服务器收到的数据包从几个字节到几千字节不等.
到目前为止,我所发现的有关使用套接字 ( recv)接收数据的所有内容都使用普通的旧 C 语言。
即使它是 C++,它要么在std::vector<char>(eww!)上逐字节接收,要么定义静态大小(例如vec.resize(BIG_NUMBER)),然后接收。
然而,所有这些似乎都非常低效和/或丑陋,所以我想知道,在 C++ 中最有效、最正确和最优雅的方法是什么?(不是 C)
Web 浏览器是某人需要接收未知数量数据的一个很好的例子。(Content-length为了示例而忽略标题)