加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

TCP没那么难吧?这篇一定要看

发布时间:2018-09-03 17:23:21 所属栏目:教程 来源:余晟
导读:9月15日技术沙龙 | 如何将智能化和运维工作相结合,实现智能运维! 2013年,慕尼黑 如今相当多的程序员都是互联网程序员,按说,应该对互联网的基础协议相当清楚。可惜至少就我的面试经验来看,许多人这方面缺课太多,简单说说TCP/IP协议分层就已经难倒了不

大流程看起来就是这样,也不难理解。不过仔细想想,还是有不少问题得考虑的。比如状态问题,既然TCP是网络通讯,会发生延迟,那么在“信息已经发送,但还没有收到确认”的时候,应当是有个明确状态的,否则会发生状态的错乱。实际上TCP也确实做到了这点,它背后有一台完整的状态机,确保每时每刻,每个动作发生之后,状态都完全可控,一切尽在掌握,不会出现任何“孤点”和“断头路”。

TCP没那么难吧?这篇一定要看

上图是TCP的状态转移图的局部,覆盖了建立链接的状态,感兴趣的读者可以按照自己实地走走看(说个题外话,“自己模拟在图上走走”看起来土,其实高科技领域也挺常用。设计波音737的时候,开始大家都不知道发动机怎么摆比较好,设计师乔·萨特就在纸上画出机身和发动机的模型,把发动机模型剪下来在飞机各处摆放,最终发现吊在翼下最合适)。

我在之前关于软件设计的文章里几次提到状态图、状态转移函数,无论是用户生命周期、订单流转过程,都可以用这个工具来解决。遗憾的是,我发现还有许多设计人员不懂得或者不习惯用使用它,实在很可惜。

回到TCP建立连接的过程,我们还要注意ISN。在建立连接时必须先确定ISN,通过它把客户端和服务器的计数对齐。通常的教材上说,ISN是随机生成的,这样就保证了唯一性。 随机的目的是保持唯一,但千万不要以为“随机就不会重复”,简单的“取随机数”是很容易碰撞的。所以传统的“随机”方案是维护一个时钟和一个32位的计数器,时钟每过4毫秒,计数器自增1。因为2^32毫秒就是差不多4个半小时(MSL,Max Segment Lifetime),这基本超出了任何数据包在网络中的可能传输时间,所以可以认为这种ISN是独一无二的。

但这种方案也有风险,既然这样的ISN是连续的,那么中途的恶意程序可能能够预测ISN的生成规律,从而伪造ISN…… 总之ISN的生成是个有趣的设计问题,这里不展开了,有兴趣可以自己搜索资料阅读。

我在开发中遇到不少程序员,一旦需要避免重复,就想到“生成随机数”,根本不管随机数也可能碰撞。更有甚者,一旦遇到类似ISN的场合,就想当然把初始值设定为0,真是让人欲哭无泪(有没有想过ISN为什么不能设定为0呢,欢迎留言讨论)。

说完了建立连接的握手,我们再来看终止连接的挥手。通常大家都知道,TCP是“三次握手,四次挥手”(虽然我很不赞成“次”,但既然它已经约定俗成,这里还是延用通用的说法吧)。那么,为什么要四次才能挥手呢?

知道这个答案的人比能讲清楚“三次握手”的要多。通常的答案都是:TCP是双向通讯协议,要结束连接,双方都必须发送终止信号,告诉对方后续再没有数据发过来了,并等待对方确认,所以一共需要2+2=4次。

TCP没那么难吧?这篇一定要看

如果你之前看过建立连接的过程,大概会有这样的疑问:既然建立连接的时候可以节省一步,把服务端返回SYN和ACK合并到一起,那么结束连接的时候,是否也可以把服务端返回的SYN和FIN合并起来,节省一步呢?

想到了这个问题就值得恭喜,因为你不是只满足于“知其然”,而希望“知其所以然”。不过我们也需要想到,既然TCP连接的建立和终止都是同一批人定义的,既然他们能想到在建立连接时节省一步,那么他们没有理由在终止连接时不做节省。之所以没有“节省”,一定是有理由存在的。

没错,确实是有理由的,而且这个理由很好理解,因为建立和终止连接的场景是不一样的。在建立连接之前,客户端和服务器端都不会向对方发送任何数据,所以在服务端返回ACK的时候带上SYN,客户端当然知道这是从服务端收到的第一个数据包。

而在结束连接时,客户端向服务端发送FIN,表示“我这边不会继续发送数据过来了”,服务端响应ACK,这都没有问题。但此时,服务端之前向客户端发送数据的操作可能还没有完成,服务端仍然在向客户端传输数据。如果服务端把FIN和ACK合并起来,就会出现这样的情况:客户端的数据还没有接受完,忽然收到服务端的消息“后续没有数据了,终止连接”。显然,这种情况不应当出现,所以不能把ACK和FIN合并在一起,所以终止连接必须要四步。

最近和实习生聊天,说起开发中遇到的各种问题,以及对应的模型,大家听得入迷。事后有人问我:为什么我们工作中遇不到这么有意思的问题呢?我知道,这是个比较典型的问题。其实答案也很典型:因为你没有去深究问题背后的原型。懂得了背后的原型,就具备了“从已知推导无知”的本领,也具备了“从无知中发现已知”的眼光。

我和朋友聊开发有个共同的判断:TCP的握手和挥手看起来简单,但真让如今的开发人员去设计握手和挥手流程,估计有超过一半的人设计不出稳定、可靠、高效的握手和挥手流程。这样说来,许多业务系统里业务层面的通讯极不可靠,协议设计错漏百出,也是无奈的结果了。

补充一句。我曾在面试中遇到过这样的人,非名校毕业,已经有五年工作经验,除了对流行的框架和热点问题对答如流,对数据库理论、网络基础知识、数据结构和算法依然如数家珍。事实充分证明,不是所有人工作之后就把大学的知识丢个精光的,事实也证明,这样的候选人确实能担大任。

【编辑推荐】

  1. HTTPS那些协议:TLS, SSL, SNI, ALPN, NPN
  2. 以女朋友为例讲解 TCP/IP 三次握手与四次挥手
  3. 一个HTTPS问题的排查,谁的锅?
  4. 6张动态图轻松学习TCP三次握手和四次挥手
  5. HTTPS 不方便的地方!你知道多少?
【责任编辑:未丽燕 TEL:(010)68476606】
点赞 0

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读