计算机网络 理解流量控制与SACK机制

news/2024/5/18 15:29:13 标签: tcp/ip, udp, http
http://www.w3.org/2000/svg" style="display: none;">

文章目录

  • 从Telnet协议理解TCP的全双工
    • 理解TCP的双工
    • 理解TCP的全双工
  • 流量控制
    • 解释
    • 示意图
    • 接收方的实现
    • 发送方的实现
    • 三次握手时的窗口信息
    • Window size scaling factor
  • SACK
    • 示意图
    • 三次握手时确认SACK能力
    • Options的构成
      • 列举可能的Options
      • 利用No-Operation来填充其他Options
    • wireshark抓包到的SACK
    • 实例分析
    • 总结

从Telnet协议理解TCP的全双工

理解TCP的双工

TCP是一个双工协议,因为它连接的两端都可以向对方输出数据。
https://img-blog.csdnimg.cn/d47cc87d3cc448bea8bd762cbfdd0e4b.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
单独拿出上图的红框标记,我们就可以单独将 主机A当作发送方,主机B当作接收方。
https://img-blog.csdnimg.cn/753464f595c842ada8a153c47c03a314.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
单独拿出上图的红框标记,我们就可以单独将 主机B当作发送方,主机A当作接收方。

理解TCP的全双工

上一节的内容,我们可以得知最起码TCP是一种半双工的协议。
https://img-blog.csdnimg.cn/de774081fbfa434781fedc935f6b8b45.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
但实际上TCP也是支持上图这样,双方同时向对方发送数据的。所以TCP是全双工的协议。

流量控制

解释

按照上一章的思路,我们固定住一个发送方向,把两个主机分别当作 发送方、接收方。

每一条TCP连接中,接收方会为连接设置一个接收缓存。当接收方收到了正确的、按序的字节后,它就将数据放入接收缓存中。相关联的应用进程会从该缓存中读取数据,但不一定数据刚一到达就马上被读取。事实上,接收方的应用进程也许正忙于其他任务,甚至要过很长的时间后才去读取数据。

如果应用进程读取数据时相对缓慢,而发送方发送得太多、太快,发送的数据就会很容易地使得接收缓存溢出。所以TCP为它的应用进程提供了流量控制服务(flow-control service)以消除接收缓存溢出的可能性。

流量控制实际上是一个速度匹配服务,即发送方的发送速率与接收方应用程序的读取速率相匹配。

示意图

再按照上一章的思路,我们固定住一个发送方向,把两个主机分别当作 发送方、接收方。假设主机A正在向主机B发送一个大文件。
https://img-blog.csdnimg.cn/48b340144c4e4c91a4e517e7a0f68004.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
那在TCP报文段携带的数据上我们只需要关心上面的这些东西就可以了:

发送方:

  • 发送方的Sequence Number
  • 发送方的Payload

接收方:

  • 接收方的Acknowledgment Number
  • 接收方的Window

接收方的实现

既然整个流量控制服务都是为了将就接收方的接收缓存,那就从接收方接收缓存开始讲起:

现主机B为该TCP连接分配了一个接受缓存,大小为 R c v B u f f e r RcvBuffer RcvBuffer。主机B上的应用程序不时从该缓存中读取数据,那么有以下变量:

  • L a s t B y t e R e a d LastByteRead LastByteRead:主机B上的应用程序已从缓存中读取的数据的最后一个字节的编号。
  • L a s t B y t e R c v d LastByteRcvd LastByteRcvd:主机B从下层网络里接收到的数据中的最后一个字节的编号。

一个字节要首先从下层网络中接收到,才可能被上层应用读取到,所以肯定有:
L a s t B y t e R e a d ≤ L a s t B y t e R c v d LastByteRead \leq LastByteRcvd LastByteReadLastByteRcvd

L a s t B y t e R e a d LastByteRead LastByteRead L a s t B y t e R c v d LastByteRcvd LastByteRcvd之间的数据就是 应用程序还没来得及读取的数据,这些数据自然会被缓存起来。由于TCP不允许以分配的缓存溢出,所以肯定有:

L a s t B y t e R c v d − L a s t B y t e R e a d ≤ R c v B u f f e r LastByteRcvd - LastByteRead \leq RcvBuffer LastByteRcvdLastByteReadRcvBuffer

总的缓存大小再减去 还没来得及读取的数据大小,就是接收方可以接受的数据量大小,也就是接收窗口。接收窗口用 r w n d rwnd rwnd表示,根据接收缓存可用空间的大小来设置:
r w n d = R c v B u f f e r − ( L a s t B y t e R c v d − L a s t B y t e R e a d ) rwnd = RcvBuffer - (LastByteRcvd - LastByteRead) rwnd=RcvBuffer(LastByteRcvdLastByteRead)

根据每次接收的数据的多少,和上层应用的读取数据的多少,这个可用空间也在随之变化,所以 r w n d rwnd rwnd是动态变化的。当然也需要接收方每次接收到数据后,把 r w n d rwnd rwnd的值告知给发送方。 r w n d rwnd rwnd也就是上图中的window = 100了。
https://img-blog.csdnimg.cn/179072af62d843e6aeae50af392c4f3e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
接收方的示意图如上。

发送方的实现

我们知道整个流量控制都是在将就接收方的接收缓存,所以每次发送方从接收方那里收到ACK = ywindow = 100时,都会根据这两个参数来调整自己的提供窗口。
https://img-blog.csdnimg.cn/0a694271012c402fbf529196f8de77e4.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

如上图,现假设某一时刻下:

  • 发送方的提供窗口长度为N,发送方刚发送了14-20,和21-23的两个数据包。
  • 21-23这个数据包丢失了。
  • 接收方只收到了14-20,刚反馈了信息ACK = 21window = 5。(因为接收方已经收到了序号20,所以期待的是21;将rwnd的值传给window)

此时,发送方的窗口内的序号已经都被使用了,不能再发送数据了,除非接收方反馈ACK和window的信息给发送方,让发送方窗口滑动。

https://img-blog.csdnimg.cn/9f0685b5bd484d06b9767d4fc93ee503.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

如上图,当发送方收到ACK = 21window = 5后,它立即对自己的窗口进行调整:

  • 根据ACK = 21将窗口的左边界设定为ACK的值,因为从ACK开始后的这些序号都是没有被确认过的。即窗口左边界右移。
  • 根据window = 5,重新设定5为窗口的新长度。即窗口可能会伸或缩。

综上我们可以看出,流量控制总是在让发送方来同步接收方的窗口信息。同步后,双方的窗口会处于同一个位置。
https://img-blog.csdnimg.cn/4dc5b7fce7204864bf0413ce0312922f.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
如上图,体现了发送方同步了窗口后的状态(只保留了一些重要信息),此时,窗口是完全一致的,但发送方窗口里可能会有 已发送、待确认 的数据(21-23)。

  • 这些数据如果丢失了没有到达接收方,那么之后发送方会重新发送这些数据。
  • 这些数据如果顺利到达接收方但接收方的ACK却丢失了,那么接收方窗口向前移动,之后发送方也会重新发送这些数据。
  • 这些数据如果顺利到达接收方且接收方的ACK也顺利到达了,那么接收方窗口先向前移动,之后发送方窗口也向前移动。

三次握手时的窗口信息

https://img-blog.csdnimg.cn/7651e35347714d0393cd393fb62cfb0b.png" alt="在这里插入图片描述" />
这个本机与百度之间的三次握手。192.168.0.103为本机ip,39.156.66.14为百度ip。
https://img-blog.csdnimg.cn/09d255e7f8fd4c79b3aa18e1668d87cf.png" alt="在这里插入图片描述" />
首先将本机当作发送方,百度当作接收方。从Ack = 1Win = 8192可以得知,初始时,百度作为接收方的接收窗口从序号1开始,长度为8192。
https://img-blog.csdnimg.cn/3b30098173f042198d1582639a9b6d90.png" alt="在这里插入图片描述" />
然后将百度当作发送方,本机当作接收方。从Ack = 1Win = 131072可以得知,初始时,本机作为接收方的接收窗口从序号1开始,长度为131072。

Window size scaling factor

本节将百度当作发送方,本机当作接收方。
https://img-blog.csdnimg.cn/84d7f705b9404a5db7a4c08daa5cf459.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

如上图,在第三次握手时,本机给出了window = 131072,这是通过512 * 256算出来的。即:
C a l c u l a t e d _ w i n d o w _ s i z e = W i n d o w ∗ W i n d o w _ s i z e _ s c a l i n g _ f a c t o r Calculated\_window\_size = Window * Window\_size\_scaling\_factor Calculated_window_size=WindowWindow_size_scaling_factor
但实际上你在这个包里面找不到Window size scaling factor。

其实这个Window size scaling factor在本机的第一次握手给出了:
https://img-blog.csdnimg.cn/36352fcd803846b8922f444f38f3ceba.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
如上图,在Options中设置了Window scale为8,也就是2的8次方。另外,第一次握手时,虽然也给了Window的值,但实际不会使用它,因为肯定要以最新的第三次握手的值为准。在第一次握手的简述中(上图第一行里面),也没有出现Win = xxx的描述。

可以这么理解,Window size scaling factor和ACK、window一样,都是接收方给发送方以同步窗口的信息,只是这个Window size scaling factor如果没有改变的话,那么就只需要发送一次就行了,发送方自己会负责记住这个Window size scaling factor的。

SACK

我们知道Acknowledgment Number是累积确认的含义,如果有Acknowledgment Number = x,那么(... , x-1]这个区间内的数据都已经被接收方接收到了。根据SR协议我们知道TCP也可以支持选择确认,即接收方允许数据失序到达。

总之,SACK信息不是单独存在的。接收方反馈SACK信息时,既会反馈ACK信息(累积确认),也会反馈SACK信息(选择确认)。

示意图

https://img-blog.csdnimg.cn/b30c58150d8940aa814c94c03bb03c17.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
如上图,现假设某一时刻下:

  • 发送方的提供窗口长度为N,发送方刚发送了14-20、21、22-23的三个数据包。
  • 21这个数据包丢失了。
  • 接收方只收到了14-20和22-23,刚反馈了信息ACK = 21SACK = [22-23]window = 5。(因为接收方在连续已收到的分组上的最大序号是20,所以期待的是21;将rwnd的值传给window)

https://img-blog.csdnimg.cn/eaa03daac8df4f6f8584a4fe1a8d5369.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

如上图,因为SACK的存在:

  • 在发送方的窗口里,可能存在 已发送、已确认 的分组。
  • 在接收方的窗口里,可能存在 已接收、未被读取 的分组。

三次握手时确认SACK能力

https://img-blog.csdnimg.cn/7651e35347714d0393cd393fb62cfb0b.png" alt="在这里插入图片描述" />
这个本机与百度之间的三次握手。192.168.0.103为本机ip,39.156.66.14为百度ip。
https://img-blog.csdnimg.cn/a51134243b114726b69db0b0b9290642.png" alt="在这里插入图片描述" />
在第一次握手和第二次握手时,本机和百度都分别表示自己有SACK的能力。

Options的构成

因为SACK permitted和SACK都是属于TCP header里的Options,所以这里还是讲一下Options的构成。
https://img-blog.csdnimg.cn/20ec2bf51aa4460ebcc14342e7df88ef.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

  • 如上图为TCP的header的构成,每排是32bit,4byte。
  • 前5排是固定的,所以TCP的header至少会占20byte。
  • OptionsPadding那一排不是固定的。OptionsPadding加起来最多可以占40byte。
    • Padding是填充的意思。每排都是4byte的,如果Options的哪排没有填满4byte数据,那么就填充0(只可能在整个选项的最后面填充)。
  • 综上,TCP的header最多可以60byte。

列举可能的Options

https://img-blog.csdnimg.cn/95d9ce917f6d42229bee1a29e00647b4.png" alt="在这里插入图片描述" />
如上图,Options只可能是上图两种形式。

https://img-blog.csdnimg.cn/718ff828b5ad4f4987800424186f9a1e.png" alt="在这里插入图片描述" />
No-Operation这种Option,总共1字节,只带Kind,即Kind=1代表为No-Operation。
https://img-blog.csdnimg.cn/3b98199e125c478888d85778d08d43f6.png" alt="在这里插入图片描述" />
Maximum segment size这种Option,总共4字节,带有Kind、Length和Data,即Kind=2代表为Maximum segment size。注意Length总是处于第二个字节,Length的值又为4,那么Data部分只可能是剩余的那两个字节,即图上的05 b4
https://img-blog.csdnimg.cn/15eac27b28ba40eca1106f0d3dd3c823.png" alt="在这里插入图片描述" />
SACK permitted这种Option,总共2字节,只带有Kind、Length,因为Length的值为2,而Length又处于第二个字节,所以这个option到Length为止。
https://img-blog.csdnimg.cn/e50ac50fc1674e99a24e8acca8867ecc.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
SACK这种Option,总共10字节,带有Kind、Length和Data。Data有8字节,包括左边界和右边界,各占4字节(这很自然,因为Sequence Number和Acknowledgment Number也都是占的4字节,既然都是4字节,所以他们的范围才能是一样的)。

利用No-Operation来填充其他Options

由于每一排占的是4字节,但有的选项是不足4字节的,那么那一排的前面部分就要由No-Operation来填充。No-Operation相当于是一种特殊的Options,可以用来填充。
https://img-blog.csdnimg.cn/0bbe13a105ed43a5b6fca8bfbf15499a.png" alt="在这里插入图片描述" />
如上图,是一个TCP的header的选项们。
https://img-blog.csdnimg.cn/8c1be8ddf5f543bdb043ae0fe1c5b3a8.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

Maximum segment size由于刚好是4字节,那么不需要No-Operation来填充。

https://img-blog.csdnimg.cn/2a0c9c2effa844f4a9a1a65dad48986e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
Window scale由于是3字节,所以前面需要1个No-Operation来填充。
https://img-blog.csdnimg.cn/01c739a0c4b246ad98642f9fdc0d1bc4.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
SACK permitted由于是2字节,所以前面需要2个No-Operation来填充。

wireshark抓包到的SACK

https://img-blog.csdnimg.cn/971305ef3c084d73ab7bfe58b5e045ff.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

  • Acknowledgment Number为21314,这意味着(... , 21313]区间已经都被接收到了。
  • 一个SACK块为[28614, 34454],这意味着[28614, 34454]区间也被接收到了。注意,这个区间是超过了21314的。

https://img-blog.csdnimg.cn/d42f02a8223d45ce94cfc976ff007bb5.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

  • Acknowledgment Number为20101,这意味着(... , 20100]区间已经都被接收到了。
  • 一个SACK块为[18761, 20101],但这个块是小于等于20101的,这种SACK信息被称为DSACK。这好像不符合SACK的本意,但DSACK的作用是方便发送方判断何时的重传是没有必要的,比如发送方可以推断是否发生了包失序、ACK丢失、包重复或伪重传。
    • 发送方过早判定超时,被称为伪超时。而伪超时就会造成伪重传。

实例分析

https://img-blog.csdnimg.cn/3612e1633a3342e9b49435e636b4bb26.png" alt="在这里插入图片描述" />
这个本机与百度之间的通信。192.168.0.103为本机ip,39.156.66.14为百度ip。为了方便查看方向,我们记住7715为本机应用端口,443为百度应用端口。
https://img-blog.csdnimg.cn/92a29495f4b9419bb68f4faf61386bd5.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />

第一条数据,本机告诉百度,本机作为接收方,已经接收的区间为(... , 32660)
https://img-blog.csdnimg.cn/7e3c06cc2dca4f709a3bdad7a2f146c5.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
第二条数据,百度作为发送方发数据给本机。但本机期待的是32660及以后的数据包,这次百度发来的数据却是[34072, 34072 + 1412),属于是失序到达,wireshark认为(... , 32660)[34072, 34072 + 1412)中间的那个segment还没有收到,所以显示TCP Previous segment not captured。
https://img-blog.csdnimg.cn/5f99e09afa474680afce8557f216a7cc.png" alt="在这里插入图片描述" />
在第四条数据中:

  • 本机根据第二条数据反馈了ACK。因为从第二条数据中,我们收到了[34072, 34072 + 1412),所以带有了SACK块为SLE=34072 SRE=35484
  • 因为这条数据的Ack=32660和第一条数据一样,所以显示TCP Dup ACK 266#1,266为第一条数据的标号。

https://img-blog.csdnimg.cn/29c8c76bf14b4191ac4678372831b48e.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
第三条数据,也是百度作为发送方发数据给本机。但由于相对于第二条数据来说,第三条数据的顺序乱了,所以显示TCP Out-Of-Order。这条数据百度发送了[32660, 32660 + 1412)区间的数据给本机。
https://img-blog.csdnimg.cn/0c2a25c06e4e449b8c198296de9f48e1.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FubGlhbjUyMw==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述" />
第五条数据,本机根据第二、三条数据反馈了ACK。

  • 第二条数据中,百度发送了[34072, 34072 + 1412)[34072, 35484)
  • 第三条数据中,百度发送了[32660, 32660 + 1412)[32660, 34072)
  • 这两个区间合起来就是[32660, 35484)
  • 之前本机的接收窗口的左边界就是32660(即ACK = 32660),现在遇到了[32660, 35484),那么接收窗口就会右移了,移动到35484。

总结

SACK总的来说只是一种锦上添花的东西。一个ACK包,里面必须存在一个Ack序号,这个Ack序号起到了累积确认的效果。而SACK则是一种可能存在的东西,它在累积确认的范围之外,增加了选择确认的效果。


http://www.niftyadmin.cn/n/768157.html

相关文章

计算机网络 理解拥塞控制

文章目录前言如何检测拥塞拥塞控制方法分类通过窗口减缓TCP发送拥塞控制算法理论基础状态迁移图慢启动拥塞避免快速恢复总结前言 TCP的流量控制服务完成了对发送方发送速率的调节——当TCP通信的接收方的接收速率无法匹配发送速率时,发送方会降低发送速率。但流量控…

新版VSCode 1.60.0版 解决“无法将XXXX项识别为 cmdlet、函数、脚本文件或可运行程序的名称”的问题

环境 windows10系统,所以下面的那条配置"terminal.integrated.shell.windows"的后面是windows。 问题 前几天VSCode自动更新了,然后插件Task Explorer里面的任务就无法执行了。看了一下,发现了原因: 以前我在user配置…

Ubuntu16 通过gdebi安装搜狗输入法

环境 Ubuntu16.04 LTS已安装好了gdebi去搜狗输入法官网下载了搜狗输入法的deb包(我的是sogoupinyin_2.4.0.3469_amd64.deb) 输入法系统选择 需要选择为fcitx,一般默认就是这个了。 安装过程 右键单击搜狗输入法deb包,使用gdeb…

Visual Studio 2019 常用快捷键

注释 注释:选定区域,ctrl K,然后再ctrl C。 解注释:选定区域,ctrl K,然后再ctrl U。 多行编辑 Multi-caret selection caret就是指 那个一闪一闪的光标。 selection就是指 框住的一个单词。 CtrlA…

浅析——为什么UTF-16需要大端小端,而UTF-8不需要

文章目录为什么UTF-16需要大端小端什么是大端和小端内存中文件中大端形式小端形式为什么UTF-8不需要大端小端为什么UTF-16需要大端小端 我们使用编码网站查询“你”字的编码。 从上面的Unicode来看,我们知道,4F是数据位的高位,60是数据位的…

计算机网络 对Reno算法的优化——NewReno算法

Reno状态迁移图 实例分析Reno和NewReno 我们假设当前处于拥塞避免状态。如下图,[0-11]的这个窗口内的12个数据包从发送方发送。不过1、4数据包还没到达接收方就丢失了。一般情况下,发送方发送了seq0,len1的数据包后,接收方回复的ACK包为ack1…

TCP报文段的数据长度是如何计算得到的

TCP/IP结构分析 应用层把数据传给运输层,也就是给TCP协议。来自应用层的数据会被分割为MSS的大小,放到如下图的数据部分。 TCP报文段发送给网络层,也就是给IP协议。需要在TCP报文段的外面再套上IP协议的头部。如下图的数据部分&#xff0c…

计算机网络自顶向下.6e 第4章 网络层 知识点浅析

文章目录前言概述转发和路由选择网络服务模型虚电路和数据报网络虚电路网络数据报网络路由器工作原理输入端口交换结构输出端口何处出现排队路由选择控制平面网际协议(IP):因特网中的转发和编址数据报格式(datagram)IP…