IP数据包长度问题总结

2023-11-08

首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层。   
其中以太网(Ethernet)的数据帧在链路层   
IP包在网络层   
TCP或UDP包在传输层   
TCP或UDP中的数据(Data)在应用层   
它们的关系是 数据帧{IP包{TCP或UDP包{Data}}}   
---------------------------------------------------------------------------------
在应用程序中我们用到的Data的长度最大是多少,直接取决于底层的限制。   
我们从下到上分析一下:   
1.在链路层,由以太网的物理特性决定了数据帧的长度为(46+18)-(1500+18),其中的18是数据帧的头和尾,也就是说数据帧的内容最大为1500(不包括帧头和帧尾),即MTU(Maximum Transmission Unit)为1500;  
2.在网络层,因为IP包的首部要占用20字节,所以这的MTU为1500-20=1480; 
3.在传输层,对于UDP包的首部要占用8字节,所以这的MTU为1480-8=1472;   
所以,在应用层,你的Data最大长度为1472。 (当我们的UDP包中的数据多于MTU(1472)时,发送方的IP层需要分片fragmentation进行传输,而在接收方IP层则需要进行数据报重组,由于UDP是不可靠的传输协议,如果分片丢失导致重组失败,将导致UDP数据包被丢弃)。   
从上面的分析来看,在普通的局域网环境下,UDP的数据最大为1472字节最好(避免分片重组)。   
但在网络编程中,Internet中的路由器可能有设置成不同的值(小于默认值),Internet上的标准MTU值为576,所以Internet的UDP编程时数据长度最好在576-20-8=548字节以内。
---------------------------------------------------------------------------------  
MTU对我们的UDP编程很重要,那如何查看路由的MTU值呢?   
对于windows OS: ping -f -l   如:ping -f -l 1472 192.168.0.1   
如果提示:Packets needs to be fragmented but DF set.   则表明MTU小于1500,不断改小data_length值,可以最终测算出gateway的MTU值;   
对于linux OS: ping -c -M do -s   如: ping -c 1 -M do -s 1472 192.168.0.1   
如果提示 Frag needed and DF set……   则表明MTU小于1500,可以再测以推算gateway的MTU。
--------------------------------------------------------------------------------- 

IP数据包的最大长度是64K字节(65535),因为在IP包头中用2个字节描述报文长度,2个字节所能表达的最大数字就是65535。  
   
由于IP协议提供为上层协议分割和重组报文的功能,因此传输层协议的数据包长度原则上来说没有限制。实际上限制还是有的,因为IP包的标识字段终究不可能无限长,按照IPv4,好像上限应该是4G(64K*64K)。依靠这种机制,TCP包头中就没有“包长度”字段,而完全依靠IP层去处理分帧。这就是为什么TCP常常被称作一种“流协议”的原因,开发者在使用TCP服务的时候,不必去关心数据包的大小,只需讲SOCKET看作一条数据流的入口,往里面放数据就是了,TCP协议本身会进行拥塞/流量控制。  
   
UDP则与TCP不同,UDP包头内有总长度字段,同样为两个字节,因此UDP数据包的总长度被限制为65535,这样恰好可以放进一个IP包内,使得UDP/IP协议栈的实现非常简单和高效。65535再减去UDP头本身所占据的8个字节,UDP服务中的最大有效载荷长度仅为65527。这个值也就是你在调用getsockopt()时指定SO_MAX_MSG_SIZE所得到返回值,任何使用SOCK_DGRAM属性的socket,一次send的数据都不能超过这个值,否则必然得到一个错误。  
   
那么,IP包提交给下层协议时将会得到怎样的处理呢?这就取决于数据链路层协议了,一般的数据链路层协议都会负责将IP包分割成更小的帧,然后在目的端重组它。在EtherNet上,数据链路帧的大小如以上几位大侠所言。而如果是IP   over   ATM,则IP包将被切分成一个一个的ATM   Cell,大小为53字节。

******************************************************************************************************************************

******************************************************************************************************************************

    CP提供的是一种面向连接的,可靠的字节流服务,TCP提供可靠性的一种重要的方式就是MSS。通过MSS,应用数据被分割成TCP认为最适合发送的数据块,由TCP传递给IP的信息单位称为报文段或段(segment)。代表一个TCP socket的结构体struct tcp_sock中有多个成员用于确定应用数据被分割成最大为多大的数据块较为合适(最大报文段长度MSS)。
    我们不难联想到,跟最大报文段长度最为相关的一个参数是网络设备接口的MTU,以太网的MTU是1500,基本IP首部长度为20,TCP首部是20,所以MSS的值可达1460(MSS不包括协议首部,只包含应用数据)。
    前面的TCP三次握手协议中我们看到,通讯的双方都通过TCP选项通告了自己期望接收的MSS值,该值直接来源于struct tcp_sock的成员advmss,而这个值直接取自于网络设备接口的MTU减去IP首部和TCP首部的长度。在本地以太网中可达1460(如果首部都不含选项的话)。而成员rx_opt是一个结构体struct tcp_options_received,它记录的是来自对端的TCP选项通告,其成员mss_clamp表示mss的上限值,其来源就是对端的MSS通告,而mss_user是用户设置的mss,其优先级最高,如果有user_mss,则使用user_mss,忽略其它。
    从上面我们可以看到,MSS是可以通过SYN段进行协商的(MSS选项只能出现在SYN报文段中),但它并不是任何条件下都可以协商的,如果一方不接受来自另一方的MSS值,并且没有user_mss,则MSS就定为默认值536字节(加上首部,允许576字节的IP数据报)。实际上,struct tcp_sock->rx_opt->mss_clamp的初始值就定为536,等收到来自对端的MSS通告后,才进行修改。而结构体struct tcp_sock的成员mss_cache用于缓存上次的有效的mss,其初始值也被定为536。
    函数mytcp_sync_mss为一个tcp socket中的mss相关的成员进行数据同步,其基本的一个算法是:
    1、当前的MSS正常情况下应该为mtu-IP首部-TCP首部(不包括选项)。
    2、struct tcp_sock->rx_opt->mss_clamp中含有对端通告的能够接受的MSS值,如果该值小于第一步计算所得到的MSS,则以该值为准。
    3、IP首部如果带有IP选项,则MSS中要减去选项长度。
    4、如果MSS已经小于48了,则令其等于48。
    5、减去TCP首部中选项的长度。
    6、如果MSS当前已经大于滑动窗口大小的1/2,则取滑动窗口大小的1/2作为MSS值(但不能小于48)。
    7、成员mss_cache用于缓存下刚刚计算所得的MSS。
    所以,说本地以太网中MSS为1460的说法并不正确,它还会动态变化,如果IP首部和TCP首部中出现选项,则MSS要相应的减小,一般TCP首部中会有12字节的时间戳选项(外加两字节的填充选项),这时的MSS就等于1448。
    MSS的主要作用是限制另一端主机发送的数据的长度,同时,主机本身也控制自己发送数据报的长度,这将使以较小MTU连接到一个网络上的主机避免分段。
    struct tcp_sock有一个成员xmit_size_goal,用于记录该socket发送数据报时的segment的大小,一般情况下它的值就等于MSS(特殊情况有例外,以后再分析)。
----------------------------------------


以太网(IEEE 802.3)帧格式:

1、前导码:7字节0x55,一串1、0间隔,用于信号同步

2、帧起始定界符:1字节0xD5(10101011),表示一帧开始

3、DA(目的MAC):6字节

4、SA(源MAC):6字节

5、类型/长度:2字节,0~1500保留为长度域值,1536~65535保留为类型域值(0x0600~0xFFFF)

6、数据:46~1500字节

7、帧校验序列(FCS):4字节,使用CRC计算从目的MAC到数据域这部分内容而得到的校验和。

以CSMA/CD作为MAC算法的一类LAN称为以太网。CSMA/CD冲突避免的方法:先听后发、边听边发、随机延迟后重发。一旦发生冲突,必须让每台主机都能检测到。关于最小发送间隙和最小帧长的规定也是为了避免冲突。

考虑如下的情况,主机发送的帧很小,而两台冲突主机相距很远。在主机A发送的帧传输到B的前一刻,B开始发送帧。这样,当A的帧到达B时,B检测到冲突,于是发送冲突信号。假如在B的冲突信号传输到A之前,A的帧已经发送完毕,那么A将检测不到冲突而误认为已发送成功。由于信号传播是有时延的,因此检测冲突也需要一定的时间。这也是为什么必须有个最小帧长的限制。

按照标准,10Mbps以太网采用中继器时,连接的最大长度是2500米,最多经过4个中继器,因此规定对10Mbps以太网一帧的最小发送时间为51.2微秒。这段时间所能传输的数据为512位,因此也称该时间为512位时。这个时间定义为以太网时隙,或冲突时槽。512位=64字节,这就是以太网帧最小64字节的原因。

512位时是主机捕获信道的时间。如果某主机发送一个帧的64字节仍无冲突,以后也就不会再发生冲突了,称此主机捕获了信道。

由于信道是所有主机共享的,如果数据帧太长就会出现有的主机长时间不能发送数据,而且有的发送数据可能超出接收端的缓冲区大小,造成缓冲溢出。为避免单一主机占用信道时间过长,规定了以太网帧的最大帧长为1500。

100Mbps以太网的时隙仍为512位时,以太网规定一帧的最小发送时间必须为5.12μs。

1000Mbps以太网的时隙增至512字节,即4096位时,4.096μs。

*************************************

MTU的含义: MAC帧内的数据(Payload)字段的最大长度

    我们使用Ping命令时, -l参数所指定的数据包大小, 是指的ICMP报文中的ICMPData字段的长度,不包括ICMP Header,更不包括IPHeader.

以太网封装IP数据包的最大长度是1500字节,也就是说以太网最大帧长应该是以太网首部加上1500,再加上7字节的前导同步码和1字节的帧开始定界符,具体就是:7字节前导同步吗+1字节帧开始定界符+6字节的目的MAC+6字节的源MAC+2字节的帧类型+1500+4字节的FCS。

    按照上述,最大帧应该是1526字节,但是实际上我们抓包得到的最大帧是1514字节,为什么不是1526字节呢?原因是当数据帧到达网卡时,在物理层上网卡要先去掉前导同步码和帧开始定界符,然后对帧进行CRC检验,如果帧校验和错,就丢弃此帧。如果校验和正确,就判断帧的目的硬件地址是否符合自己的接收条件(目的地址是自己的物理硬件地址、广播地址、可接收的多播硬件地址等),如果符合,就将帧交“设备驱动程序”做进一步处理。这时我们的抓包软件才能抓到数据,因此,抓包软件抓到的是去掉前导同步码、帧开始分界符、FCS之外的数据,其最大值是6+6+2+1500=1514。

   以太网规定,以太网帧数据域部分最小为46字节,也就是以太网帧最小是6+6+2+46+4=64。除去4个字节的FCS,因此,抓包时就是60字节。当数据字段的长度小于46字节时,MAC子层就会在数据字段的后面填充以满足数据帧长不小于64字节。由于填充数据是由MAC子层负责,也就是设备驱动程序。不同的抓包程序和设备驱动程序所处的优先层次可能不同,抓包程序的优先级可能比设备驱动程序更高,也就是说,我们的抓包程序可能在设备驱动程序还没有填充不到64字节的帧的时候,抓包程序已经捕获了数据。因此不同的抓包工具抓到的数据帧的大小可能不同。下列是本人分别用wireshark和sniffer抓包的结果,对于TCP 的ACK确认帧的大小一个是54字节,一个是60字节,wireshark抓取时没有填充数据段,sniffer抓取时有填充数据段。


转自http://blog.csdn.net/naturebe/article/details/6712153

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IP数据包长度问题总结 的相关文章

  • antV G2 常用指标参数 01

    antV G2 会比较多的API 查看起来也比较费时间 所以把一些常有的方法 参数 指标列举 方便运用 01 柱状图两边留空间 time 是横坐标的 指标 chart scale time range 0 05 0 95 02 自定义纵坐标
  • Linux查找特定进程信息

    命令 查找ssh进程 root linuxcentos ps ef grep ssh 执行结果 root 1303 1 0 Apr17 00 00 00 usr sbin sshd root 3260 3087 0 Apr17 00 00
  • matlab中std函数的用法,matlab std函数 用法及实例

    MATLAB常常用到std函数来进行标准差计算 下面我就通过实例介绍一下 matlab std函数怎么用 1 std函数是用来计算标准偏差的一个函数 由于其有不同的参数 我们就用下面的例子进行介绍 A 1 2 3 1 1 1 标准差的两种计
  • Java中HashMap原理与分析

    HashMap的底层数据结构 HashMap是以Key Value的方式进行数据结构存储的一种数据结构 JDK1 7采用的是数组 链表 使用Entry类存储key和value JDK1 8采用的是数组 链表 红黑树 使用Node类存储key
  • 智星云AI主机docker使用指南

    智星云AI云主机默认提供docker安装 用户只需要在算力市场 点击 AI云主机 选择Centos或者Ubuntu系统即可租用到安装好docker的云主机 图1 算力市场 登录上云主机后 我们首先运行一个简单的docker hello wo
  • vue全局组件的引入

    1 创建组件 在自定义组件的文件夹下 layout 创建组件 并创建index js文件 2 导出组件 在index js内导出组件 可以同时注册多个组件 代码如下 import QRcode from components layout

随机推荐

  • 一些web工具的原理

    1 子域名收集工具 通过枚举可能的子域名并尝试进行DNS解析来确定是否存在有效的子域名 2 设备发现工具 通过发送 ICMP 或 ARP数据包给目标 观察目标返回的信息来判断设备是否活跃 或是通过直接向端口发送 TCP UDP 等网络请求
  • flutter图片点击跳转_Flutter “跳转页面”(一)

    跳转页面 为啥加双引号 其实所谓的跳转页面可能和以前认识的不太一样 因为在Flutter里 所有能看到的东西一般都是widget 但是 没有说那个app是由一个页面构成的 所以 这个概念确实还是有的 这个功能的实现需要用到两个东西Route
  • Vue报错Custom elements in iteration require 'v-bind:key' directives."错误解决

    错误代码
  • 造一台机器人需要哪些技能?

    转自 帐号已迁移 大家好 我是小王 是一名刚刚加入机器人队的大学生 有人说搞机器人特别简单 只要画画图 拧拧螺丝 敲敲代码就可以了 He tui 要这么容易 每年能有上百支机器人队伍 花十几万挤破了头都抢不到30万奖金吗 不过 团队有了我这
  • Osmosis 0.46详细使用说明

    原文地址 http wiki openstreetmap org wiki Osmosis Detailed Usage 0 46 全局选项 Short Option Long Option Description v verbose 需要
  • 图神经网络基础(part 1)

    文章目录 一 图的基本概念 二 简易图谱论 2 1 拉普拉斯矩阵 2 2 拉普拉斯二次型 2 3 拉普拉斯矩阵与图扩散 2 4 图论傅里叶变换 一 图的基本概念 对于接触过数据结构和算法的人来说 图并不是一个陌生的概念 一个图 Graph
  • 解释器-架构案例2021(三十一)

    软件架构设计与评估 某公司支持用户使用浏览器在线进行基于机器学习的智能应用开发活动 该平台核心应用场景是用户拖拉拽算法组件灵活定义机器学习流程 采用自助方式智能应用设计 实现与部署 并开发新算法加入平台 a 平台用户分为算法工程师 软件工程
  • markdown使用手册

    目录 记录 04 学会用SLA评估系统 功能快捷键 合理的创建标题 有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中 居左 居右 SmartyPants 创建一
  • 前端上传组件Plupload使用指南 与swfupload一样强大

    http blog csdn net z69183787 article details 46698741 Plupload 是一款由著名的web编辑器 TinyMCE 团队开发的上传组件 简单易用且功能强大 我们完全可以使用Pluploa
  • 静态资源加载不到解决办法

    这是我总结的几种解决办法 可以自行尝试实在不行都加上 第一种在springmvc配置文件当中加入资源映射
  • 选课微信小程序开发 java

    1 使用技术 java springboot mysql hibernate 微信小程序 2 功能介绍 后台管理 学生管理 课程管理 类型管理 选课管理 操作中心 管理员中心 导入导出学生 微信小程序端 学生端 查看课程 选课 查看选课课程
  • 网络爬虫是怎么运行的

    2 2 1知识概述 网络爬虫究竟是怎么运行的 单个页面是如何运行的 1 指定一个url 2 使用技术发送get请求 3 获得服务端的响应 4 将二进制的数据 转化成HTML文档 网络爬虫一般会爬取很多很多很多的页面 for 1 指定一个ur
  • 如何在TheBrain中为Plex选择自定义图像并更改默认字体?

    TheBrain 点击下载 您的终极数字记忆和无限思维导图软件 我们从一个想法跳到另一个想法 构建越来越复杂的网络 直到新想法形成 TheBrain允许你以同样的方式组织你的信息 而不限制你预先确定的文件结构 事实上 你的数字大脑是没有限制
  • Unix/Linux编程:文件树遍历-----nftw()

    nftw 函数是对执行类似功能的老函数 ftw 的加强 由于提供了更多功能 对符号链接的处理也更易于把握 GNU C 语言函数库也提供了派生自 BSD 分支的 fts API fts open fts read fts children f
  • telnet配置及用法

    内容转载 http jingyan baidu com article ae97a646b22fb6bbfd461d19 html 搭建或配置网络环境时 经常会使用ping命令检查网络是否可达 有些时候Ping命令也不好使 比如因防火墙禁止
  • 中国半导体硅片行业未来发展趋势与销售规模预测报告2022版

    中国半导体硅片行业未来发展趋势与销售规模预测报告2022版 HS HS HS HS HS HS HS HS HS HS HS HS 修订日期 2021年11月 搜索鸿晟信合研究院查看官网更多内容 第一章 半导体硅片相关概述 1 1 半导体硅
  • C语言向上取整数简单写法

    C语言整数除法向上取整 define GET M N M 1 N 1 实例 一共100字节的数据 一次发送11字节 需要发送多少次 GET 100 16 7 次
  • 记录一道leetcode算法题的坑

    题目链接 这个题并不难 只是想让自己牢记一句老话 题目里面的每个条件都有用 int twoSum int nums int numsSize int target int returnSize int a 2 0 注意 注意 注意 retu
  • Mathematica 随机打乱列表顺序/列表随机重排列

    更新 找到相关函数了 没仔细看说明以为RandomSample只能随机取样来着 汗 RandomSample list 原内容 没必要看了 没有找到直接的相关函数 想到的方法是随机交换列表元素 例如以下程序为1 10的数字乱序 Permut
  • IP数据包长度问题总结

    首先要看TCP IP协议 涉及到四层 链路层 网络层 传输层 应用层 其中以太网 Ethernet 的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据 Data 在应用层 它们的关系是 数据帧 IP包 TCP