专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

一文教会实战网络抓包和分析包

  话不多说,直接上图看内容
  显形不可见的网络包
  网络世界中的数据包交互我们肉眼是看不见的,它们就好像隐形了一样,我们对着课本学习计算机网络的时候就会觉得非常的抽象,加大了学习的难度。
  但莫慌,自从有了两大分析网络包的利器:tcpdump和Wireshark,我们看不见的数据包,再也没有那么神秘了。
  唉,当初大学学习计网的时候,要是能知道这两个工具,就不会学的一脸懵逼。
  tcpdump和Wireshark有什么区别?
  tcpdump和Wireshark就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。tcpdump仅支持命令行格式使用,常用在Linux服务器中抓取和分析网络包。Wireshark除了可以抓包外,还提供了可视化分析网络包的图形页面。
  所以,这两者实际上是搭配使用的,先用tcpdump命令在Linux服务器上抓包,接着把抓包的文件拖出到Windows电脑后,用Wireshark可视化分析。
  当然,如果你是在Windows上抓包,只需要用Wireshark工具就可以。
  tcpdump在Linux下如何抓包?
  tcpdump提供了大量的选项以及各式各样的过滤表达式,来帮助你抓取指定的数据包,不过不要担心,只需要掌握一些常用选项和过滤表达式,就可以满足大部分场景的需要了。
  假设我们要抓取下面的ping的数据包:
  要抓取上面的ping命令数据包,首先我们要知道ping的数据包是icmp协议,接着在使用tcpdump抓包的时候,就可以指定只抓icmp协议的数据包:
  那么当tcpdump抓取到icmp数据包后,输出格式如下:
  从tcpdump抓取的icmp数据包,我们很清楚的看到icmpecho的交互过程了,首先发送方发起了ICMPechorequest请求报文,接收方收到后回了一个ICMPechoreply响应报文,之后seq是递增的。
  我在这里也帮你整理了一些最常见的用法,并且绘制成了表格,你可以参考使用。
  首先,先来看看常用的选项类,在上面的ping例子中,我们用过i选项指定网口,用过nn选项不对IP地址和端口名称解析。其他常用的选项,如下表格:
  接下来,我们再来看看常用的过滤表用法,在上面的ping例子中,我们用过的是icmpandhost183。232。231。174,表示抓取icmp协议的数据包,以及源地址或目标地址为183。232。231。174的包。其他常用的过滤选项,我也整理成了下面这个表格。
  说了这么多,你应该也发现了,tcpdump虽然功能强大,但是输出的格式并不直观。
  所以,在工作中tcpdump只是用来抓取数据包,不用来分析数据包,而是把tcpdump抓取的数据包保存成pcap后缀的文件,接着用Wireshark工具进行数据包分析。
  Wireshark工具如何分析数据包?
  Wireshark除了可以抓包外,还提供了可视化分析网络包的图形页面,同时,还内置了一系列的汇总分析工具。
  比如,拿上面的ping例子来说,我们可以使用下面的命令,把抓取的数据包保存到ping。pcap文件
  接着把ping。pcap文件拖到电脑,再用Wireshark打开它。打开后,你就可以看到下面这个界面:
  是吧?在Wireshark的页面里,可以更加直观的分析数据包,不仅展示各个网络包的头部信息,还会用不同的颜色来区分不同的协议,由于这次抓包只有ICMP协议,所以只有紫色的条目。
  接着,在网络包列表中选择某一个网络包后,在其下面的网络包详情中,可以更清楚的看到,这个网络包在协议栈各层的详细信息。比如,以编号1的网络包为例子:
  可以在数据链路层,看到MAC包头信息,如源MAC地址和目标MAC地址等字段;可以在IP层,看到IP包头信息,如源IP地址和目标IP地址、TTL、IP包长度、协议等IP协议各个字段的数值和含义;可以在ICMP层,看到ICMP包头信息,比如Type、Code等ICMP协议各个字段的数值和含义;
  Wireshark用了分层的方式,展示了各个层的包头信息,把不可见的数据包,清清楚楚的展示了给我们,还有理由学不好计算机网络吗?是不是相见恨晚?
  从ping的例子中,我们可以看到网络分层就像有序的分工,每一层都有自己的责任范围和信息,上层协议完成工作后就交给下一层,最终形成一个完整的网络包。
  解密TCP三次握手和四次挥手
  既然学会了tcpdump和Wireshark两大网络分析利器,那我们快马加鞭,接下来用它俩抓取和分析HTTP协议网络包,并理解TCP三次握手和四次挥手的工作原理。
  本次例子,我们将要访问的http:192。168。3。200服务端。在终端一用tcpdump命令抓取数据包:
  接着,在终端二执行下面的curl命令:
  最后,回到终端一,按下CtrlC停止tcpdump,并把得到的http。pcap取出到电脑。
  使用Wireshark打开http。pcap后,你就可以在Wireshark中,看到如下的界面:
  我们都知道HTTP是基于TCP协议进行传输的,那么:最开始的3个包就是TCP三次握手建立连接的包中间是HTTP请求和响应的包而最后的3个包则是TCP断开连接的挥手包
  Wireshark可以用时序图的方式显示数据包交互的过程,从菜单栏中,点击统计(Statistics)流量图(FlowGraph),然后,在弹出的界面中的流量类型选择TCPFlows,你可以更清晰的看到,整个过程中TCP流的执行过程:
  你可能会好奇,为什么三次握手连接过程的Seq是0?
  实际上是因为Wireshark工具帮我们做了优化,它默认显示的是序列号seq是相对值,而不是真实值。
  如果你想看到实际的序列号的值,可以右键菜单,然后找到协议首选项,接着找到RelativeSeq后,把它给取消,操作如下:
  取消后,Seq显示的就是真实值了:
  可见,客户端和服务端的序列号实际上是不同的,序列号是一个随机值。
  这其实跟我们书上看到的TCP三次握手和四次挥手很类似,作为对比,你通常看到的TCP三次握手和四次挥手的流程,基本是这样的:
  为什么抓到的TCP挥手是三次,而不是书上说的四次?
  当被动关闭方(上图的服务端)在TCP挥手过程中,没有数据要发送并且开启了TCP延迟确认机制,那么第二和第三次挥手就会合并传输,这样就出现了三次挥手。
  而通常情况下,服务器端收到客户端的FIN后,很可能还没发送完数据,所以就会先回复客户端一个ACK包,稍等一会儿,完成所有数据包的发送后,才会发送FIN包,这也就是四次挥手了。
  TCP三次握手异常情况实战分析
  TCP三次握手的过程相信大家都背的滚瓜烂熟,那么你有没有想过这三个异常情况:TCP第一次握手的SYN丢包了,会发生了什么?TCP第二次握手的SYN、ACK丢包了,会发生什么?TCP第三次握手的ACK包丢了,会发生什么?
  有的小伙伴可能说:很简单呀,包丢了就会重传嘛。
  那我在继续问你:那会重传几次?超时重传的时间RTO会如何变化?在Linux下如何设置重传次数?。。。。
  是不是哑口无言,无法回答?
  不知道没关系,接下里我用三个实验案例,带大家一起探究探究这三种异常。
  实验场景
  本次实验用了两台虚拟机,一台作为服务端,一台作为客户端,它们的关系如下:
  客户端和服务端都是CentOs6。5Linux,Linux内核版本2。6。32服务端192。168。12。36,apacheweb服务客户端192。168。12。37
  实验一:TCP第一次握手SYN丢包
  为了模拟TCP第一次握手SYN丢包的情况,我是在拔掉服务器的网线后,立刻在客户端执行curl命令:
  其间tcpdump抓包的命令如下:
  过了一会,curl返回了超时连接的错误:
  从date返回的时间,可以发现在超时接近1分钟的时间后,curl返回了错误。
  接着,把tcpsystimeout。pcap文件用Wireshark打开分析,显示如下图:
  从上图可以发现,客户端发起了SYN包后,一直没有收到服务端的ACK,所以一直超时重传了5次,并且每次RTO超时时间是不同的:第一次是在1秒超时重传第二次是在3秒超时重传第三次是在7秒超时重传第四次是在15秒超时重传第五次是在31秒超时重传
  可以发现,每次超时时间RTO是指数(翻倍)上涨的,当超过最大重传次数后,客户端不再发送SYN包。
  在Linux中,第一次握手的SYN超时重传次数,是如下内核参数指定的:
  tcpsynretries默认值为5,也就是SYN最大重传次数是5次。
  接下来,我们继续做实验,把tcpsynretries设置为2次:echo2procsysnetipv4tcpsynretries
  重传抓包后,用Wireshark打开分析,显示如下图:
  实验一的实验小结
  通过实验一的实验结果,我们可以得知,当客户端发起的TCP第一次握手SYN包,在超时时间内没收到服务端的ACK,就会在超时重传SYN数据包,每次超时重传的RTO是翻倍上涨的,直到SYN包的重传次数到达tcpsynretries值后,客户端不再发送SYN包。
  实验二:TCP第二次握手SYN、ACK丢包
  为了模拟客户端收不到服务端第二次握手SYN、ACK包,我的做法是在客户端加上防火墙限制,直接粗暴的把来自服务端的数据都丢弃,防火墙的配置如下:
  接着,在客户端执行curl命令:
  从date返回的时间前后,可以算出大概1分钟后,curl报错退出了。
  客户端在这其间抓取的数据包,用Wireshark打开分析,显示的时序图如下:
  从图中可以发现:客户端发起SYN后,由于防火墙屏蔽了服务端的所有数据包,所以curl是无法收到服务端的SYN、ACK包,当发生超时后,就会重传SYN包服务端收到客户的SYN包后,就会回SYN、ACK包,但是客户端一直没有回ACK,服务端在超时后,重传了SYN、ACK包,接着一会,客户端超时重传的SYN包又抵达了服务端,服务端收到后,然后回了SYN、ACK包,但是SYN、ACK包的重传定时器并没有重置,还持续在重传,因为第二次握手在没收到第三次握手的ACK确认报文时,就会重传到最大次数。最后,客户端SYN超时重传次数达到了5次(tcpsynretries默认值5次),就不再继续发送SYN包了。
  所以,我们可以发现,当第二次握手的SYN、ACK丢包时,客户端会超时重发SYN包,服务端也会超时重传SYN、ACK包。
  咦?客户端设置了防火墙,屏蔽了服务端的网络包,为什么tcpdump还能抓到服务端的网络包?
  添加iptables限制后,tcpdump是否能抓到包,这要看添加的iptables限制条件:如果添加的是INPUT规则,则可以抓得到包如果添加的是OUTPUT规则,则抓不到包
  网络包进入主机后的顺序如下:进来的顺序WireNICtcpdumpnetfilteriptables出去的顺序iptablestcpdumpNICWire
  tcpsynretries是限制SYN重传次数,那第二次握手SYN、ACK限制最大重传次数是多少?
  TCP第二次握手SYN、ACK包的最大重传次数是通过tcpsynackretries内核参数限制的,其默认值如下:catprocsysnetipv4tcpsynackretries5
  是的,TCP第二次握手SYN、ACK包的最大重传次数默认值是5次。
  为了验证SYN、ACK包最大重传次数是5次,我们继续做下实验,我们先把客户端的tcpsynretries设置为1,表示客户端SYN最大超时次数是1次,目的是为了防止多次重传SYN,把服务端SYN、ACK超时定时器重置。
  接着,还是如上面的步骤:客户端配置防火墙屏蔽服务端的数据包客户端tcpdump抓取curl执行时的数据包
  把抓取的数据包,用Wireshark打开分析,显示的时序图如下:
  从上图,我们可以分析出:客户端的SYN只超时重传了1次,因为tcpsynretries值为1服务端应答了客户端超时重传的SYN包后,由于一直收不到客户端的ACK包,所以服务端一直在超时重传SYN、ACK包,每次的RTO也是指数上涨的,一共超时重传了5次,因为tcpsynackretries值为5
  接着,我把tcpsynackretries设置为2,tcpsynretries依然设置为1:echo2procsysnetipv4tcpsynackretriesecho1procsysnetipv4tcpsynretries
  依然保持一样的实验步骤进行操作,接着把抓取的数据包,用Wireshark打开分析,显示的时序图如下:
  可见:客户端的SYN包只超时重传了1次,符合tcpsynretries设置的值;服务端的SYN、ACK超时重传了2次,符合tcpsynackretries设置的值
  实验二的实验小结
  通过实验二的实验结果,我们可以得知,当TCP第二次握手SYN、ACK包丢了后,客户端SYN包会发生超时重传,服务端SYN、ACK也会发生超时重传。
  客户端SYN包超时重传的最大次数,是由tcpsynretries决定的,默认值是5次;服务端SYN、ACK包时重传的最大次数,是由tcpsynackretries决定的,默认值是5次。
  实验三:TCP第三次握手ACK丢包
  为了模拟TCP第三次握手ACK包丢,我的实验方法是在服务端配置防火墙,屏蔽客户端TCP报文中标志位是ACK的包,也就是当服务端收到客户端的TCPACK的报文时就会丢弃。
  iptables配置命令如下:
  接着,在客户端执行如下tcpdump命令:
  然后,客户端向服务端发起telnet,因为telnet命令是会发起TCP连接,所以用此命令做测试:
  此时,由于服务端收不到第三次握手的ACK包,所以一直处于SYNRECV状态:
  而客户端是已完成TCP连接建立,处于ESTABLISHED状态:
  过了1分钟后,观察发现服务端的TCP连接不见了:
  过了30分钟,客户端依然还是处于ESTABLISHED状态:
  接着,在刚才客户端建立的telnet会话,输入123456字符,进行发送:
  持续好长一段时间,客户端的telnet才断开连接:
  以上就是本次的实现三的现象,这里存在两个疑点:为什么服务端原本处于SYNRECV状态的连接,过1分钟后就消失了?为什么客户端telnet输入123456字符后,过了好长一段时间,telnet才断开连接?
  不着急,我们把刚抓的数据包,用Wireshark打开分析,显示的时序图如下:
  上图的流程:客户端发送SYN包给服务端,服务端收到后,回了个SYN、ACK包给客户端,此时服务端的TCP连接处于SYNRECV状态;客户端收到服务端的SYN、ACK包后,给服务端回了个ACK包,此时客户端的TCP连接处于ESTABLISHED状态;由于服务端配置了防火墙,屏蔽了客户端的ACK包,所以服务端一直处于SYNRECV状态,没有进入ESTABLISHED状态,tcpdump之所以能抓到客户端的ACK包,是因为数据包进入系统的顺序是先进入tcpudmp,后经过iptables;接着,服务端超时重传了SYN、ACK包,重传了5次后,也就是超过tcpsynackretries的值(默认值是5),然后就没有继续重传了,此时服务端的TCP连接主动中止了,所以刚才处于SYNRECV状态的TCP连接断开了,而客户端依然处于ESTABLISHED状态;虽然服务端TCP断开了,但过了一段时间,发现客户端依然处于ESTABLISHED状态,于是就在客户端的telnet会话输入了123456字符;由于服务端的防火墙配置了屏蔽所有携带ACK标志位的TCP报文,客户端发送的数据报文,服务端并不会接收,而是丢弃(如果服务端没有设置防火墙,由于服务端已经断开连接,此时收到客户的发来的数据报文后,会回RST报文)。客户端由于一直收不到数据报文的确认报文,所以触发超时重传,在超时重传过程中,每一次重传,RTO的值是指数增长的,所以持续了好长一段时间,客户端的telnet才报错退出了,此时共重传了15次,然后客户端的也断开了连接。
  通过这一波分析,刚才的两个疑点已经解除了:服务端在重传SYN、ACK包时,超过了最大重传次数tcpsynackretries,于是服务端的TCP连接主动断开了。客户端向服务端发送数据报文时,如果迟迟没有收到数据包的确认报文,也会触发超时重传,一共重传了15次数据报文,最后telnet就断开了连接。
  TCP第一次握手的SYN包超时重传最大次数是由tcpsynretries指定,TCP第二次握手的SYN、ACK包超时重传最大次数是由tcpsynackretries指定,那TCP建立连接后的数据包最大超时重传次数是由什么参数指定呢?
  TCP建立连接后的数据包传输,最大超时重传次数是由tcpretries2指定,默认值是15次,如下:catprocsysnetipv4tcpretries215
  如果15次重传都做完了,TCP就会告诉应用层说:搞不定了,包怎么都传不过去!
  那如果客户端不发送数据,什么时候才会断开处于ESTABLISHED状态的连接?
  这里就需要提到TCP的保活机制。这个机制的原理是这样的:
  定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的TCP连接已经死亡,系统内核将错误信息通知给上层应用程序。
  在Linux内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为默认值:net。ipv4。tcpkeepalivetime7200net。ipv4。tcpkeepaliveintvl75net。ipv4。tcpkeepaliveprobes9tcpkeepalivetime7200:表示保活时间是7200秒(2小时),也就2小时内如果没有任何连接相关的活动,则会启动保活机制tcpkeepaliveintvl75:表示每次检测间隔75秒;tcpkeepaliveprobes9:表示检测9次无响应,认为对方是不可达的,从而中断本次的连接。
  也就是说在Linux系统中,最少需要经过2小时11分15秒才可以发现一个死亡连接。
  这个时间是有点长的,所以如果我抓包足够久,或许能抓到探测报文。
  实验三的实验小结
  在建立TCP连接时,如果第三次握手的ACK,服务端无法收到,则服务端就会短暂处于SYNRECV状态,而客户端会处于ESTABLISHED状态。
  由于服务端一直收不到TCP第三次握手的ACK,则会一直重传SYN、ACK包,直到重传次数超过tcpsynackretries值(默认值5次)后,服务端就会断开TCP连接。
  而客户端则会有两种情况:如果客户端没发送数据包,一直处于ESTABLISHED状态,然后经过2小时11分15秒才可以发现一个死亡连接,于是客户端连接就会断开连接。如果客户端发送了数据包,一直没有收到服务端对该数据包的确认报文,则会一直重传该数据包,直到重传次数超过tcpretries2值(默认值15次)后,客户端就会断开TCP连接。
  TCP快速建立连接
  客户端在向服务端发起HTTPGET请求时,一个完整的交互过程,需要2。5个RTT的时延。
  由于第三次握手是可以携带数据的,这时如果在第三次握手发起HTTPGET请求,需要2个RTT的时延。
  但是在下一次(不是同个TCP连接的下一次)发起HTTPGET请求时,经历的RTT也是一样,如下图:
  在Linux3。7内核版本中,提供了TCPFastOpen功能,这个功能可以减少TCP连接建立的时延。
  在第一次建立连接的时候,服务端在第二次握手产生一个Cookie(已加密)并通过SYN、ACK包一起发给客户端,于是客户端就会缓存这个Cookie,所以第一次发起HTTPGet请求的时候,还是需要2个RTT的时延;在下次请求的时候,客户端在SYN包带上Cookie发给服务端,就提前可以跳过三次握手的过程,因为Cookie中维护了一些信息,服务端可以从Cookie获取TCP相关的信息,这时发起的HTTPGET请求就只需要1个RTT的时延;
  注:客户端在请求并存储了FastOpenCookie之后,可以不断重复TCPFastOpen直至服务器认为Cookie无效(通常为过期)
  在Linux上如何打开FastOpen功能?
  可以通过设置net。ipv4。tcpfastopn内核参数,来打开FastOpen功能。
  net。ipv4。tcpfastopn各个值的意义:0关闭1作为客户端使用FastOpen功能2作为服务端使用FastOpen功能3无论作为客户端还是服务器,都可以使用FastOpen功能
  TCPFastOpen抓包分析
  在下图,数据包7号,客户端发起了第二次TCP连接时,SYN包会携带Cooike,并且长度为5的数据。
  服务端收到后,校验Cooike合法,于是就回了SYN、ACK包,并且确认应答收到了客户端的数据包,ACK516
  TCP重复确认和快速重传
  当接收方收到乱序数据包时,会发送重复的ACK,以便告知发送方要重发该数据包,当发送方收到3个重复ACK时,就会触发快速重传,立刻重发丢失数据包。
  TCP重复确认和快速重传的一个案例,用Wireshark分析,显示如下:
  数据包1期望的下一个数据包Seq是1,但是数据包2发送的Seq却是10945,说明收到的是乱序数据包,于是回了数据包3,还是同样的Seq1,Ack1,这表明是重复的ACK;数据包4和6依然是乱序的数据包,于是依然回了重复的ACK;当对方收到三次重复的ACK后,于是就快速重传了Seq1、Len1368的数据包8;当收到重传的数据包后,发现Seq1是期望的数据包,于是就发送了个确认收到快速重传的ACK
  注意:快速重传和重复ACK标记信息是Wireshark的功能,非数据包本身的信息。
  以上案例在TCP三次握手时协商开启了选择性确认SACK,因此一旦数据包丢失并收到重复ACK,即使在丢失数据包之后还成功接收了其他数据包,也只需要重传丢失的数据包。如果不启用SACK,就必须重传丢失包之后的每个数据包。
  如果要支持SACK,必须双方都要支持。在Linux下,可以通过net。ipv4。tcpsack参数打开这个功能(Linux2。4后默认打开)。
  TCP流量控制
  TCP为了防止发送方无脑的发送数据,导致接收方缓冲区被填满,所以就有了滑动窗口的机制,它可利用接收方的接收窗口来控制发送方要发送的数据量,也就是流量控制。
  接收窗口是由接收方指定的值,存储在TCP头部中,它可以告诉发送方自己的TCP缓冲空间区大小,这个缓冲区是给应用程序读取数据的空间:如果应用程序读取了缓冲区的数据,那么缓冲空间区就会把被读取的数据移除如果应用程序没有读取数据,则数据会一直滞留在缓冲区。
  接收窗口的大小,是在TCP三次握手中协商好的,后续数据传输时,接收方发送确认应答ACK报文时,会携带当前的接收窗口的大小,以此来告知发送方。
  假设接收方接收到数据后,应用层能很快的从缓冲区里读取数据,那么窗口大小会一直保持不变,过程如下:
  但是现实中服务器会出现繁忙的情况,当应用程序读取速度慢,那么缓存空间会慢慢被占满,于是为了保证发送方发送的数据不会超过缓冲区大小,服务器则会调整窗口大小的值,接着通过ACK报文通知给对方,告知现在的接收窗口大小,从而控制发送方发送的数据大小。
  零窗口通知与窗口探测
  假设接收方处理数据的速度跟不上接收数据的速度,缓存就会被占满,从而导致接收窗口为0,当发送方接收到零窗口通知时,就会停止发送数据。
  如下图,可以看到接收方的窗口大小在不断的收缩至0:
  接着,发送方会定时发送窗口大小探测报文,以便及时知道接收方窗口大小的变化。
  以下图Wireshark分析图作为例子说明:
  发送方发送了数据包1给接收方,接收方收到后,由于缓冲区被占满,回了个零窗口通知;发送方收到零窗口通知后,就不再发送数据了,直到过了3。4秒后,发送了一个TCPKeepAlive报文,也就是窗口大小探测报文;当接收方收到窗口探测报文后,就立马回一个窗口通知,但是窗口大小还是0;发送方发现窗口还是0,于是继续等待了6。8(翻倍)秒后,又发送了窗口探测报文,接收方依然还是回了窗口为0的通知;发送方发现窗口还是0,于是继续等待了13。5(翻倍)秒后,又发送了窗口探测报文,接收方依然还是回了窗口为0的通知;
  可以发现,这些窗口探测报文以3。4s、6。5s、13。5s的间隔出现,说明超时时间会翻倍递增。
  这连接暂停了25s,想象一下你在打王者的时候,25s的延迟你还能上王者吗?
  发送窗口的分析
  在Wireshark看到的Windowssize也就是win,这个值表示发送窗口吗?
  这不是发送窗口,而是在向对方声明自己的接收窗口。
  你可能会好奇,抓包文件里有Windowsizescalingfactor,它其实是算出实际窗口大小的乘法因子,Windowsizevalue实际上并不是真实的窗口大小,真实窗口大小的计算公式如下:
  WindowsizevalueWindowsizescalingfactorCaculatedwindowsize
  对应的下图案例,也就是32204865536。
  实际上是Caculatedwindowsize的值是Wireshark工具帮我们算好的,Windowsizescalingfactor和Windossizevalue的值是在TCP头部中,其中Windowsizescalingfactor是在三次握手过程中确定的,如果你抓包的数据没有TCP三次握手,那可能就无法算出真实的窗口大小的值,如下图:
  如何在包里看出发送窗口的大小?
  很遗憾,没有简单的办法,发送窗口虽然是由接收窗口决定,但是它又可以被网络因素影响,也就是拥塞窗口,实际上发送窗口是值是min(拥塞窗口,接收窗口)。
  发送窗口和MSS有什么关系?
  发送窗口决定了一口气能发多少字节,而MSS决定了这些字节要分多少包才能发完。
  举个例子,如果发送窗口为16000字节的情况下,如果MSS是1000字节,那就需要发送1600100016个包。
  发送方在一个窗口发出n个包,是不是需要n个ACK确认报文?
  不一定,因为TCP有累计确认机制,所以当收到多个数据包时,只需要应答最后一个数据包的ACK报文就可以了。
  TCP延迟确认与Nagle算法
  当我们TCP报文的承载的数据非常小的时候,例如几个字节,那么整个网络的效率是很低的,因为每个TCP报文中都会有20个字节的TCP头部,也会有20个字节的IP头部,而数据只有几个字节,所以在整个报文中有效数据占有的比重就会非常低。
  这就好像快递员开着大货车送一个小包裹一样浪费。
  那么就出现了常见的两种策略,来减少小报文的传输,分别是:Nagle算法延迟确认
  Nagle算法是如何避免大量TCP小数据报文的传输?
  Nagle算法做了一些策略来避免过多的小数据报文发送,这可提高传输效率。
  Nagle伪代码如下:if有数据要发送{if可用窗口大小MSSand可发送的数据MSS{立刻发送MSS大小的数据}else{if有未确认的数据{将数据放入缓存等待接收ACK}else{立刻发送数据}}}
  使用Nagle算法,该算法的思路是延时处理,只有满足下面两个条件中的任意一个条件,才能可以发送数据:条件一:要等到窗口大小MSS并且数据大小MSS;条件二:收到之前发送数据的ack回包;
  只要上面两个条件都不满足,发送方一直在囤积数据,直到满足上面的发送条件。
  上图右侧启用了Nagle算法,它的发送数据的过程:一开始由于没有已发送未确认的报文,所以就立刻发了H字符;接着,在还没收到对H字符的确认报文时,发送方就一直在囤积数据,直到收到了确认报文后,此时没有已发送未确认的报文,于是就把囤积后的ELL字符一起发给了接收方;待收到对ELL字符的确认报文后,于是把最后一个O字符发送了出去
  可以看出,Nagle算法一定会有一个小报文,也就是在最开始的时候。
  另外,Nagle算法默认是打开的,如果对于一些需要小数据包交互的场景的程序,比如,telnet或ssh这样的交互性比较强的程序,则需要关闭Nagle算法。
  可以在Socket设置TCPNODELAY选项来关闭这个算法(关闭Nagle算法没有全局参数,需要根据每个应用自己的特点来关闭)。
  那延迟确认又是什么?
  事实上当没有携带数据的ACK,它的网络效率也是很低的,因为它也有40个字节的IP头和TCP头,但却没有携带数据报文。
  为了解决ACK传输效率低问题,所以就衍生出了TCP延迟确认。
  TCP延迟确认的策略:当有响应数据要发送时,ACK会随着响应数据一起立刻发送给对方当没有响应数据要发送时,ACK将会延迟一段时间,以等待是否有响应数据可以一起发送如果在延迟等待发送ACK期间,对方的第二个数据报文又到达了,这时就会立刻发送ACK
  延迟等待的时间是在Linux内核中定义的,如下图:
  关键就需要HZ这个数值大小,HZ是跟系统的时钟频率有关,每个操作系统都不一样,在我的Linux系统中HZ大小是1000,如下图:
  知道了HZ的大小,那么就可以算出:最大延迟确认时间是200ms(10005)最短延迟确认时间是40ms(100025)
  TCP延迟确认可以在Socket设置TCPQUICKACK选项来关闭这个算法。
  延迟确认和Nagle算法混合使用时,会产生新的问题
  当TCP延迟确认和Nagle算法混合使用时,会导致时耗增长,如下图:
  发送方使用了Nagle算法,接收方使用了TCP延迟确认会发生如下的过程:发送方先发出一个小报文,接收方收到后,由于延迟确认机制,自己又没有要发送的数据,只能干等着发送方的下一个报文到达;而发送方由于Nagle算法机制,在未收到第一个报文的确认前,是不会发送后续的数据;所以接收方只能等待最大时间200ms后,才回ACK报文,发送方收到第一个报文的确认报文后,也才可以发送后续的数据。
  很明显,这两个同时使用会造成额外的时延,这就会使得网络很慢的感觉。
  要解决这个问题,只有两个办法:要不发送方关闭Nagle算法要不接收方关闭TCP延迟确认
  参考资料:
  〔1〕Wireshark网络分析的艺术。林沛满。人民邮电出版社。
  〔2〕Wireshark网络分析就这么简单。林沛满。人民邮电出版社。
  〔3〕Wireshark数据包分析实战。ChrisSanders。人民邮电出版社。读者问答

家长必学技能!七个控管小孩iPhone帐号的方式如果家中的小孩有使用手机的需求,身为家长一定会担心小孩使用手机后在课业上的专注度交友状况半夜不睡觉或者是在手机游戏上乱花钱,这时候iCloud家人共享里面就有一个管理家中小孩iPh婴儿羊奶粉王者之争,蓝河和佳贝艾特该如何选择?随着消费水平的升级,羊奶粉得到越来越多父母的认可,尤其是90后新手爸妈,对于羊奶粉的认可程度较高。其中,佳贝艾特和蓝河是目前风向较大的羊奶粉品牌,那么这两款羊奶粉对比怎么样?应该怎她在向你求救,你却教她懦弱女儿被霸凌,妈妈的回应引起众怒前一段时间,刷到一条视频,看得让我很生气。一个小女孩放学回家一边扒拉着碗里的饭一边在餐桌上哭着说班上的女孩不好相处,一下子没有和他们说到一起,她们就说坏话。谁知道她妈妈听到女儿的话悠悠往事我的坐月子经历每天微习惯打卡养成记打工的日常生活我和老公于1996年元旦结的婚。结婚第一年的五月我怀孕了。那时侯我和老公都在兰州安宁的砖厂打工。我老公在砖厂开装载机,我在砖厂保养组哪些症状表明孩子可能得了脑瘫?家长应及早发现积极治疗脑瘫是一种特别严重的儿科疾病,会使患儿各方面都受到影响,无论是语言还是行动能力,如果得不到及时有效的治疗,则会使患儿即使长大成人也无法自理,甚至会影响患儿的寿命。因此当出现脑瘫的相捡到宝了!休斯顿火箭队签下30323天才后卫NBA常规赛,太阳今日迎战火箭,前者近来状态不俗取得六连胜,后者则是遭遇两连败,此役保罗继续伤缺。比赛开始后,太阳始终占据着场上的主动没想到的是,在末节他们的命中率出现下降,火箭抓WNBA全明星坎贝奇的下海之路伊丽莎白坎贝奇(ElizabethCambage),1991年8月18日出生于英国伦敦,澳大利亚女子篮球运动员,场上司职中锋,现签约了某成人网站。2007年,伊丽莎白坎贝奇进入澳大梅西收获世界杯第9球超越马拉多纳两项数据再超C罗千场造1174球北京时间12月4日凌晨3点,2022卡塔尔世界杯18决赛,阿根廷队对阵澳大利亚队,本场比赛是梅西职业生涯第1000场里程碑,他在上半场就打进一球,帮助阿根廷队最终21淘汰了澳大利亚分布式数据库数据复制,如何保证数据在分布式场景下的高可用?前面一篇我们讲的是分片技术,它主要的目的是提高数据容量和性能。今天我们将介绍分布式数据库另外一个重要根基复制。复制的主要目的是在几个不同的数据库节点上保留相同数据的副本,从而提供一经济日报携手京东发布数据华东农产品加快走出去数据来源京东消费及产业发展研究院为农产品加入体验感随着人们消费习惯的改变,农产品电商的模式逐渐成为传统销售渠道外的新赛道。线上渠道不仅是高质量农产品走出去的好帮手,还能通过信息文化这样的全明星还有什么意义,得分刚破100分,到底防还是不防守?刚刚结束了全明星正赛,最终南区以10088战胜北区,赵睿获得全明星的最有价值球员。首先不说过程,就说比分刚刚过百,全明星赛这合理嘛,你说玩命防守吧,还有点收敛,你说不防守吧,还给你
朝称与俄站同一战壕,美高官访中东,中俄合作,朝鲜战争模式再现1月25日,美国和德国宣布向乌克兰提供主战坦克后,欧洲波兰西班牙挪威等国随之跟进,媒体称一个进攻性的坦克联盟出现了。这无疑对俄罗斯是十分不利的。但情况随之出现重大变化,1月27日,小市值股12只,净利润翻倍股11只,机构也密集关注,低估值滞涨股名单请收藏!A股这些行业估值显著降低兔年大吉一批低估值滞涨股来了,这类股票有望在后续行情中实现估值回归。2022年以来,A股经历了一波向下调整今年开年重拾涨势,与2021年相比主要股指仍处于相对低位。估值方面来看,与中工漫评丨该为人脸信息识别划红线了绘画刘琪文字李靖打开手机,上海市民陈宽发现,每天需要进行人脸识别的App太多。从手机银行App到购物软件,从化妆类App到游戏防沉迷一天下来,脸要被扫十几次。(据法治日报1月28日今天大年初七,新的一年祝工作顺利,前兔似锦!就业是头等民生大事稳经济大盘的重要支撑。稳就业事关广大家庭生计,为了稳定和扩大就业,过去这一年出台了哪些政策?中国政府网(IDzhengfu)国务院客户端带你看。新的一年,祝工作顺为什么明明白天很累,晚上我们还是睡不着?现代的生活几乎让人喘不过气来,对于80后90后来说,生活的节奏跟自己的童年时期真是天壤之别。以前我们可以跟小伙伴玩玩游戏,看看书,跟大人逛逛街。现在到了我们成家立业的时候,却发现承新春走基层百岁老人过生日,各路亲戚云祝福大年初三,又是林家院里给百岁老人林洪泉做寿的日子。与往年在饭店里的喧闹场景不同,这一次儿孙们在家里为老人办了小范围的温馨寿宴,各路亲戚则纷纷送上云祝福。林洪泉是济南市长清区崮云湖街差点不能回家过年!怀孕6个月阳了,她被抢救9天9夜1月18日下午,明媚的阳光斜照着小区,温暖着每一个回家过年的人儿。小丽坐在房间的落地窗前,掀开盖布,摆上琴谱,十指开始在钢琴上跳跃。图源网络悠扬的琴声中,一旁的父亲边拍边跟远在外省永兴材料研究报告特钢新能源双轮驱动,攻守兼备成长可期(报告出品方作者华福证券,王保庆)1锂电新能源特钢新材料双轮驱动1。1不锈钢线棒材龙头,切入新能源快车道永兴特种材料科技股份有限公司前身湖州久立特钢有限公司成立于2000年7月,2关注汽车海运价格暴涨,比亚迪下单2艘7000车双燃料汽车运输船文懂车帝原创刘艺伟懂车帝原创行业随着新能源汽车市场快速发展,中国车企正密集出海,运输需求旺盛叠加海上船舶运力有限,导致运价暴涨,由此比亚迪开始组建海上船队。近日,中国船舶集团旗下广又是曼德拉效应?满江红上映后,精忠报国还是尽忠报国引争论电影满江红上映之后掀起了一阵浪潮,激发了大家心中的记忆,诗词满江红也是被拿出来反复背诵,怒发冲冠,凭栏处肯定就要有人接下一句,也带火了岳飞相关的旅游景区。满江红的主人公是岳飞,讲述满江红张艺谋儿子出演引关注,但星二代里我只服王骁满江红的票房这波彻底杀疯了,截止目前影片狂揽30。6亿票房,预测票房也达到了46。5亿,照着这个势头发展,该片是有机会冲进影史榜前五的。而票房井喷的同时,影片也在豆瓣上斩获了7。5
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网