TCP 的办公室

新人拜访

“您好,我是 TCP服务的实习生,刚培训完,请问您就是 TCP老司机吗?”

正坐在办公室悠闲喝着咖啡的我,差点一口喷出来,“哦哦,行,你终于来啦,看来几天前的资源申请通过了啊,老司机?”

“浏览器老大这么叫你的,说你厉害,靠谱的很。”

“好吧,既然来了,赶紧准备准备!这你的工作台。” 我放下手中的咖啡,走到了一个靠窗的工作台,指了指。

“好嘞。” 说着,刚来的小伙子走了过来。

工作台

“好多工具啊,这个通道是什么,这儿还有个钟?都怎么用呀?” 小伙子满脸好奇的问道。

“这样吧,从左到右,我一一给你说说。”

“首先,最左边呢,是个通道,这里会蹦出应用层需要我们发送的数据。最常见的就是 HTTP那小子的报文了。”

“了解,我们的工作就是发送应用层的数据。原来不需要我们自己去拿啊!”

“旁边呢就是扫描机,你需要根据实际情况把数据进行扫描,扫描机会把数据分块,按序号,放在旁边这个盒子里。”

“嗯嗯,这个我清楚,数据块大小需要根据实时的网络情况确定。”

“不错。这小伙子脑子还挺灵光。看来培训的不错” 我心中暗暗赞到。

“再往右,你看到这又是一个通道,这个通道就是我们和服务器进行沟通的通道了。通道旁是两个计数器,分别用来记录我们的序号和服务器序号,这个会自动加,你不用操作。就叫 1号计数器和 2号计数器吧,等下会用到。”

“好的,1号计数器其实就是报文中的序号?”

“嗯嗯,不错,用的时候看一眼就行,在计数器旁边有几个按钮,我给你说说。这里最好记一下。”

“嗯嗯” 说着小伙子拿出了笔记本开始记录。

任务降临

我指了指标着 SYN的按钮,说道:“这个是请求连接按钮,也就是通知服务器,我们想发数据给他。”

说着,最左侧的通道突然一闪,蹦出了一个 HTTP服务打包好的包裹,刚来的小兄弟显的有点慌乱,咽了一口气。

“刚好,那我就那这给给你做一下演示吧。” 说着,我站到了工作台正中。

“嗯。” 小兄弟紧张的说不出话来。

“首先呢,按一下 SYN按钮,请求发送数据。” 1号计数器跳了一下,由原本的 0跳到了 1。“按下这个按钮工作台会发送一个请求连接报文,相信报文的内容你应该清楚吧?” 我问道。

SYN1,序号为 0。” 看了一眼 1号计数器,小伙子自信的答道。

“嗯,不错!” 不一会计数器旁的通道蹦出了一段报文,2号计数器直接由 0跳到了 11

“让我们来看看,都有什么,你看这里。” 我指了指报文中的 ACK,小伙子也靠了过来。

ACK等于 1,说明服务器接受了我们的连接请求,对吧?” 小伙子说道。

“是的,那我们建立连接?” 我露出了狡猾的笑容。

“还需要核对 确认序号吧?” 小伙子有点困惑。

“为什么?” 我反问道。

“确保连接的准确性。老师说过,网络是一个复杂的环境,会出现报文滞留的情况,因此 TCP连接两端规定,在得到请求连接时,需要将 确认序号置为请求序号加 1。那么现在我们应该还要核对 确认序号1号计数器的值!” 小伙子转眼看向 1号计数器,“咦,怎么一样?应该是差 1的啊?”

“你忘了,在你按下 SYN按钮时,1号计数器已经跳了一下吗?”

“哦 ~” 小伙子恍然大悟,“那是应该相等,这个也太好用了吧!得记一下!”

“唰唰唰” 一旁发出铅笔摩擦纸面的声响,“有我刚来的样子” 我不经感叹道。

“接着,你看 SYN字段为 1,说明服务器请求连接,TCP是一个稳定的连接,双向数据的通道,需要双方都确认连接状态,这点我不需要特殊说明吧?”

“嗯嗯,在学校老师说过。”

“那好,为了确保连接的正确性,我们需要和服务器做相同的操作,把序号加 1后,放在确认序号内,服务器返回的序号是 10我们返回 11就行。但这些不需要你进行实际的报文生成,在你确定可以建立连接的情况下,按一下标着 ACK按钮就行。” 说着我按下了 ACK按钮。“现在三次握手结束,连接通道成功生成。我们开始传输数据,剩下还有几个按钮用到的时候在说。”

“那个,我想问一下,我知道 TCP是个双向数据通道,但如果我们不确认建立连接,直接发送数据应该也没问题吧?我们和服务器都已经发送了一次请求,并且都收到了,为什么还要确认一下呢?” 小伙子若有所思道。

“既然是双向数据通道,那么通道的两端都应该清楚自己和对方的发送和接收的能力,对吧?”

“当然!不然通道是不稳定的。”

“那你想想,在前两次通信过程中,双方都知道了哪些情况?”

“第一次我们发报文,第二次服务器返回报文我们接收到,那我们就知道了我们有能力发送和接收,服务器也有能力接收和发送。”

“那服务器呢?”

“服务器的话,应该知道了他自己有能力接收,知道我们有能力发送,他自己却不清楚他能不能发送,也不知道我们是否能接收!因为我们还没回复他。”

“因此呢,三次通信(握手)让双方都知道了双方都有发送与接收的能力,这对于一个双向数据通道来说至关重要。” 我解释道。

“嗯嗯,我记一下。” 又是一阵 “唰唰唰” 的声音。

发送报文

“已经建立了通道,那接下来就简单了。” 我拿起 HTTP扔过来的数据,说道:“我们看看我们一次能发送的数据包大小,在这儿。” 我指了指工作台最右侧的屏幕,屏幕上显示着一连串的信息,“这些就是系统参数,这个就是我们网络所能承受的最大发送量。”

“嗯,一次可以发送 1100字节。” 小伙子边看边说道。

“嗯,不错。那我们就将数据按 1000来切割吧,剩一定空间个报文头部使用。” 说着我启动一遍的扫描机,设定为 1000,丢进 HTTP的数据,一旁的盒子出现排好序的数据块。

“好神奇啊,学校里都我们自己切的。” 小伙子双眼中冒着金光。

“接下来发生报文就好了。”

“好的,我来拼接数据,源端口:5800,目标端口:80,序号:1,数据偏移:20,标志位:无特殊情况,窗口大小:3,校验和:...” 小伙子突然叽里咕噜一堆,吓了我一跳。

“不需要这么麻烦,源端口,目标端口,在工作台接收到应用层数据后,就能生成,至于序号和偏移量,你也不用关心啦,我来演示一遍,看好。”

我瞧了一眼服务器先前返回的报文,得知窗口为 3,拿起盒子里的数据就往按钮旁的通道里丢,一连丢了 3个。1号计数器也连续跳了 3下,由 1跳到了 1001,在由 1001跳到了 2001,最终定格在 3001

“好了,接下来就等服务器响应了。”

“这就好了?” 小伙子明显有点不敢相信。

“对啊,好了!等服务器确认就行。” 我有点得意。“工作台会帮我们把数据打包生成报文,这个工作台可是我的专利!”

“哇塞,老司机就是厉害!比学校里高级多了。” 小伙子双眼中再次亮起金光。

单向关闭

没过多久,2号计数器连跳 3次,哒哒哒,通道里蹦出 3个服务器返回的报文,内容都为:请求完成,需要下一份数据。

我拿起盒子里的下 3块,往通道里扔。1号计数器哒哒哒,又连着跳了 3次。如此循环往复了十几次,数据终于发完。

“今天的网不错诶,没有重发的情况出现。现在我们发完了,只需要等待服务器发送数据就行了。”

大概过了 10ms,通道内陆陆续续开始蹦出报文,我刚想上手,一旁小伙子一把把报文揽走,“这个我熟,我来吧!”

获取报文数据,按照序号排好,一顿操作还挺溜。

哒哒哒,2号计数器不断的跳动,定格在 50001上。

“好现在数据也接收完毕了,需要进行单向关闭。如何进行关闭?” 我想考考小伙子的能力。

“发送报文,将 FIN置为 1,序号为 43001。” 小伙子瞧了一眼 1号计数器说道:“然后等服务器返回确认就好了,哦,对为了应付网络滞留情况出现,需要核对 确认序号。”

“不错,但在这...” 我话还没说完,小伙子兴奋的说道:“是不是按那个 FIN按钮就好了?”

“嗯,对!我们只需要核对 确认序号就好了。你来操作吧 ~” 看着一脸兴奋的小伙子,我停止了手中的操作。

“好的。” 说着,小伙子按下了 FIN按钮。1号计数器跳了一下,定格在 43002。不一会通道里蹦出了报文,确认序号与 1好计数器一致,都为 43002

“现在单向关闭成功,等待服务器请求关闭。” 小伙子一副训练有素的样子。

“嗯,不错,接下来就等待服务器最终确定关闭了。” 我拿起一旁的咖啡,慢悠悠的说道:“那你知道为什么这是单向关闭?”

“因为只有我们这边确认把数据都已经发送完毕啦 ~ 没准服务器还有数据给我们呢 ~ ”

“嗯,不错。” 我拿起咖啡喝了一口,不经感慨道:“后继有人了啊!”

“老大,服务器发出关闭请求了,你看。” 小伙子拿起一个报文,对我说道。

“我想你应该知道怎么做了吧?”

“嗯嗯,按 ACK按钮就好了,这个和开启连接确认是同一个操作,按您的智慧,应该是这样。” 说着按下了 ACK按钮。

“嗯,这个彩虹屁真香,哦不,你真聪明!”

“哈哈” 我们同时发出笑声,“我和你说,那个 HTTP服务部可不咋的,经常砸我,这不数据都好了,砸 TM的。”

duang~” 通道一头发出一阵巨响,“TCP你们没完了是不?”

原文链接:segmentfault.com

上一篇:深入源码学习Vue响应式原理
下一篇:面试完然后?为什么就没然后了?提升成功率

相关推荐

  • 要强的 TCP

    圆桌会议 “又到了一月一次的总结大会,大家说说最近工作上出现的问题吧。” 浏览器老大坐在圆桌最前端,说道:“好意见赶紧提,吐槽也可以说。” “我!我!我!” TCP 喊道。 “嗯,你说。

    5 个月前
  • 使用JavaScript从浏览器连接到TCP套接字

    使用JavaScript从浏览器连接到TCP套接字...

    2 年前
  • 传输层的TCP和UDP协议

    图片描述(https://img.javascriptcn.com/b9dbfbd080317fa081e6a0002770106c "图片描述") 作者:HerryLo(https://githu...

    10 个月前
  • 从办公室的勾心斗角看JS隐式类型转换

    (/public/upload/7b27490ef9f71461696d2b477811abef) 背景 有天上班,隔壁同事老黄在chrome控制台下输入了console.log(a == 1...

    1 个月前
  • 三次握手、四次挥手以及TCP标志位的详细介绍

    一、TCP标志位 在讲TCP三次握手和四次挥手之前,先说一下TCP标志位,方便后续的理解。 简单来说,TCP标志位的值代表了当前请求的目的。 标志位一共有6种,分别是: 1. SYN(sy...

    6 个月前
  • vue-player或TcPlayer在微信内自动播放video和audio

    不管是IOS和Android,当video和audio初始src为空,根据点击不同的媒体源(非播放器控件),比如多个章节的视频列表,动态给src赋值并执行play()方法时,大多数的机器并不会执行自动...

    2 年前
  • tcp协议为什么是三次握手而不是两次握手?

    我们都知道tcp协议需要三次握手,那为什么不是两次握手呢,关于这个疑问我查了很多资料,看到很多的解释,现归纳总结如下,方便我们理解记忆 如果是两次握手,我们一起来看看下面两种场景 1.造成资源浪费...

    1 年前
  • tcp-proxy.js

    simple tcp proxy tcpproxy.js A TCP Proxy package for NodeJS NPM versionnpmimagenpmurl Build Stat...

    1 年前
  • tcp-proxy

    A simple TCP proxy using node.js based on the work of nodehttpproxy tcpproxy Exactly what you wou...

    1 年前
  • tcp-port-used

    A simple Node.js module to check if a TCP port is already bound. tcpportused ============= A simpl...

    1 年前

官方社区

扫码加入 JavaScript 社区