TCP 和 IP 「越界」行为的一点思考

最近在看书的时候看到一段有意思的注解。

首先,我们知道接收网络包的时候,IP 层完成一系列操作,将包交给 TCP 层时,TCP 要根据 IP 头部中的双方 IP 地址、TCP 头部中的双方端口号来查找对应的套接字,关于这个细节,引发了一点思考。

严格来说,TCP 模块和 IP 模块有各自的责任范围,TCP 头部属于 TCP 模块的责任范围,而 IP 模块属于 IP 模块的责任范围。根据这样的逻辑,当包交给 TCP 模块以后,TCP 模块需要查询 IP 头部中接收方和发送方的 IP 地址来找到相应的套接字,这个过程就显得有点「越界」。如果要避免「越界」,应该对两者进行明确的划分,IP 模块只向 TCP 模块传递 TCP 头部以及之后的数据,而对于 IP 头部中重要的信息,则由 IP 层通过参数的形式传递给 TCP。

然而,如果根据这样严格的划分来开发的话,IP 和 TCP 之间的交互就会产生更多成本,而且这两个模块之间进行交互的频率和场景其实很多,总体的交互成本就会很高,程序的运行效率就会下降。

因此,不妨将责任划分的宽松一点,将 TCP 和 IP 当做一个整体来看待,这样可以带来更大的灵活性。 日常开发中也经常会有这样的情况,我们为了维护方便、架构清晰,会将逻辑分为多层,力求严格按照层级划分去迭代,不出现「越界」的行为,但有时候一味追求层级界线确实会产生额外的成本,TCP/IP 这样庞大成熟的体系,也会出现类似的问题,也会为了解决问题而做一些「妥协」。

没有谁可以设计出完美的架构,所谓完美,可能就是在某种程度上,灵活和成本之间的权衡。