什么时候TCP网络数据包会在应用层被分割?

什么时候TCP网络数据包会在应用层被分割?,tcp,network-programming,packet,Tcp,Network Programming,Packet,什么时候TCP数据包会在应用层被分割?当从应用程序发送TCP数据包时,应用层的接收方是否会收到两个或更多数据包中的数据包?如果是,是什么条件导致数据包被分割。似乎一个数据包在达到以太网(在网络层)1500字节的限制之前不会被分割。但是,对于应用层的接收者来说,这个片段是透明的,因为网络层将在将数据包发送到下一层之前重新组装片段,对吗 如果一个3000字节的数据包进入一个默认MTU大小为1500(以太网)的以太网网络,它将被分为两个数据包,每个数据包的长度为1500字节。那是我能想到的唯一一次 W

什么时候TCP数据包会在应用层被分割?当从应用程序发送TCP数据包时,应用层的接收方是否会收到两个或更多数据包中的数据包?如果是,是什么条件导致数据包被分割。似乎一个数据包在达到以太网(在网络层)1500字节的限制之前不会被分割。但是,对于应用层的接收者来说,这个片段是透明的,因为网络层将在将数据包发送到下一层之前重新组装片段,对吗

如果一个3000字节的数据包进入一个默认MTU大小为1500(以太网)的以太网网络,它将被分为两个数据包,每个数据包的长度为1500字节。那是我能想到的唯一一次


Wireshark是检查此问题的最佳选择。我已经使用它一段时间了,我印象深刻

如果一个数据包超过了网络设备的最大值,它将被分成多个数据包。(注意,大多数设备设置为1500字节,但这不是必需的。)


数据包的重建对应用程序来说应该是完全透明的。

正确-看到这一点最有用的方法是使用一个非常宝贵的工具。花点时间想一想,这已经帮我省了好几次钱,并且给了我一个很好的现实检查

不同的网段可以有不同的MTU值。在这种情况下,可能会出现碎片。有关更多信息,请参阅


这种(反)分段发生在TCP层。在应用层,没有更多的数据包。TCP向应用程序提供了一个连续的数据流。

在应用程序层,有许多原因可以解释为什么整个1500字节可能不会显示一次读取。内部操作系统和TCP堆栈中的各种因素可能导致应用程序在一次读取调用中获取一些字节,在下一次读取调用中获取一些字节。是的,TCP堆栈必须在发送数据包之前重新组装数据包,但这并不意味着您的应用程序将在一次读取中获得所有数据包(很可能在一次读取中获得数据包,但不能保证在一次读取中获得数据包)


TCP试图保证字节的有序传递,错误检查、自动重新发送等都在背后发生。将其视为应用层的一个管道,不要陷入堆栈如何通过网络发送的困境。

当它到达MTU小于数据包大小的网络设备时,它将被拆分。大多数以太网设备都是1500台,但由于额外的路由信息,如果以太网通过PPPoE(DSL)传输,它通常会更小,比如1492台,如果添加第二层(如Windows Internet连接共享),它甚至会更低。而且拨号通常是576

但一般来说,您应该记住TCP不是数据包协议。它使用最低级别的数据包通过IP进行传输,但就任何TCP堆栈的接口而言,它是一种流协议,不需要为您提供与发送或接收的物理数据包的1:1关系(例如,大多数堆栈将保留消息,直到某个时间段过期,或者有足够的消息来最大化给定MTU的IP数据包大小)


例如,如果您发送了两个“数据包”(调用发送函数两次),则接收程序可能只接收1个“数据包”(接收TCP堆栈可能将它们组合在一起)。如果您通过TCP实现消息类型协议,则应在每条消息的开头包含一个标头(或其他一些标头/脚注)因此,当一条消息分为两部分接收时,或者当多条消息作为一个块接收时,接收方可以将TCP流拆分为单独的消息。

碎片对于TCP应用程序来说应该是透明的。请记住,TCP是一个流协议:如果您正在构建,您将获得的是数据流,而不是数据包如果你的应用程序基于完整数据包的思想,那么你就会遇到问题,除非你添加一个抽象层来组装流中的整个数据包,然后将数据包传递给应用程序。

A“应用层”是一个TCP数据包(好吧,实际上是分段的;TCP在它自己的层不知道来自数据包)因为它不存在,所以永远不会被分割。应用层是您将数据视为字节流的地方,可靠且有序地交付


如果你不这么想,你很可能是以错误的方式来处理某件事。然而,这并不是说在这上面可能没有一层,比如说,在这个可靠的、按顺序按TestStream传递的消息序列。

这个问题做出了一个不正确的假设——TCP不会将数据包传递到它的endpo相反,它发送字节流(八位字节)。如果应用程序将两个字符串写入TCP,则可以在另一端作为一个字符串传递;同样,一个字符串也可以在另一端作为两个(或更多)字符串传递

,第1.5节:

“TCP能够传输 连续的八位字节流 通过 将一定数量的八位字节打包到 通过网络传输的数据段 互联网系统。”

关键词是连续的八位字节流(字节)

,第2.8节:

“没有必要的关系 在推送功能和段之间 边界。任何特定的数据 段可能是单个 发送呼叫,全部或部分,或 多个发送呼叫。“

第2.8节的全部内容都是相关的。

页面是关于其他人提出的一些问题的良好信息来源,即需要在应用程序协议基础上逐个应用程序协议进行数据封装,这在您描述的意义上不是很权威,但它有一些示例,并且来源于一些相当大的名字在网络编程中