﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Ay's Blog@CNSSUESTC-随笔分类-Others</title><link>http://www.cppblog.com/ay19880703/category/20325.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 18 Jan 2013 17:03:20 GMT</lastBuildDate><pubDate>Fri, 18 Jan 2013 17:03:20 GMT</pubDate><ttl>60</ttl><item><title>[导入]Wireless Fundamental(2) -- 802.11 MAC头格式解析(updating)</title><link>http://www.cppblog.com/ay19880703/archive/2011/03/05/155083.html</link><dc:creator>__ay</dc:creator><author>__ay</author><pubDate>Sat, 05 Mar 2011 08:55:00 GMT</pubDate><guid>http://www.cppblog.com/ay19880703/archive/2011/03/05/155083.html</guid><wfw:comment>http://www.cppblog.com/ay19880703/comments/155083.html</wfw:comment><comments>http://www.cppblog.com/ay19880703/archive/2011/03/05/155083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ay19880703/comments/commentRss/155083.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ay19880703/services/trackbacks/155083.html</trackback:ping><description><![CDATA[<p>&nbsp;</p><p><span style="font-size:18px">作者：__ay&nbsp;</span></p><p>&nbsp;</p><p><span style="font-size: 18px; line-height: 22px; "><br /></span></p><p><span style="font-size: 18px; line-height: 22px; ">在上一篇中，简要概述了无线网络的通信机制，那么在下来就得开始介绍一下无线网络的通信细节了。说到这里，以后所说的内容会有《802.11 无线网络权威指南 第二版影印版》这本书内容的影子，还有内容中会加上通过wireshark抓包的分析以及IEEE关于wlan&nbsp;80211协议的说明文档。虽然说这本书虽然讲得好，但是很多数据包细节上的问题还是需要我们亲手去做实验去验证的，一向认为学习不能仅仅看书，亲手去验证一些你认为疑惑的地方可能会比做几道课后题的效果要好得多得多 ^_^</span></p><p><span style="font-size: 18px; line-height: 22px; "><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">1 MAC802.11数据帧格式</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">首先要说明的是mac802.11的帧格式很特别，它与TCP/IP这一类协议不同，它的长度是可变的。不同功能的数据帧长度会不一样。这一特性说明mac802.11数据帧显得更加灵活，然而，也会更加复杂。mac 802.11的数据帧长度不定主要是由于以下几点决定的</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">1.1 mac地址数目不定，根据帧类型不同，mac 802.11的mac地址数会不一样。比如说 ACK帧仅有一个mac地址，而数据帧有3个mac地址，在WDS模式（下面要提到）下，帧头竟然有4个mac地址。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">1.2 802.11的管理帧所携带的信息长度不定，在管理帧中，不仅仅只有一些类似于mac地址，分片标志之类的这些信息，而且另外还会包括一些其它的信息，这些信息有关于安全设置的，有关于物理通信的，比如说我们的SSID名称就是通过管理帧获得的。AP会根据不同的情况发送包含有不同信息的管理帧。管理帧的细节问题我们会在后面的文章中讨论，这里暂时跳过。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">1.3 加密（wep,wpa等）信息，QOS（quality of service）信息，若有加密的数据帧格式和没有加密的数据帧格式还不一样，加密数据帧格式还多了个加密头，用于解密用。然则QOS也是同样道理。</span></p><p><span style="font-size: 18px; line-height: 22px; "><br /></span></p><p><span style="font-size: 18px; line-height: 22px; ">竟然mac 802.11数据帧那么复杂，我们就先从通用的格式开始说吧</span></p><p><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/o_8a29fe944858205f7bf480c8.jpg" border="0" alt="" width="695" height="196" /><br /></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">帧控制(2&nbsp;bytes)：</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">用于指示数据帧的类型，是否分片等等信息，说白了，这个字段就是记录了mac 802.11的属性。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Protocol version：表明版本类型，现在所有帧里面这个字段都是0x00</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Type：指明数据帧类型，是管理帧，数据帧还是控制帧</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Subtype：指明数据帧的子类型，因为就算是控制帧，控制帧还分RTS帧，CTS帧，ACK帧等等，通过这个域判断出该数据帧的具体类型</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*To&nbsp;DS/From&nbsp;DS：这两个数据帧表明数据包的发送方向，分四种可能情况讨论</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;**若数据包To&nbsp;DS为0，From&nbsp;DS为0，表明该数据包在网络主机间传输</span></p><p>&nbsp;</p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;**若数据包To&nbsp;DS为0，From&nbsp;DS为1，表明该数据帧来自AP</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;**若数据包To&nbsp;DS为1，From&nbsp;DS为0，表明该数据帧发送往AP</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;**若数据包To&nbsp;DS为1，From&nbsp;DS为1，表明该数据帧是从AP发送自AP的，也就是说这个是个WDS(Wireless Distribution System)数据帧，至于什么是WDS，可以参考下这里的介绍 <a href="http://network.pconline.com.cn/solution/0801/1216050.html" target="_blank">#传送门</a></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px; ">&nbsp;&nbsp; &nbsp;*Moreflag：分片标志，若数据帧被分片了，那么这个标志为1，否则为0</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Retry：表明是否是重发的帧，若是为1，不是为0</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*PowerManage：当网络主机处于省电模式时，该标志为1，否则为0.</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Moredata：当AP缓存了处于省电模式下的网络主机的数据包时，AP给该省电模式下的网络主机的数据帧中该位为1，否则为0</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Wep：加密标志，若为1表示数据内容加密，否则为0</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*Order 这个表示用于PCF模式下，这里不予讨论</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">生存周期/Associate&nbsp;ID&nbsp;(2 bytes):</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">先前不是讲过虚拟载波监听的一个机制么，他的Network Allocation Vector（NAV）就存在这里，这里叫duration，即生存周期。当然不是所有时候这个字段存放的NAV值。在特定类型数据帧中，它也可能表示Associate ID。一旦有主机关联到AP了，AP都会为主机分配一个Associate&nbsp;ID。比如在网络主机通知AP自己要进入省电模式（power saving）的时候，网络主机发给AP的通知数据帧里面，这个域就表示的是Associate ID而不是NAV了。当然还可以通过最高位来判断这个域的含义：</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*在15bit为0的时候，该域表示duration</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">&nbsp;&nbsp; &nbsp;*在15bit为1，14bit为1的时候，表示Associate ID。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">序列控制(2 bytes：4&nbsp;bits/12 bits)：这个域分2部分，一个是分片序列号和标识帧列号。分片序列号就是记录分片序号的。比如一个帧A被分片成a1，a2，a3，那么a1，a2，a3这三个分片帧的分片序列分别是0,1,2。这个和IP分段原理一样的，该域占4个比特位。剩下的12个比特位就用于标识帧的序号，这个跟IP头里面的序列号一样。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">MAC地址 1-4&nbsp;</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">这四个地址在不同帧中有不同含义。这些以后会讨论。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">以后我们可能会碰到以下类型的mac地址</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">RA(receiver address)：无线网络中，该数据帧的接收者</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">TA(transmitter&nbsp;address)：无线网络中，该数据帧的发送者</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">BSSID(Basic Service Set ID)：在infrastructure&nbsp;BBS中，BSSID就是AP的mac地址。但是在IBBS中，它是一个随机即生成的46位二进制序列，还有最高两位分别是Universal/Local标志位和Individual/Group标志位。IBBS的BSSID中，Universal/Local标志位为1，表示本地MAC，Individual/Group标志位为0，表示是个人MAC。也就是说在IBBS中，BSSID地址应该类如 10xxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx（x表示随机数要么0要么1,&nbsp;2进制表示</span><span class="Apple-style-span" style="line-height: 22px; font-size: 16.6667px; ">）</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px; ">DA(destine</span><span class="Apple-style-span" style="font-size: 20px; line-height: 22px; ">&nbsp;address)：该帧的目的mac</span><span class="Apple-style-span" style="font-size: 20px; line-height: 22px; ">地址</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">SA(source&nbsp;address)：该帧的源mac地址</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">这里的DA和SA含义和普通以太网中的含义一样，在无线网络中可能我们需要通过AP把数据发送到其它网络内的某台主机中。但是有的人会奇怪，直接在RA中填这台主机的mac地址不就久好了么。但是请注意RA的含义，说的是无线网络中的接收者，不是网络中的接收者，也就是说这台目的主机不再无线网络范围内。在这种情况下我们的RA只是一个中转，所以需要多出一个DA字段来指明该帧的最终目的地，当然，如果有了DA那必须有SA，因为若目的主机要回应的话，SA字段是必不可少的。(假设没有SA字段，那么目的主机回应的数据包就只能发送到源主机所属的AP上了~)</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;">最典型的一个例子就是在WDS模式下，数据帧会有4个地址，RA，TA表示接收端和发送端，这两个地址用于无线传输的时候。还有2个地址是DA和SA，分别跟以太网中一样表示源地址和目的地址。WDS帧的格式如下图：</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 22px;"><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/o_1930a235428f1319241f146a.jpg" border="0" alt="" width="878" height="227" /><br /><span class="Apple-style-span" style="line-height: 21px; font-size: 12.5px; "><span class="Apple-style-span" style="line-height: 22px; font-size: 18px; ">打个比方说，AP1有主机A，AP2有主机B。如果A要和B同学，那么A会首先发送数据帧给AP1，然后</span><span class="Apple-style-span" style="line-height: 22px; font-size: 18px; ">AP1发送帧给AP2 。这个时候帧里面会有4个地址，分别是RA=mac(AP2)，TA=mac(AP1)，DA=mac(B)，SA=mac(A)。</span></span></span></p><p><br /></p><img src ="http://www.cppblog.com/ay19880703/aggbug/155083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ay19880703/" target="_blank">__ay</a> 2011-03-05 16:55 <a href="http://www.cppblog.com/ay19880703/archive/2011/03/05/155083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]Wireless Fundamental(1) -- 802.11MAC入门科普篇</title><link>http://www.cppblog.com/ay19880703/archive/2011/02/05/155084.html</link><dc:creator>__ay</dc:creator><author>__ay</author><pubDate>Sat, 05 Feb 2011 10:20:00 GMT</pubDate><guid>http://www.cppblog.com/ay19880703/archive/2011/02/05/155084.html</guid><wfw:comment>http://www.cppblog.com/ay19880703/comments/155084.html</wfw:comment><comments>http://www.cppblog.com/ay19880703/archive/2011/02/05/155084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/ay19880703/comments/commentRss/155084.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/ay19880703/services/trackbacks/155084.html</trackback:ping><description><![CDATA[<p><span class="Apple-style-span" style="line-height: 27px; font-size: 20px; ">作者：__ay&nbsp;</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">参考书目是&nbsp;《802.11 无线网络权威指南 第二版影印版》 &nbsp;中文版翻译的太恶心了。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px; "><br /></span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">在无线网络通信中，MAC层的工作细节和有线网络差的实在是太大了&#8230;&#8230;</span></p><p><span style="line-height: 22px; font-size: 18px; ">这里仅仅谈论无线MAC层的通信机制，MAC以上的有线无线都一样~~</span></p><p><span style="line-height: 22px; font-size: 18px; "><br /></span></p><p><strong><span style="font-size: 18px; line-height: 22px; ">1. 神马是RTS/CTS？？</span></strong></p><p><strong><span style="font-size: 18px; line-height: 22px; "><br /></span></strong></p><p><span class="Apple-style-span" style="line-height: 22px; font-size: 18px; ">那么说起无线网路，我们其实最最首先考虑通信的可靠性问题，要知道有线网络的传输环境比无线网络封闭多了，但是其可靠性也比无线网络高多了，最最起码有线网络不要考虑可能的微波，手机信号等因素的干扰。正是</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">由于考虑到其它电子设备比如手机，微波炉等有发射微波功能电子产品，我们空气中的无线信号受到的干扰远远比有线信号的要强的多。所以在无线通信时，要考虑到可能的干扰性，所以需要对每一个发送出去的帧进行确认。过程就如下图所示。</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/9fa67d502353f27543a75b07.jpg" border="0" alt="" width="851" height="304" /></span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">但是，出现一个问题一个棘手的问题。就是说如何处理所谓的隐藏节点的问题，那啥是隐藏节点咧？</span></p><p><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/693fe2e8fbd8dc6eb90e2d39.jpg" border="0" alt="" width="905" height="234" /><br /></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">在上一个图中我们可以yy一种特殊情况：&nbsp;2号机可以接收到1号和3号的信号，但是1号机无法发现3号机。</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">那么在1，3号同时发送帧给2号机的时候，2号机没法回应这2个帧，因为帧冲突了。在无线网络里，所有主机都公用一个空气媒介，也就是说在一个主机发送数据的时候其它主机必须保持沉默。那么上述这种情况显然违背了这个规则，造成的结果就是2号机根本没法收到数据。</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">所以这里就又引出一个以太网类似的另一个问题：冲突避免</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">那么对于这种情况我们则需要有个协调机制，协调谁先发，谁后发</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">这就引出了2个功能帧&nbsp;</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">RTS:&nbsp;Request to Send</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">CTS: Clear to Send</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">在1号机传送数据之前，首先发送一个RTS帧给2号机，那么所有接收到RST帧的机器则会保持沉默</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">但是3号机收不到丫~~</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">所以2号机会回应1号机一个CTS帧，3号机收到CTS，则保持沉默（这样所以可能干扰到1/2号机通信的主机都沉默了），然后整个无线网络媒介就可以被空出来给1号机用来传送数据帧给2号机了</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">这就是RTS/CTS机制 发送过程大致如下</span></p><p><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/ecd5b23c5e6fa4bf3c6d9718.jpg" border="0" alt="" width="902" height="389" /><br /></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">但是对于这个机制的使用会消耗额外的计算资源，那么有一个折中的做法就是设置一个RTS的阀值，当网络数据包长度超过这个阀值的时候就启用RTS/CTS机制，否则保持自由发送模式。（我发现老外很喜欢中庸之道~）。当然这个机制可能有些人说无法保证没有冲突，应为可能1,3主机可能同时发送2个RTS包给2号机。这里会有个冲突回避问题，原理和以太网类似，都是遇到发送冲突，那么就随机选择回避。这个就是下面要讨论的一个问题了。</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; "><br /></span></p><p><strong><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">2 WLAN的冲突回避</span></strong></p><p><strong><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></strong></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">无线网络通信另一个主要的问题就是协调问题，就是如何协调区域内的各个主机进行通信，当然RTS/CTS是一种解决机制，但是这只是个小部分，到底如何让无线区域内的主机&#8220;流畅&#8221;的通信，就得涉及到一系列冲突回避策略等问题上了。</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">首先说一下协调模式：</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">在以太网中用的是CSMA/DA的方法，所有主机自由发送报文，若冲突了退避一段时间在发就是了。</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">而在无线网中则有3种协调模式</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">DCF (</span><span class="Apple-style-span" style="font-size: 18px; font-family: Arial, 宋体; ">Distribution Coordination Function)</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">区域内的主机传输，但是跟以太网的冲突避免一样，在检测到冲突后则进行退避。不过需要提的是有时候DCF会采用RTS/CTS机制来减少冲突。这个机制自由性比较强。</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">PCF (</span><span class="Apple-style-span" style="font-size: 18px; font-family: Arial, 宋体; ">Point Coordination&nbsp;Function)</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">这个机制依赖于ACCESS POINTS，既需要通过一台指定的无线主机来协调通信。所以这个机制可以为主机提供无竞争服务，因为AP可以指定谁先发数据谁后发数据，没有传输冲突，真和谐，就是开销要高一些。&nbsp;</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">HCF (</span><span class="Apple-style-span" style="font-size: 18px; font-family: Arial, 宋体; ">Hybird Coordination Function)</span></p><p><span style="font-size: 18px; font-family: Arial, 宋体; ">这个机制是以上两个机制的折中，一方面提供一个尽力而为的服务，但是又对于通信的步骤要求又不如PCF那<span style="font-size: 18px; font-family: Arial, 宋体; ">么严格。这个模式通过维护多个服务队列，然后再决定为怎样的主机提供怎样的服务。</span></span></p><p><span class="Apple-style-span" style="font-size: 19px; line-height: 27px;"><br /></span></p><p>&nbsp;</p><p><span style="font-size:18px">我们以后的讨论情景是基于DCF下的。特别在DCF过程中，他的退避算法和以太网的算法很相似。也是随即退避，随着发送失败的次数增加，退避时间的选择范围会进行指数增长。当检测到信道空闲后，要发送数据的主机需要等待DIFS时间间隔后然后进入竞争状态下，所谓的竞争状态就是说所有主机会在自己的竞争窗口中随即选择一个等待时间，这个等待时间过后则开始发送数据。</span></p><p><span style="font-size:18px">首先来说几个定义：</span></p><p><span style="font-size:18px">1.时隙(原文是slot，我们暂且称之为时隙吧)：这个是退避时间的最小单位，在以太网中退避时间单位是毫秒还是微秒来着我忘了，这个时隙就是无线网络中的时间单位，这个时隙是根据情况而定的。在高速网络(网卡处理性能越好)中时隙会越短。时隙可能是2微秒，也可能是4毫秒，反正是在不同网络中时隙可能不同，这个可以看成退避时间的最小单位。</span></p><p><span style="font-size:18px">2.竞争窗口，就是在发送失败后选择退避时间的集合。比如说初始的窗口大小是0-31&nbsp;slots。这就表明在主机需要在0-31 slots里面随即抽取出一个值来进行等待。打个比方我们的slot设为2微秒，那么在上一次传输数据完毕后经过DIFS（下面会介绍到）间隙，我们在自己的竞争窗口(范围：0-31&nbsp;slots)随即选取到了24这个值，那么我们需要等待的时间就是24&nbsp;slots == 24*2 微秒 ==&nbsp;48 微秒。当然竞争窗口的大小会随着发送失败的次数而增加，因为发送失败次数越多表示网络负载越大，那么所有无线网主机在检测到自己发送失败了以后都要将自己的竞争窗口乘以2，然后再继续等待发送。不过当失败次数达到阀值的时候竞争窗口大小就不会增加了。当发送成功以后竞争窗口就会恢复初始值。</span></p><p><span style="font-size:18px">有图有真相，贴个图继续分析：</span></p><p><span style="font-size: 18px; "><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/ecd5b23c66756cbc3c6d9702.jpg" border="0" alt="" width="869" height="568" />看到初始窗口范围是0-31，随着重传次数增加，窗口也是呈指数增长。当增长到阀值1024大小时就停止增长了，接下来如果还是重传失败的话就一直随机在0-1023 slots中挑出一个值来进行等待。</span></p><div><span style="font-size: 18px; "><br /></span></div><p>&nbsp;</p><p><strong><span style="font-size: 18px; font-family: Arial, 宋体; ">3 时序</span></strong></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">再者就是时序问题了，简单来说就是如何规定无线主机什么时候该</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">做什么。</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">那首先先得说一下无线网络监听机制，这个和有线网络里面不太一样。</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">有线网络里面若物理信道有数据传输的话是肯定可以监听的到的，</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">但无线网络里面却不一定。就拿之前那个隐藏节点的例子来说，</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">3号机可能无法通过监听物理信道来得知一二号机正在传输。</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">所以无线网络通信中，要确定信道是否被占用，引入了虚拟载波监听。</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; "><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; color: #ff0000; font-size: 18px; ">注：载波监听和虚拟载波监听是同时在运行的，只有当这两个模块显示空闲时才表示信道空闲，若其中的一个模块显示信道繁忙都表示信道正在被占用。</span></p><p><span class="Apple-style-span" style="line-height: 27px; color: #ff0000; font-size: 18px; "><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><span style="font-size: 18px; ">关于虚拟载波监听</span><span style="font-size: 18px; ">的原理，那么得先介绍</span></span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">一个叫Network Allocation Vector（NAV）这个变量。这个变量会附在无线数据包内的。</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">准备发送数据的主机通过NAV这个值通知其它沉默的主机信道要被占用多长时间来用于传输数据。</span><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">每个主机都会维护一个自己的NAV值，然而这个NAV值每隔1微秒会递减1，直到递减为0的时候就表示虚拟载波监听的信道空闲。</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 15.8333px; "><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 15.8333px; ">说白了NAV就是个定时器，但是是个动态定时器，当主机沉默时会不断的收到来自无线网络中的含有NAV值的数据包，只有当数据包中的NAV值大于自己的NAV值时，主机才会更新自己的NAV值。</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">比如说 1号主机的NAV值是100，那么收到一个A包，它的NAV值是99，那么1号主机的NAV值就还是100不变。过了10微秒，1号主机又收到一个B包，它的NAV值还是99，但是这个时候1号主机的NAV值是90了(每隔1微秒会递减1的嘛)，所以1号主机会把自己的NAV值更新为99。直到这个NAV值递减到0才说明信道可用。</span></p><p><span class="Apple-style-span" style="font-size: 19px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">接下来又回到时序问题上，在每帧发送结束后（这里指的是所有主机，特别是沉默的主机，当沉默主机检测到NAV值是0就表示传送完毕了）都会有个等待间隙。但这等待间隙类型分4种：</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">SIFS&nbsp;(short interframe space)</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">该类型时间间隔最短，这个类型的时间间隔主要用于高优先级别的操作。要发送RTS,CTS,ACK或者是被分片的帧(假设一个帧被分成了3块，第一部分传送完毕，等待SIFS间隔继续发送第二块，而其他要发送完整帧的主机则需要等待DIFS间隔，这样就能够确保这被分片的帧能够一次性发送完毕，也就是被分片的帧享受更高的传输优先级)的时候。</span></p><p><span class="Apple-style-span" style="font-size: 19px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">PIFS (PCF interframe space)</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">PIFS时间间隔其次，在传输PCF相关的管理帧的时候采用这类型的时间间隔。这种情况就是一般我们用路由器，路由器的管理帧只要等待PIFS就可以发送了。</span></p><p><span class="Apple-style-span" style="font-size: 19px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">DIFS (DCF interframe space)</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">DIFS时间间隔最长，所有主机要传输数据的话必须在上一次传输完毕后统一等待DIFS时隙后才能尝试发送。当然，这里说的是尝试发送，因为后面还得进入一个竞争间隔。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">EIFS (extended interframe space)</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">这类帧的时间间隔不确定，在传输错误的时候才会用到。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">所以除去EIFS，他们仨的时间关系就是 &nbsp;SIFS&lt;PIFS&lt;DIFS，SIFS等待时间最短，DIFS最长，PIFS居中</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">。可以发现，时间越短，发送成功率越高，这也就说明优先级越高。显而易见，RTS/CTS帧，也叫控制帧的发送间隔都是SIFS，因为这类帧的优先级要高于平常的数据传输。所以当你要发送RTS之类的帧时就采用SIFS时间间隔，这样就能够保证RTS帧能够更快比使用其它时间间隔的帧发送出去，其它帧接收到RTS报文后就开始保持沉默将不试图发送帧了。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">整个过程串起来就如下图所示：</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/5cb64a00668359541c95836b.jpg" border="0" alt="" width="886" height="306" /><br />先分析上面的那个时间轴，RTS发送出去，收到CTS。然后间隔SIFS就开始发送数据了，这里的帧是分片的，分片的帧需要一次性传输完，所以每个帧的等待发送时间是SIFS。里面还可以看到ACK的回复时间也是需要等待SIFS的，因为这几个类型的帧对保证数据传输非常重要，所以享有更高的发送优先级，在这种情况下，其它的无线主机发送数据干扰这次传输是不可能的，因为他们需要等待DIFS时间间隔。在他们等待没完的时候RTS,CTS,ACK，分片帧的传输早都开始传输了，这些主机接收到数据传输信息后只能进入沉默。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">那么下面的那个时间轴就更清晰了，这个时间轴其实可以看成是其它沉默无线主机NAV值的情况。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">在刚发送第一个RTS帧的时候，其它主机收到了RTS帧中附带的NAV值，等到0号帧传送结束后各个主机开始等待DISF时间准备传输，但是这个时候发送主机由于在发送分片帧，所以只要等待SIFS时间就发送了，结果是其它主机的DISF时间还没等待完就收到了1号帧给他们的NAV值，然后再一号帧传送的这段时间他们又得只能沉默。这个时间轴上面部分表示SENDER通告给其它主机的NAV值的有效期，下面表示Reveiver通告给其它主机的NAV值有效期。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><strong><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">4 无线主机发送过程</span></strong></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">综合上面的所有概念，下面贴个图来全盘分析下单个无线主机发送数据包的过程</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><img src="http://www.cppblog.com/images/cppblog_com/ay19880703/20324/0d7fd62ba8be256a5243c102.jpg" border="0" alt="" width="812" height="185" /><br /><span style="font-size:18px"><br /></span></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><span style="font-size:18px">1. 前面的busy段表示主机A监听到网络数据繁忙（这里主机A判断信号方面可能是NAV值没递减到0，也可能是物理载波监听那块检测到有数据传送，还可能是2者兼有）</span><br /><span style="font-size:18px"><br /></span></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">2. OK,busy段结束后进入等待阶段，当然这里要发送数据而且不用RTS/CTS机制的话，那么等待时间应该是DIFS间隔的</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; "><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">3. 进入竞争发送阶段，所有主机在自己窗口中随机选一个时间来等待</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; "><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">4. 假设主机A随机到的等待时间最短，那么他就开始发送数据了，其它主机发现有数据传输了则会进入沉默状态，等待下一次数据传输完毕后进行竞争。</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; "><br /></span></p><p><strong><span class="Apple-style-span" style="line-height: 27px; font-size: 20px; ">5 重传</span></strong></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">刚才说到了分片，那么连带重传一起说了吧</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">先说说为什么要分片，什么时候分片的问题</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">在无线网络通信中，要知道传输时受到的干扰是多种多样的，也就是说无线网络在MAC层的稳定性是远远不如以太网般稳定的。所以在长数据帧传输的时候很容易中间被中断。为了提高稳定性，就把这个帧分片，然后再传输，显然短帧传输成功率要高于长帧。这样设计的目的是为了提高无线MAC层的可靠性。这个就跟你拿IE下一个1G的东西（一次性传长帧）和拿迅雷下同样一个1G的东西道理是一样的，显然拿迅雷下更稳定些，因为有断点续传。那么分片传输充其量就是把以前的普通IE下载升级优化成了断点续传罢了。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">当数据包到指定的分片阀值的时候就对数据包进行分片，同一个帧被分片的部分也会带有一样的帧序号，也会有自己的分片编号，也会有个表示为表示这个帧是不是分片帧。这个跟IP分片设计原则是一样的，这个就不具体说了。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;"><br /></span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">再者就是重传问题了，神马时候重传？</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">以上篇幅提到过，只有在收到ACK确认后主机才会认为自己发送帧是成功的。同样，RTS只有在收到CTS后才认为自己的RTS发送成功了。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">所以这里涉及到一个问题就是发送失败如何处理？重传？对~是重传，但是一直发送失败呢？所以对于每个帧都有个重传计数器（注：竞争窗口大小就是根据这个重传计数器来决定的），失败一次就递增一，但失败到指定的上限的时候就放弃发送该帧然后向上层协议报告。</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">然而重传计数器有2个，分别是长帧重传计数器和短帧重传计数器。某帧当长度大于指定阀值的时候，该帧发送失败则长帧重传计数器递增1，反之亦然。这个阀值是可以设定的，重传上限也可以设定。这么设计是因为长帧会占用更多资源（内存空间，传输时间等）以便让管理员通过调整阀值和各个计数器的重传上限来优化无线网络。那么我们来YY一下（纯属YY&#8230;&#8230;我比较没做过网络优化这方面的经验，只是假设下可能的场景~），比如说我希望用来传输300字节一下的帧的时间多一些，那么我就设定阀值为300，然后长帧重传计数器的上限设置低一些，短帧重传计数器上限设置高一些。</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; "><br /></span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">重传计数器要清零很简单，有几种情况</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">1 RTS帧发送出去若收到CTS帧则清零重传技术器（当然这个只可能发生在短帧计数器情况下，因为RTS数据帧一般情况下不属于长帧&#8230;&#8230;当然你要把阀值设成RTS帧大小我也没话说~）</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">2 帧数据发送出去，收到ACK确认</span></p><p><span class="Apple-style-span" style="line-height: 27px; font-size: 18px; ">3 收到广播或者多播帧(<span style="color: #ff0000; font-size: 18px; ">why？书里面这么写的，但没写为什么，这里的多播和广播帧是不是值通告NAV值的广播帧咧？如果是这样，那么就说得通了。待高手解释~</span>)</span></p><p><span class="Apple-style-span" style="font-size: 20px; line-height: 27px;">OK，这一篇结束<br /><br /><br /><br /><br /><br /></span></p><img src ="http://www.cppblog.com/ay19880703/aggbug/155084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/ay19880703/" target="_blank">__ay</a> 2011-02-05 18:20 <a href="http://www.cppblog.com/ay19880703/archive/2011/02/05/155084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>