TCP/UDP/IP报文大小

打印 上一主题 下一主题

主题 972|帖子 972|积分 2916

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
TCP/UDP/IP报文大小

1、概述

首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层。此中以太网(Ethernet)的数据帧在链路层

IP包在网络层

TCP或UDP包在传输层

TCP或UDP中的数据(Data)在应用层

它们的关系是 数据帧{IP包{TCP或UDP包{Data}}}

不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据报(datagram),在链路层叫做帧(frame)。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,末了将应用层数据交给应用程序处置惩罚。

在应用程序中我们用到的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字节以内
MSS的主要作用是限制另一端主机发送的数据的长度,同时,主机自己也控制自己发送数据报的长度,这将使以较小MTU连接到一个网络上的主机避免分段。
MTU的含义: MAC帧内的数据(Payload)字段最大长度
 

2、TCP、UDP数据包最大值简直定 

UDP和TCP协议使用端标语实现多项应用同时发送和汲取数据。数据通过源端口发送出去,通过目的端口汲取。有的网络应用只能使用预留或注册的静态端口;而别的一些网络应用则可以使用未被注册的动态端口。因为UDP和TCP报头使用两个字节存放端标语,所以端标语的有效范围是从0到65535。动态端口的范围是从1024到65535。
MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,Ethernet II帧的结构DMAC+SMAC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64Bytes最大不能超过1518Bytes,对于小于大概大于这个限制的以太网帧我们都可以视之为错误的数据帧,一般的以太网转发设备丢弃这些数据帧。

由于以太网EthernetII最大的数据帧是1518Bytes如许,刨去以太网帧的帧头(DMAC目的MAC地址48bits=6Bytes+SMAC源MAC地址48bits=6Bytes+Type域2Bytes)14Bytes和帧尾CRC校验部分4Bytes那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes这个值我们就把它称之为MTU
  链路层帧的大小 1500(不包括帧头、帧尾)
UDP 包的大小就应该是 1500 - IP头(20) - UDP头(8) = 1472(Bytes)
TCP 包的大小就应该是 1500 - IP头(20) - TCP头(20) = 1460 (Bytes)

注:PPPoE所谓PPPoE就是在以太网上面跑“PPP”。随着宽带接入(这种宽带接入一般为Cable Modem大概xDSL大概以太网的接入),因为以太网缺乏认证计费机制而传统运营商是通过PPP协议来对拨号等接入服务举行认证计费的,所以引入PPPoE。PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes,就酿成1492。不过目前大多数的路由设备的MTU都为1500。

假如我们定义的TCP和UDP包没有超过范围,那么我们的包在IP层就不消分包了,如许传输过程中就避免了在IP层组包发生的错误;假如超过范围,既IP数据报大于1500字节,发送方IP层就需要将数据包分成若干片,而汲取方IP层就需要举行数据报的重组。更严重的是,假如使用UDP协议,当IP层组包发生错误,那么包就会被丢弃。汲取方无法重组数据报,将导致丢弃整个IP数据报。UDP不包管可靠传输;但是TCP发生组包错误时,该包会被重传,包管可靠传输。
UDP数据报的长度是指包括报头和数据部分在内的总字节数,其报头长度固定,数据部分可变。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节(64K)。
我们在用Socket编程时,UDP协议要求包小于64K。TCP没有限定,TCP包头中就没有“包长度”字段,而完全依靠IP层去处置惩罚分帧。这就是为什么TCP经常被称作一种“流协议的原因,开发者在使用TCP服务的时间,不必去关心数据包的大小,只需讲SOCKET看作一条数据流的入口,往内里放数据就是了,TCP协议自己会举行拥塞/流量控制。 
不过鉴于Internet(非局域网)上的标准MTU值为576字节,所以建议在举行Internet的UDP编程时,最好将UDP的数据长度控制在548字节 (576-8-20)以内

 

3、TCP、UDP数据包最小值简直定

在用UDP局域网通讯时,经常发“Hello World”来举行测试,但是“Hello World”并不满足最小有效数据(64-46)的要求,为什么小于18个字节,对方仍然可以收到呢?因为在链路层的MAC子层中会举行数据补齐,不敷18个字节的用0补齐。但当服务器在公网,客户端在内网,发生小于18个字节的数据,就会出现汲取端收不到数据的环境。

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

4、实际应用

用UDP协议发送时,用sendto函数最大能发送数据的长度为:65535- IP头(20) - UDP头(8)=65507字节。用sendto函数发送数据时,假如发送数据长度大于该值,则函数会返回错误。 
用TCP协议发送时,由于TCP是数据流协议,因此不存在包大小的限制(暂不思量缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送出去,假如这段数据比较长,会被分段发送,假如比较短,可能会等候和下一次数据一起发送。

  也就是说以链路数据帧的长度必须在46-1500字节之间,这个1500字节被称为链路层的MTU(最大传输单元)

  超过1500字节怎么办?

  这也就是说IP数据报大于1500字节,大于MTU.这个时间发送方IP层就需要分片(fragmentation). 
  把数据报分成若干片,使每一片都小于MTU.而汲取方IP层则需要举行数据报的重组. 
  如许就会多做很多事变,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,汲取方便无法重组数据报.将导致丢弃整个UDP数据报。 

  举行Internet编程时则不同,因为Internet上的路由器可能会将MTU设为不同的值. 
  假如我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机制来调整MTU值,使数据报可以或许顺利到达目的地,如许就会做很多不须要的操作。鉴于Internet上的标准MTU值为576字节,所以我建议在举行Internet的UDP编程时. 最好将UDP的数据长度控制在548字节(576-8-20)以内。

IP层:

对于IP协议来说,IP包的大小由MTU决定(IP数据包长度就是MTU-28(包头长度)。 MTU值越大,封包就越大,理论上可增长传送速率,但 MTU值又不能设得太大,因为封包太大,传送时出现错误的时机大增。一般默认的设置,PPPoE连接的最高MTU值是1492, 而以太网 (Ethernet)的最高MTU值则是1500,而在Internet上,默认的MTU大小是576字节

那么就一个题目, 用wireshark捕包。 为什么frame那一行是1514bytes?

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

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

   如下图:


Preamble

Destination MAC address

Source MAC address

Type/Length

User Data

Frame Check Sequence (FCS)

8

6

6

2

46 - 1500

4


  注意:

MSS(Maximum Segment Size最大报文段长度 是 传输层 概念, 在创建TCP连接过程, 两边的SYN 报文中定义的 , 通讯两边会根据两边提供的MSS值得最小值确定为这次连接的最大MSS值。

  后面的数据传输都是按照确定的MSS举行传输。 MSS会根据物理接口的MTU计算得出 (MSS=MTU-IP头长度-TCP头长度)

MTU (max transfer unit) 是 数据链路层 中的概念,需要在 网卡中设置 的,假如IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就需要举行分片(fragmentation),把数据报分成若干片,如许每一片都小于MTU。

  对于一个以太网来说,TCP的最大报文段长度即MSS一般是1460字节(1500(MTU) - 20(IP head) - 20(TCP head) = 1460 Byte)减去12字节的TCP timestamp option,留给TCP正文数据是 1448字节 。别的,TCP流量控制接纳了滑动窗口机制,发送窗口的大小要小于min(汲取端通告的汲取窗口大小,发送端拥塞窗口大小)。

google得知Linux 2.6.39内核之前的TCP实现中,发送端初始拥塞窗口为3,单元是MSS (server机器内核版本未知,估计是2.6.39以前的)。也就是说TCP连接创建后,初始拥塞窗口限制第一次发送的数据长度要小于等于 1448 * 3 = 4344 字节,所以客户端 第一次recv 调用只收到了4344字节 数据。



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表