我正在学习互联网协议和相关原理的基础知识。我最近进行了比较 UDP 和 TCP 的实验。但是当我这样做时(使用 ttcp 程序)它只有一个进程和一个端口。IIUC 我们不能在同一个端口上并行化,但是我们可以通过在多个端口上并行使用多个进程发送多个传输来提高“效率”(吞吐量甚至发送的总数据)吗?为什么不?
并行数据传输理念的优缺点
如果您有一个与主机连接的链接,那么您的数据只会以串行方式发送,因此将数据流拆分为“并行”流实际上只会缓冲多个争用接口的流,而不是在接口上排队的一个流。
另一方面,如果您有来自主机的多条路径,将数据流拆分为多个流可能会导致数据包传输无序,这可以由 TCP 处理,但在提供数据之前重新排序数据会降低性能到另一端的应用程序,但 UDP 不会在将乱序数据传递给应用程序之前对其进行重新排序,因此必须由应用程序协议处理,对于 VoIP 或视频,延迟数据是无用的,必须丢弃。
有些情况下并行流似乎更有效,例如 HTTP 将页面请求拆分为不同页面元素的不同流,以使页面的各个部分看起来同时加载。它并不是真的更有效,因为一切都是序列化的,尽管是交错的,但它在视觉上更具吸引力。
如果您有一个与主机连接的链接,那么您的数据只会以串行方式发送,因此将数据流拆分为“并行”流实际上只会缓冲多个争用接口的流,而不是在接口上排队的一个流。
上述陈述在逻辑上是有道理的。虽然情况经常如此,但还有另一个因素需要考虑。
发送的数据包不能保证到达预期的接收者,而不会丢失、延迟、错误排序或损坏。TCP 层保证数据将被正确传递,或者至少它会通知您它尝试了所有可能的尝试都失败了。
为了做到这一点,发送方发送一些数据并等待接收方确认它已正确接收,然后再发送更多数据。如果它在一定时间内未能得到确认或收到错误接收的通知,它可以重试发送相同的数据一定次数,直到确认一切正常。在继续之前等待确认也可以防止发送方发送数据的速度超过接收方可能能够处理传入数据的速度。为了优化各种条件下的数据传输,使用了许多复杂的算法来动态协商并不断调整确认之间可以发送的数据量、等待确认的时间长度等。
正是这种确认之间的等待时间是理解为什么多个并行数据流有时可以比单个流执行得更好的关键,即使它们必须共享相同的单个链接。
当网络速度很快、没有拥塞、错误和丢包并且端点彼此“接近”时,传输和确认的往返行程非常短,几乎没有时间等待确认。网络链接一直忙于主动数据传输,如果有的话,并行化它并没有多大帮助。
但是,请考虑另一个端点是否远离繁忙的网络,数据包从一个端点传输到另一个端点所需的时间相对较长。发送者将有一段时间无法发送,因为它正在等待确认消息返回,然后再发送更多消息,并且网络链接在部分时间处于空闲状态。
在这种情况下提高吞吐量的一种方法是启动多个并行对话。它们将随机地最终处于发送/确认/等待周期的不同部分。当对话 A 处于等待状态时,对话 B 可以使用链接进行发送,并且对话 C 正在发送,而 B 和 A 都在等待,依此类推。
这有其局限性,因为当多个对话准备好一次发送数据时,它们最终会开始相互竞争。并行流的最佳数量将因情况而异。在有助于并行化的情况下,添加前几个通常会增加最大的收益,之后的每次添加收益都会递减。还有其他限制,包括可用 CPU、内存和磁盘吞吐量。
通常,对于单个应用程序来说,跟踪多个并行数据流(应该表示单个文件等)并试图弄清楚如何将这些数据拆分为并行流然后再重新组合,这在编程方面太复杂了.
当您有许多较小的文件要移动并且每个文件都可以由单个文件传输程序移动时,通常最简单的并行数据传输方法就出现了。例如:假设您要移动 30 个大小大致相同的文件:文件传输程序的三个实例可以同时运行,第一个负责文件 00-09,第二个负责 10-19,第三个负责 20- 29.
除了在慢速网络上更优化地移动数据之外,还有其他好处。如果需要在每一端对数据流进行额外的处理工作,例如为了安全而进行的加密/解密,则可以利用多个 CPU 处理内核(现在在大多数计算机上很常见)来处理多个流。在按顺序发送所有内容的情况下,通常只有一个 CPU 内核能够完成这项工作。