在看待数据的传输时,人们首要考虑的是:
而不是:
于是:
如何发现对端没有收到呢?又如何晓得对端已经收到呢? 使用TCP,TCP可以解决这些问题。 这实际是在循环论证。 人们习惯了TCP,所以才会首先考虑本文最开始的问题。 不信你去问他们为什么不用UDP。 他们肯定说UDP不可靠,丢包了不知道。 绝大多数传输需求都在TCP之后产生,甚至UDP也是为保持IP的语义从TCP剥出的。 IP本是尽力而为,若想尽力而为,需要一个与TCP并列的UDP。 当使用UDP承载HTTP时,他们会在UDP上实现丢包检测和重传。 他们说,HTTP必须不能丢包啊。 可难道不是因为先有了TCP才让HTTP有所依托,HTTP才不能丢包的吗? 当传输流媒体时,他们会说关键帧不能丢。 难道不是因为TCP保证可靠传输才使流媒体将关键帧放心编码到TCP的吗? 时代变了,直播的低延时刚需让TCP不再适合,可UDP上却依然叠加了纷乱复杂的重传策略。 为什么数据就是不能丢呢?为什么丢了非要重传呢? 他们说,丢了不恢复,上层逻辑就乱了。 这里面难道没有TCP的影子? 他们甚至不曾想到用TCP传输不能丢的关键帧,用UDP传输非关键帧丢了拉倒。 他们甚至可以修改TCP让它一个关键帧传两遍。 但让接收端决定能不能丢难道就是不可以吗? 当然可以用NACK促成此事。让接收端决定。 可他们总能说出100个NACK的缺陷,却总绕不开本文开端的问题。 NACK丢了怎么办?如何区分NACK丢了还是重传丢了? 丢就丢了呗,为什么老纠结丢了呢? 丢了要重传,为什么老纠结重传呢? 核心还是“不能丢”的观念。 他们受TCP影响太大。 他们总期许网络会提供一定的承诺。 于是他们开始赌概率。 弱网场景,少传一点总能保证一定的成功率。 只传输最关键的数据,其它主动丢弃,如何? 轻装撤退? 但很遗憾,网络什么都保证不了。 丢弃数据换成功率只是一厢情愿。 你少发以求不丢,你以为信道被你独有。 数据还是会丢,丢了还不告诉你。 你“丢数据”还是为了“不能丢”。 关键还是“不能丢”。 寓形宇内复几时?曷不委心任去留。 忘掉TCP,看另一种传输方式。 与TCP相反的,人的交流方式。 人采用NACK策略,没有消息就是好消息。 如果没听清,对方会让你再说一遍。 对方若静默,你也不会重复说,你只是探活:还在吗? 需要什么,对方要求,若没要求,你就只管说, 或者静默。 没有反馈环,没有自时钟。 需要的数据丢了怎么办?对端会要求你再发一遍。 什么?指望对端要求? 我要保留数据到什么时候?我又什么时候清除已传输的数据? 这不,又陷进TCP了吧。 数据在发送端岂不是永久保留? 你见过数据发送之后即删除的吗? 重传队列,那是TCP的事,事实上并不存在。 重传队列只是一个cache。 可是,没有反馈,拥塞控制怎么做? TCP有反馈,可它的拥塞控制做得并不好。 可反馈仅指示拥塞控制的时机, 拥塞控制起作用依赖的却是数学上的AIMD。 对端告诉你实际接收速率, 你照着发岂不是更好? 这便是rate-based拥塞控制,这是天然的收敛。 可是TCP却做不到,TCP不得不间接数ACK来测算rate。 简单的反馈速率不实施,却要测算? TCP做不到啊。 所以TCP只能近似实施rate-based拥塞控制。 终于,TCP并不是什么都好。 单向有损传输才是纯粹的传输。 接收端反馈所求与所需, 而不反馈数据是否被接收。 这种策略对流媒体传输很友好。 配合编解码在时间和空间的颠倒, 你将得到意想不到的回报。 你要主动做FEC吗? FEC难道不是一种编码吗? 这便做不做均可了。 依然类比人的通信方式,人脑天然具有FEC能力。 计算机没这能力,便诉诸编码。 我还是建议不做FEC。 若求低延时,FEC将消耗大量不必要的带宽。 若求高吞吐,FEC将消耗大量带内的带宽。 那便无论如何都不需要了。 为1%的场景对全序列做FEC,得不偿失。 问题是,若你能精确识别1%的数据,那便为他们加入FEC编码吧, 比丢了强。 不是说丢了也不重传了吗? 我是说,用FEC换接收端的要求,无关重传。 忘了TCP吧,忘了TCP吧。 TCP对人们的影响太大了。 如果TCP确实影响了人们对传输的理解和控制, 那么记住确实比忘掉来得容易。 你也许只是记住了TCP,其实我也是。
浙江温州皮鞋湿,下雨进水不会胖。
|