tcp流量控制一个非常能学到知识的技术帖

Easter79
• 阅读 526

模拟测试程序,从客户端向服务器发数据,人工控制服务器收数据。当客户端发了一部分数据后,无法再发送,此时服务器开始每次收取1K。
按照常理推断,服务器收取1K后,客户端应该能够继续发送数据,但实测观察发现,客户端还是无法发送数据,直到服务器收取了一定数据量后,客户端才能够继续发送。  

tcp抓包如下:

[plain] view plain copy

 tcp流量控制一个非常能学到知识的技术帖 tcp流量控制一个非常能学到知识的技术帖

  1. 11:42:40.217984 IP localhost.6379 > localhost.28944: . ack 65665 win 0 <nop,nop,timestamp 1816613366 1816613366>  
  2. 0x0000: 4500 0034 5e08 4000 4006 deb9 7f00 0001 E..4^.@.@.......  
  3. 0x0010: 7f00 0001 18eb 7110 7c79 0efb 7c5f 2ff1 ......q.|y..|_/.  
  4. 0x0020: 8010 0000 3a7f 0000 0101 080a 6c47 51f6 ....:.......lGQ.  
  5. 0x0030: 6c47 51f6 lGQ.  
  6. 11:42:40.425034 IP localhost.28944 > localhost.6379: . ack 1 win 257 <nop,nop,timestamp 1816613573 1816613366>  
  7. 0x0000: 4500 0034 7f94 4000 4006 bd2d 7f00 0001 E..4..@.@..-....  
  8. 0x0010: 7f00 0001 7110 18eb 7c5f 2ff0 7c79 0efb ....q...|_/.|y..  
  9. 0x0020: 8010 0101 38b0 0000 0101 080a 6c47 52c5 ....8.......lGR.  
  10. 0x0030: 6c47 51f6 lGQ.  
  11. 11:42:40.425047 IP localhost.6379 > localhost.28944: . ack 65665 win 0 <nop,nop,timestamp 1816613573 1816613366>  
  12. 0x0000: 4500 0034 5e09 4000 4006 deb8 7f00 0001 E..4^.@.@.......  
  13. 0x0010: 7f00 0001 18eb 7110 7c79 0efb 7c5f 2ff1 ......q.|y..|_/.  
  14. 0x0020: 8010 0000 39b0 0000 0101 080a 6c47 52c5 ....9.......lGR.  
  15. 0x0030: 6c47 51f6 lGQ.  
  16. 11:42:40.838967 IP localhost.28944 > localhost.6379: . ack 1 win 257 <nop,nop,timestamp 1816613987 1816613573>  
  17. 0x0000: 4500 0034 7f95 4000 4006 bd2c 7f00 0001 E..4..@.@..,....  
  18. 0x0010: 7f00 0001 7110 18eb 7c5f 2ff0 7c79 0efb ....q...|_/.|y..  
  19. 0x0020: 8010 0101 3643 0000 0101 080a 6c47 5463 ....6C......lGTc  
  20. 0x0030: 6c47 52c5 lGR.  
  21. 11:42:40.838983 IP localhost.6379 > localhost.28944: . ack 65665 win 0 <nop,nop,timestamp 1816613987 1816613366>  
  22. 0x0000: 4500 0034 5e0a 4000 4006 deb7 7f00 0001 E..4^.@.@.......  
  23. 0x0010: 7f00 0001 18eb 7110 7c79 0efb 7c5f 2ff1 ......q.|y..|_/.  
  24. 0x0020: 8010 0000 3812 0000 0101 080a 6c47 5463 ....8.......lGTc  
  25. 0x0030: 6c47 51f6 lGQ.  
  26. 11:42:41.666922 IP localhost.28944 > localhost.6379: . ack 1 win 257 <nop,nop,timestamp 1816614815 1816613987>  
  27. 0x0000: 4500 0034 7f96 4000 4006 bd2b 7f00 0001 E..4..@.@..+....  
  28. 0x0010: 7f00 0001 7110 18eb 7c5f 2ff0 7c79 0efb ....q...|_/.|y..  
  29. 0x0020: 8010 0101 3169 0000 0101 080a 6c47 579f ....1i......lGW.  
  30. 0x0030: 6c47 5463 lGTc  
  31. 11:42:41.666939 IP localhost.6379 > localhost.28944: . ack 65665 win 0 <nop,nop,timestamp 1816614815 1816613366>  
  32. 0x0000: 4500 0034 5e0b 4000 4006 deb6 7f00 0001 E..4^.@.@.......  
  33. 0x0010: 7f00 0001 18eb 7110 7c79 0efb 7c5f 2ff1 ......q.|y..|_/.  
  34. 0x0020: 8010 0000 34d6 0000 0101 080a 6c47 579f ....4.......lGW.  
  35. 0x0030: 6c47 51f6 lGQ.  
  36. 11:42:43.322908 IP localhost.28944 > localhost.6379: . ack 1 win 257 <nop,nop,timestamp 1816616471 1816614815>  
  37. 0x0000: 4500 0034 7f97 4000 4006 bd2a 7f00 0001 E..4..@.@..*....  
  38. 0x0010: 7f00 0001 7110 18eb 7c5f 2ff0 7c79 0efb ....q...|_/.|y..  
  39. 0x0020: 8010 0101 27b5 0000 0101 080a 6c47 5e17 ....'.......lG^.  
  40. 0x0030: 6c47 579f lGW.  
  41. 11:42:43.322921 IP localhost.6379 > localhost.28944: . ack 65665 win 0 <nop,nop,timestamp 1816616471 1816613366>  
  42. 0x0000: 4500 0034 5e0c 4000 4006 deb5 7f00 0001 E..4^.@.@.......  
  43. 0x0010: 7f00 0001 18eb 7110 7c79 0efb 7c5f 2ff1 ......q.|y..|_/.  
  44. 0x0020: 8010 0000 2e5e 0000 0101 080a 6c47 5e17 .....^......lG^.  
  45. 0x0030: 6c47 51f6 lGQ.  
  46. 11:42:46.634889 IP localhost.28944 > localhost.6379: . ack 1 win 257 <nop,nop,timestamp 1816619783 1816616471>  
  47. 0x0000: 4500 0034 7f98 4000 4006 bd29 7f00 0001 E..4..@.@..)....  
  48. 0x0010: 7f00 0001 7110 18eb 7c5f 2ff0 7c79 0efb ....q...|_/.|y..  
  49. 0x0020: 8010 0101 144d 0000 0101 080a 6c47 6b07 .....M......lGk.  
  50. 0x0030: 6c47 5e17 lG^.

  

可以看到服务器返回了大量的ack 65665 win 0的包。

经过查阅相关资料,发现这个问题现象和tcp流控有关,由于涉及内容太多,这里只总结关键点:
1)ack 65665 win 0中的win 0,是服务器告诉客户端:我的tcp滑窗已经满了,没有空间了,客户端收到这样的包后,停止发送数据;
2)为什么服务器收取了一部分数据后,tcp滑窗已经不是满了的状态,还继续返回ack 65665 win 0呢?
这是tcp的协议规定的,当滑窗满了后,为了避免再次很快被填满,只有当滑窗空间达到buffer size的一般或者MSS的大小时才告诉客户端可以继续发送了,即ack包中win不再为0。详见如下说明:

To avoid SWS, we simply make the rule that the receiver may not update its advertised receive window in such a way that this leaves too little usable window space on the part of the sender. In other words, we restrict the receiver from moving the right edge of the window by too small an amount. The usual minimum that the edge may be moved is either the value of theMSS parameter, or one-half the buffer size, whichever is less.

实测和代码验证确认,Linux应该是等于MSS。

这个问题的处理过程中涉及到了很多tcp协议的知识,例如:MSS,SWS(Slide window system),SWS(Silly window syndrome),tcp缓存,ack机制等,有兴趣的同学可以去查查。

完整的解释请参考如下链接:
http://www.tcpipguide.com/free/t_TCPWindowManagementIssues.htm

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
3年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo
Wesley13 Wesley13
3年前
34.TCP取样器
阅读文本大概需要3分钟。1、TCP取样器的作用   TCP取样器作用就是通过TCP/IP协议来连接服务器,然后发送数据和接收数据。2、TCP取样器详解!(https://oscimg.oschina.net/oscnet/32a9b19ba1db00f321d22a0f33bcfb68a0d.png)TCPClien
Stella981 Stella981
3年前
Linux应急响应(二):捕捉短连接
0x00前言​短连接(shortconnnection)是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。在系统维护中,一般很难去察觉,需要借助网络安全设备或者抓包分析,才能够去发现。0x01应急场景​
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k