unix udp sendto 最大可发送的数据长度

sendto 的最大可发送数据长度受限于两个值。

第一 【2^16 -1 - 8 -20】

第二 【SO_SNDBUF】

解释受限于【2^16-1-8-20】

数据封装过程

第一步: 用户层 : user数据

第二步: udp层数据: udp首部(8) + user数据

第三步:

ip层数据报文: ip首部(20) + udp首部(8) + user 数据

因为,ip首部中用于表示ip数据报文段的长度为16bit,所有ip最大可封装的数据长度为【2^16-1-20】

所以user数据的最大长度为【2^16-1-20-8】.

注意引起ip分片是因为ip数据报文段>MTU(受限于链路层最大传输长度)。

而不是上层数据[udp首部+user数据]>[2^16-1-20],如果上层数据大于[2^16-1-20],将向上层返回错误。

ip层的处理情况可以这样理解:

1 将上层数据封装成一个ip数据报文,如果数据报文的数据部分大于【2^16-1-20】,返回错误

2 如果ip数据报文段大于MTU,则将该ip数据报文段进行分片处理,分成多个ip数据报文段

所以, 当sendto数据超过【2^16-1-20-8】时,系统会返回 Message too long 错误。

受限于【SO_SNDBUF】情况

可参看http://blog.chinaunix.net/uid-20662820-id-3600294.html

SO_SNDBUF 可由getsockopt 查看,可由setsockopt 设置

SO_SNDBUF 的取值规则可参看 http://blog.csdn.net/ziliangxiao/article/category/2210813

SO_SNDBUF 规定了ip层用于发送udp数据最大可分配空间的长度为Max_mem_alloc,一般Max_mem_alloc>=SO_SNDBUF

规则参看http://blog.chinaunix.net/uid-20662820-id-3600294.html

简而言之,ip层分配用于发送的报文段时,会查看已分配size_alloc的大小是否大于SO_SNDBUF

如果size_alloc大于等于SO_SNDBUF,则分配失败,即该udp数据报文发送失败No buffer space available

如果size_alloc小于SO_SNDBUF, 则分配成功成功

所以,有可能最后一次分配完时,已分配的size_alloc 会大于SO_SNDBUF

关键在于理解,每次分配是否成功取决于是否还有剩下的,而不在与剩下的够不够分配,

————————————————
版权声明:本文为CSDN博主「一人在人间」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ziliangxiao/article/details/24294991

原文地址:https://www.cnblogs.com/Ph-one/p/12033214.html

时间: 2024-11-07 03:01:45

unix udp sendto 最大可发送的数据长度的相关文章

udp回显客户端发送的数据

这里让客户端给服务端发送的数据被服务端自动发回来 客户端: import socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: client_socket.sendto(input('请输入要回显的数据:').encode(), ('127.0.0.1', 23234)) client_recv_temp_data = client_socket.recvfrom(1024) pri

STM32 UART DMA实现未知数据长度接收

串口通信是经常使用到的功能,在STM32中UART具有DMA功能,并且收发都可以使用DMA,使用DMA发送基本上大家不会遇到什么问题,因为发送的时候会告知DMA发送的数据长度,DMA按照发送的长度直接发送就OK了,但是使用DMA接收时候就不同了,因为有时候数据接收并不是每一次都是定长的,但是DMA只在接收数据长度和设定数据长度相同的时候才可以触发中断,告诉MCU数据接收完毕,针对这个问题,解决方法如下,有一点复杂,但是很管用. UART在传输一个字节的时候,首先拉低,传输起始位,然后在是LSB

Udp实现消息的发送和接收、以及图片的上传

//Udp实现消息的发送和接收 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; import java.util.Scanner; public class UdpUtils implements Runnable { //定义

跨进程发送消息数据(发送WM_COPYDATA消息,够简单的)

1 //1.发送窗体 2 procedure TForm2.Button1Click(Sender: TObject); 3 var 4 h: HWND; 5 Size: Integer; 6 CopyDataStruct: TCopyDataStruct; 7 begin 8 h := FindWindow(nil, '接收窗口'); { 按标题查找目标窗口 } 9 if h > 0 then 10 begin 11 Size := ByteLength(Edit1.Text) + 2; {

后端接收不到AngularJs中$http.post发送的数据的问题

1.问题: 后端接收不到AngularJs中$http.post发送的数据,总是显示为null 示例代码: $http.post(/admin/KeyValue/GetListByPage, { pageindex: 1, pagesize: 8 }) .success(function(){ alert("Mr靖"); }); 代码没有错,但是在后台却接收不到数据,这是为什么呢? 用火狐监控:参数是JSON格式 用谷歌监控:传参方式是request payload 可以发现传参方式是

Http post方式发送json数据

HttpClient模拟get,post请求并发送请求参数(json等) import java.io.IOException; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; import org.apache.commons.httpclient.Header; import org.

iOS开发网络篇—发送json数据给服务器以及多值参数

iOS开发网络篇—发送json数据给服务器以及多值参数 一.发送JSON数据给服务器 发送JSON数据给服务器的步骤: (1)一定要使用POST请求 (2)设置请求头 (3)设置JSON数据为请求体 代码示例: 1 #import "YYViewController.h" 2 3 @interface YYViewController () 4 5 @end 6 7 @implementation YYViewController 8 9 - (void)viewDidLoad 10

Servlet向客户端发送中文数据的编码情况

(更多内容请关注本人微信订阅号:it_pupil) 本文讲述服务端servlet向客户端浏览器发送中文数据的编码情况,需要抓住下面几点: 输出流发送数据,必须是以字节形式传输的.也就是说,如果你在服务端定义一个字符串,那么servlet要先编码成字节数组,再发送到客户端. 客户端浏览器在收到字节码数据时,需要将其解码成字符串显示出来. 在服务端,如果你使用的是字节流,那么只需要注意两点:  拿到字符串,以特定形式编码成字节数组(如UTF-8).(字节数组是你人工转换的) 告诉浏览器,以相同方式解

简析TCP的三次握手与四次分手(TCP协议头部的格式,数据从应用层发下来,会在每一层都会加上头部信息,进行封装,然后再发送到数据接收端)good

2014-10-30 分类:理论基础 / 网络开发 阅读(4127) 评论(29) TCP是什么? 具体的关于TCP是什么,我不打算详细的说了:当你看到这篇文章时,我想你也知道TCP的概念了,想要更深入的了解TCP的工作,我们就继续.它只是一个超级麻烦的协议,而它又是互联网的基础,也是每个程序员必备的基本功.首先来看看OSI的七层模型: 我们需要知道TCP工作在网络OSI的七层模型中的第四层——Transport层,IP在第三层——Network层,ARP在第二层——Data Link层:在第二