当发送大于 SendBufferSize 的数据时,数据将如何接收?

Aar*_*ndt 3 .net c# tcp networkstream tcpclient

我刚刚问了一个关于如何发送大于 SendBufferSize 的数据的问题,答案是将分几个部分发送。

我的第二个问题是如何接收这些数据?它会在网络流中完整还是会被分割。

第一个问题:您可以通过 TcpClient 发送大于 SendBufferSize 的文件吗?

Kar*_*uru 5

TCP 不是仅消息协议。它是一个基于流的协议,负责为我们拆分数据。Lemme 带您进入核心部分。在 TCP 的情况下有两个部分 - Segmentation 和 Fragmentation。

分段发生在 TCP(传输层)。这取决于两个参数 - MSS 和窗口大小。MSS 确定设备可以接收的最大段大小。MSS 在初始连接建立期间通过 TCP 选项进行通信。数据流的每个方向可以使用不同的 MSS,由操作系统决定。但是,窗口大小由接收方在 TCP 标头中发送,以在等待接收主机的确认和窗口更新之前,在连接的接收端传输一次可以缓冲的最大数据。也就是说,主机可以在用尽接收器的窗口大小之前发送多个段(MSS 的因子)。

分片以两种方式在 IP(网络层)发生。如果发送方和接收方之间的通信路径上没有具有 MTU 限制的设备,则仅满足以太网的 MTU(1500 字节)就会发生分片。但是,如果在发送方和接收方之间存在具有 MTU 限制的中间设备,IP 层(互联网协议)会进行数据报分段,以便可以形成数据包,以便它们可以通过具有较小最大传输单元的链路( MTU) 比原始数据报大小。对于具有 MTU 限制的中间设备,发送方还应部署路径 MTU 发现,以确定网络路径中通往接收方的最小 MTU,并动态调整 MSS 以避免网络内的 IP 分片。路径 MTU 发现是通过设置 DF (Don' t Fragment) 选项在传出数据包的 IP 标头中。发送方和接收方之间通信路径中的任何设备,其 MTU 小于数据包,将丢弃此类数据包,并使用包含设备 MTU 的 ICMP“目标不可达(数据报太大)”消息回复发送方。该信息允许发送方适当地减少其假定的路径 MTU。

因此,这导致了 MSS 和 MTU 之间的关系点。RFC 791 指出“所有主机必须准备好接受最多 576 个八位字节的数据报(无论它们是完整的还是分段的)”。因此,IP 网络的最小 MTU 是 576。在 TCP 的情况下,扣除 TCP 标头的 20 个字节和 IP 标头的 20 个字节,我们将给我们 536 个字节作为 TCP 的标准 MSS。

现在,让我们进入重新组装部分。分段可以基于中间设备上的 MTU 发生,但重组只能在目标设备上发生。TCP 负责分段,但在目标设备上,TCP 应负责排序,但应用程序应负责段的重新组装。

因此,如果您只需要基于完整消息的通信并且不关心可靠性,那么 UDP 将是您的选择。但是请注意,如果您可以通过拆分发送大数据,UDP 将无法确保数据包的顺序,也无法处理数据包丢失,因为它没有重传等纠错机制.

如果您想像在 UDP 中一样进行基于消息的通信,但又要结合 TCP 功能,例如可靠的按顺序交付、拥塞控制以及在其之上的其他改进/功能,例如多流、多宿主、in-内置MTU发现,那么SCTP应该是你的选择。但是,如果您的网络中有传统的 NAT 系统,那么您可能需要将 SCTP 封装在 UDP 中。