TCP网络数据包啥时候会在应用层分片?
Posted
技术标签:
【中文标题】TCP网络数据包啥时候会在应用层分片?【英文标题】:When will a TCP network packet be fragmented at the application layer?TCP网络数据包什么时候会在应用层分片? 【发布时间】:2010-10-19 21:31:49 【问题描述】:TCP 数据包何时会在应用层分片?当一个应用程序发送一个 TCP 数据包时,应用程序层的接收者会收到两个或多个数据包中的数据包吗?如果是,是什么条件导致数据包被分割。似乎一个数据包在达到 1500 字节的以太网(在网络层)限制之前不会被分段。但是,由于网络层会在将数据包发送到下一层之前重新组装这些碎片,因此该碎片对于应用层的接收者来说是透明的,对吧?
【问题讨论】:
唯一可以在应用层对 TCP 传输进行分段的就是应用程序。你的问题真的没有意义。 【参考方案1】:如果一个 3000 字节的数据包进入默认 MTU 大小为 1500(对于以太网)的以太网网络,它将被分成两个长度为 1500 字节的数据包。这是我唯一能想到的。
Wireshark 是检查这一点的最佳选择。我已经使用了一段时间了,印象深刻
【讨论】:
那么,接收应用会在应用层收到两个包还是一个包? 应用层没有 MTU 和数据包分片的概念。它是一个独立的层,与网络和传输层的职责不同。这么快回答,App层看不到两个包。【参考方案2】:如果一个数据包超过网络设备的最大MTU,它将被分成多个数据包。 (注意大多数设备设置为 1500 字节,但这不是必需的。)
数据包的重构应该对应用程序完全透明。
【讨论】:
【参考方案3】:正确 - 了解这一点的最有用的方法是使用 Wireshark,这是一个非常宝贵的工具。花点时间弄清楚 - 已经救了我好几次,并且很好地检查了现实
【讨论】:
【参考方案4】:不同的网段可以有不同的 MTU 值。在这种情况下,可能会出现碎片。欲了解更多信息,请参阅TCP Maximum segment size
这种(去)碎片化发生在 TCP 层。在应用层没有更多的数据包。 TCP 向应用程序提供一个连续的数据流。
【讨论】:
【参考方案5】:在应用层,有很多原因导致整个 1500 字节可能无法显示一次读取。内部操作系统和 TCP 堆栈中的各种因素可能会导致应用程序在一次读取调用中获取一些字节,而在下一次读取调用中获取一些字节。是的,TCP 堆栈必须在发送数据包之前重新组装数据包,但这并不意味着您的应用程序会一次性获得所有数据(很可能会一次读取,但不能保证一口气读完)。
TCP 试图通过错误检查、自动重新发送等在您的背后进行,以保证字节的有序传递。将其视为应用层的管道,不要太拘泥于堆栈如何通过网络实际发送它。
【讨论】:
【参考方案6】:当它遇到 MTU 低于数据包大小的网络设备时,它将被拆分。大多数以太网设备是 1500,但它通常可以更小,例如 1492,如果该以太网由于额外的路由信息而通过 PPPoE (DSL),如果添加第二层,例如 Windows Internet 连接共享,它甚至会更低。而且拨号一般是576!
一般来说,尽管您应该记住 TCP 不是数据包协议。它使用最底层的数据包通过 IP 传输,但就任何 TCP 堆栈的接口而言,它是一个流协议,不需要为您提供与发送或接收的物理数据包的 1:1 关系(例如,大多数堆栈将保留消息直到某个时间段到期,或者有足够的消息来最大化给定 MTU 的 IP 数据包的大小)
例如,如果您发送了两个“数据包”(调用您的发送函数两次),接收程序可能只会收到 1 个“数据包”(接收 TCP 堆栈可能会将它们组合在一起)。如果您通过 TCP 实现消息类型协议,则应在每条消息的开头包含一个标头(或其他一些标头/页脚机制),以便接收方可以将 TCP 流拆分回单独的消息,无论是当消息分两部分接收,或者当多个消息作为一个块接收时。
【讨论】:
它确实取决于沿途每一跳的 MTU(实际上是最小的 MTU)。但是对于小型有效载荷(如 OP 的问题中的 10 或 20 个字节),可以“几乎可以肯定”,如果整个数据包(包括每个协议层的所有标头,即使是在顶部添加的标头),它也不会被分段通过,比如说,***)+有效负载的大小在ipv4最小大小的限制内。在en.wikipedia.org/wiki/Maximum_transmission_unit 上,您可以看到对于 ipv4,您可以保证在跃点上的最大 MTU 至少为 68 字节(不是有效负载!)。 还有一个参数MSS
这里就不说了。【参考方案7】:
分片对 TCP 应用程序应该是透明的。请记住,TCP 是一种流协议:您得到的是数据流,而不是数据包!如果您基于完整数据包的概念构建应用程序,那么您将遇到问题,除非您添加一个抽象层来从流中组装整个数据包,然后将数据包传递给应用程序。
【讨论】:
【参考方案8】:“应用层”一个 TCP 数据包(嗯,真的是分段;TCP 在它自己的层不知道数据包)永远不会分段,因为它不存在。在应用层,您可以将数据视为字节流,可靠且有序地传递。
如果您有其他想法,那么您可能以错误的方式处理某些事情。但是,这并不是说在这之上可能没有一层,例如,通过这个可靠的有序字节流传递的消息序列。
【讨论】:
【参考方案9】:这个问题做了一个不正确的假设——TCP 不将数据包传送到它的端点,而是发送一个字节流(八位字节)。如果应用程序将两个字符串写入 TCP,它可能会在另一端作为一个字符串传递;同样,一个字符串可以作为两个(或更多)字符串传递到另一端。
RFC 793,第 1.5 节:
"TCP 能够传输一个 每个字节中的连续八位字节流 用户之间的方向 将一些八位字节打包成 段通过传输 互联网系统。”
关键字是八位字节的连续流(字节)。
RFC 793,第 2.8 节:
"没有必然关系 推送函数和段之间 边界。任何特定的数据 段可能是单个的结果 SEND 呼叫,全部或部分,或 多个 SEND 调用。”
第 2.8 节的全部内容都是相关的。
【讨论】:
【参考方案10】:This 页面是有关其他人提出的一些问题的良好信息来源,即需要在应用程序协议的基础上按应用程序协议进行数据封装 在您描述的意义上不是很权威,但它有示例并且来自网络编程领域的一些相当大的人物。
【讨论】:
以上是关于TCP网络数据包啥时候会在应用层分片?的主要内容,如果未能解决你的问题,请参考以下文章
计算机网络 王道考研2021 第四章:网络层 -- 网络层功能概述IP数据报格式(TCP/IP协议栈)IP数据报分片(MTU)