802.11协议帧间间隔-SIFS,DIFS,PIFS,EIFS 及 slottime

转自http://www.cnblogs.com/sujz/articles/2044342.html

SIFS, Short Interframe Space(SIFS):在802.11系列无线局域网中SIFS是固定值,SIFS是最小的帧间间隔,因此采用SIFS的节点具有访问无线链路的最高优先级。它等于节点从发送状态切换到接收状态并能正确解码所需要的时间,或者从接收状态转为发送状态所需要的时间,在SIFS过期后可能发送的数据包包括ACK、CTS帧,不同标准中规定的SIFS值不同。

Standard SIFS(μs)
IEEE 802.11b 10
IEEE 802.11a 16
IEEE 802.11g 10


DIFS, DCF Interframe Space(DIFS):在DCF协议中,节点在开始发送数据之前需要监测信道是否空闲。如果信道已经空闲,则节点仍需等待DIFS段时间才开始发送数据;而如果在DIFS时间段内任一时刻信道被监测为忙,则节点不得不推迟它的数据发送。DIFS和SIFS间的计算关系如下:

DIFS = SIFS + (2 * Slot time)

Standard Slot Time(µs) DIFS(µs)
IEEE 802.11b 20 50
IEEE 802.11a 9 34
IEEE 802.11g 9 or 20 28 or 50


PIFS, PCF Interframe Space(PIFS):PCF使得AP等待PIFS而不是DIFS时间以访问信道,由于DIFS > PIFS > SIFS,因此AP总比普通节点具有更高的访问信道的优先级。

PIFS = SIFS + Slot time

Standard Slot time(µs) PIFS(µs)
IEEE 802.11b 20 30
IEEE 802.11a 9 25
IEEE 802.11g 9 or 20 19 or 30


EIFS, Extended Interframe Space(EIFS):在前一帧出错的情况下,发送节点不得不延迟EIFS而不是DIFS时间段后再发送下一帧。

EIFS = Transmission time of Ack frame at lowest basic rate + SIFS + DIFS


由于篇幅较长,无法在此处完整展示源代码,以下是 ChannelAccess.cc 的部分源代码,供你参考: ``` #include "ChannelAccess.h" #include "veins/modules/messages/WaveShortMessage_m.h" #define CW_MIN 15 #define CW_MAX 1023 #define SLOT_TIME 0.00001 #define SIFS 0.00001 #define DIFS (2 * SIFS + SLOT_TIME) #define BACKOFF_PERIOD 0.00001 #define MAX_RETRIES 7 Define_Module(ChannelAccess); ChannelAccess::ChannelAccess() { _channelIdle = true; _waitingForSIFS = false; _currentPacket = nullptr; } bool ChannelAccess::isIdle() { return _channelIdle; } void ChannelAccess::sendPacket(Packet* packet) { _currentPacket = packet; if (_channelIdle) { startTransmission(); } else { _backoffCounter = uniform(CW_MIN, CW_MAX); _backoffPeriod = _backoffCounter * SLOT_TIME; } } void ChannelAccess::receivePacket(Packet* packet) { if (_channelIdle) { handlePacketReceived(packet); } else { delete packet; } } void ChannelAccess::handleChannelIdle() { if (!_channelIdle) { if (_waitingForSIFS) { handlePacketSent(); } else { _backoffPeriod -= simTime() - _lastInteractionTime; if (_backoffPeriod <= 0) { if (_retries <= MAX_RETRIES) { _backoffCounter *= 2; if (_backoffCounter > CW_MAX) { _backoffCounter = CW_MAX; } _backoffPeriod = _backoffCounter * SLOT_TIME; _retries++; startTransmission(); } else { delete _currentPacket; _currentPacket = nullptr; _channelIdle = true; } } else { scheduleAt(simTime() + _backoffPeriod, new cMessage("Backoff")); } } } } void ChannelAccess::handleChannelBusy() { if (!_channelIdle) { _backoffPeriod -= simTime() - _lastInteractionTime; if (_backoffPeriod <= 0) { _backoffCounter = uniform(CW_MIN, CW_MAX); _backoffPeriod = _backoffCounter * SLOT_TIME; } scheduleAt(simTime() + _backoffPeriod, new cMessage("Backoff")); } } void ChannelAccess::startTransmission() { _waitingForSIFS = true; _retries = 0; _channelIdle = false; send(_currentPacket, "out"); scheduleAt(simTime() + SIFS, new cMessage("SIFS")); } void ChannelAccess::handlePacketSent() { _channelIdle = true; _waitingForSIFS = false; delete _currentPacket; _currentPacket = nullptr; } void ChannelAccess::handlePacketReceived(Packet* packet) { if (_currentPacket && packet->getKind() == _currentPacket->getKind()) { if (packet->getSenderAddress() != _currentPacket->getSenderAddress()) { delete packet; handleTimeout(); } } else { delete packet; } } void ChannelAccess::handleTimeout() { if (_retries <= MAX_RETRIES) { _backoffCounter *= 2; if (_backoffCounter > CW_MAX) { _backoffCounter = CW_MAX; } _backoffPeriod = _backoffCounter * SLOT_TIME; _retries++; startTransmission(); } else { _channelIdle = true; _currentPacket = nullptr; } } void ChannelAccess::initialize(int stage) { BaseWaveApplLayer::initialize(stage); if (stage == 0) { _channelIdle = true; _waitingForSIFS = false; _currentPacket = nullptr; } } void ChannelAccess::handleMessageWhenUp(cMessage* message) { _lastInteractionTime = simTime(); if (message->isSelfMessage()) { if (strcmp(message->getName(), "Backoff") == 0) { handleChannelIdle(); } else if (strcmp(message->getName(), "SIFS") == 0) { handlePacketSent(); } else if (strcmp(message->getName(), "Timeout") == 0) { handleTimeout(); } delete message; } else { auto packet = check_and_cast<WaveShortMessage*>(message); if (_channelIdle) { handlePacketReceived(new Packet(packet)); } else { delete packet; } } } ``` 以上代码仅供参考,完整的 Veins 模拟器源代码可以在官方网站上下载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值