- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 UnetStack 中实现 RTS/CTS 握手技术。我已经编写了在 2 个节点之间实现 RTS/CTS 的代码(用于测试)。但是我在其中遇到了一些问题。
这是在 UnetStack IDE(版本 1.3)上。以下是我面临的问题。1. 在 fshrc.groovy 中,我使用了 ReservationReq API 来发送 RTS。 RxFrameNtf 用于获取接收信号的通知,但是当我使用变量“rx”来检查接收信号是否为 CTS 时,我得到一个空值(fshrc.groovy 的第 24 行),这表明我没有收到任何 CTS。
代码 1:fshrc.groovy
import org.arl.unet.*
import org.arl.unet.phy.*
import org.arl.unet.*
import org.arl.unet.phy.*
import org.arl.unet.mac.*
import org.arl.fjage.*
def mac = agentForService Services.MAC
subscribe phy
// add a closure to define the 'ping' command
send = { addr, value ->
println "sending RTS to node $addr"
phy << new ReservationReq(recipient: mac, to: addr, duration: 5.second)//not sure about the syntax
println "RTS Sent"
def msg = receive(RxFrameNtf, 1000)
println "abc1"
def rxNtf = receive({ it instanceof RxFrameNtf && it.from == addr}, 5000)
println "abc2"
println rxNtf
def rx = pdu.decode(msg.data)
if(rx.type == CTS_PDU && rxNtf && rxNtf.from == addr)
{
println "CTS Received at ${rxNtf.to} from ${rxNtf.from}}"
phy << new DatagramReq(to: addr, protocol: Protocol.DATA, data: value)
}
}
代码2:handshake-sim.groovy
//! Simulation: 3-node network with ping daemons
import org.arl.fjage.Message
import org.arl.unet.*
import org.arl.mac.*
import org.arl.unet.phy.*
import org.arl.fjage.RealTimePlatform
platform = RealTimePlatform
// run simulation forever
simulate {
node '1', address: 1, remote: 1101, location: [0, 0, 0], shell: true, stack: { container ->
container.add 'hand', new MySimpleHandshakeMac()
container.shell.addInitrc "${script.parent}/fshrc.groovy"
}
node '2', address: 2, remote: 1102, location: [1.km, 0, 0], shell:5102, stack: { container ->
container.add 'hand', new MySimpleHandshakeMac()
}
}
代码 3:MySimpleHandshakeMac.groovy
import org.arl.fjage.*
import org.arl.unet.*
import org.arl.unet.phy.*
import org.arl.unet.mac.*
import org.arl.unet.nodeinfo.*
class MySimpleHandshakeMac extends UnetAgent {
////// protocol constants
private final static int PROTOCOL = Protocol.MAC
private final static float RTS_BACKOFF = 2.seconds
private final static float CTS_TIMEOUT = 5.seconds
private final static float BACKOFF_RANDOM = 5.seconds
private final static float MAX_PROP_DELAY = 2.seconds
private final static int MAX_RETRY = 3
private final static int MAX_QUEUE_LEN = 16
////// reservation request queue
private Queue<ReservationReq> queue = new ArrayDeque<ReservationReq>()
////// PDU encoder/decoder
private final static int RTS_PDU = 0x01
private final static int CTS_PDU = 0x02
private final static PDU pdu = PDU.withFormat {
uint8('type') // RTS_PDU/CTS_PDU
uint16('duration') // ms
}
////// protocol FSM
private enum State {
IDLE, RTS, TX, RX, BACKOFF
}
private enum Event {
RX_RTS, RX_CTS, SNOOP_RTS, SNOOP_CTS
}
private FSMBehavior fsm = FSMBuilder.build {
int retryCount = 0
float backoff = 0
def rxInfo
state(State.IDLE) {
action {
if (!queue.isEmpty()) {
after(rnd(0, BACKOFF_RANDOM)) {
setNextState(State.RTS)
}
}
block()
}
onEvent(Event.RX_RTS) { info ->
rxInfo = info
setNextState(State.RX)
}
onEvent(Event.SNOOP_RTS) {
backoff = RTS_BACKOFF
setNextState(State.BACKOFF)
}
onEvent(Event.SNOOP_CTS) { info ->
backoff = info.duration + 2*MAX_PROP_DELAY
setNextState(State.BACKOFF)
}
}
state(State.RTS) {
onEnter {
Message msg = queue.peek()
def bytes = pdu.encode(type: RTS_PDU, duration: Math.ceil(msg.duration*1000))
phy << new TxFrameReq(to: msg.to, type: Physical.CONTROL, protocol: PROTOCOL, data: bytes)
after(CTS_TIMEOUT) {
if (++retryCount >= MAX_RETRY) {
sendReservationStatusNtf(queue.poll(), ReservationStatus.FAILURE)
retryCount = 0
}
setNextState(State.IDLE)
}
}
onEvent(Event.RX_CTS) {
setNextState(State.TX)
}
}
state(State.TX) {
onEnter {
ReservationReq msg = queue.poll()
retryCount = 0
sendReservationStatusNtf(msg, ReservationStatus.START)
after(msg.duration) {
sendReservationStatusNtf(msg, ReservationStatus.END)
setNextState(State.IDLE)
}
}
}
state(State.RX) {
onEnter {
def bytes = pdu.encode(type: CTS_PDU, duration: Math.round(rxInfo.duration*1000))
phy << new TxFrameReq(to: rxInfo.from, type: Physical.CONTROL, protocol: PROTOCOL, data: bytes)
after(rxInfo.duration + 2*MAX_PROP_DELAY) {
setNextState(State.IDLE)
}
rxInfo = null
}
}
state(State.BACKOFF) {
onEnter {
after(backoff) {
setNextState(State.IDLE)
}
}
onEvent(Event.SNOOP_RTS) {
backoff = RTS_BACKOFF
reenterState()
}
onEvent(Event.SNOOP_CTS) { info ->
backoff = info.duration + 2*MAX_PROP_DELAY
reenterState()
}
}
} // of FSMBuilder
////// agent startup sequence
private AgentID phy
private int addr
@Override
void setup() {
register Services.MAC
}
@Override
void startup() {
phy = agentForService Services.PHYSICAL
subscribe(phy)
subscribe(topic(phy, Physical.SNOOP))
add new OneShotBehavior({
def nodeInfo = agentForService Services.NODE_INFO
addr = get(nodeInfo, NodeInfoParam.address)
})
add(fsm)
}
////// process MAC service requests
@Override
Message processRequest(Message msg) {
println "processRequest"
switch (msg) {
case ReservationReq:
if (msg.to == Address.BROADCAST || msg.to == addr) return new Message(msg, Performative.REFUSE)
if (msg.duration <= 0 || msg.duration > maxReservationDuration) return new Message(msg, Performative.REFUSE)
if (queue.size() >= MAX_QUEUE_LEN) return new Message(msg, Performative.REFUSE)
queue.add(msg)
fsm.restart() // tell fsm to check queue, as it may block if the queue is empty
println "Request Accepted"
return new ReservationRsp(msg)
case ReservationCancelReq:
case ReservationAcceptReq:
case TxAckReq:
return new Message(msg, Performative.REFUSE)
}
return null
}
////// handle incoming MAC packets
@Override
void processMessage(Message msg) {
println "processMessage"
if (msg instanceof RxFrameNtf && msg.protocol == PROTOCOL) {
def rx = pdu.decode(msg.data)
def info = [from: msg.from, to: msg.to, duration: rx.duration/1000.0]
if (rx.type == RTS_PDU) fsm.trigger(info.to == addr ? Event.RX_RTS : Event.SNOOP_RTS, info)
else if (rx.type == CTS_PDU) fsm.trigger(info.to == addr ? Event.RX_CTS : Event.SNOOP_CTS, info)
}
}
////// expose parameters that are expected of a MAC service
final int reservationPayloadSize = 0 // read-only parameters
final int ackPayloadSize = 0
final float maxReservationDuration = 65.535
@Override
List<Parameter> getParameterList() { // publish list of all exposed parameters
return allOf(MacParam)
}
boolean getChannelBusy() { // channel is considered busy if fsm is not IDLE
return fsm.currentState.name != State.IDLE
}
float getRecommendedReservationDuration() { // recommended reservation duration is one DATA packet
return get(phy, Physical.DATA, PhysicalChannelParam.frameDuration)
}
////// utility methods
private void sendReservationStatusNtf(ReservationReq msg, ReservationStatus status) {
send new ReservationStatusNtf(recipient: msg.sender, requestID: msg.msgID, to: msg.to, from: addr, status: status)
}
}
我正在打印 RxNtf。 'null' 被打印为 RxNtf 的值。
最佳答案
当您发送ReservationReq
时,MAC 代理将发送一个RTS 并接收一个CTS。虽然您可以直接订阅 PHY 以收听 CTS,但这不是使用 MAC 的正确方法。您应该等待带有 ReservationStatus.START
的 MAC ReservationStatusNtf
开始传输。
下面是一些示例代码,展示了该方法的工作原理:
def mac = agentForService Services.MAC
if (mac) {
// send reservation request
def req = new ReservationReq(recipient: mac, to: addr, duration: 5.second)
def rsp = request req
if (rsp && rsp.performative == Performative.AGREE) {
// wait for a channel reservation notification
def ntf = receive(ReservationStatusNtf, timeout)
if (ntf && ntf.requestID == req.msgID && ntf.status == ReservationStatus.START) {
// request granted, make your transmission
phy << new DatagramReq(to: addr, protocol: Protocol.DATA, data: value)
}
}
}
除了直接监听 CTS 数据包会很脆弱(因为 MySimpleHandshakeMac
可能会更改协议(protocol)细节)之外,您的方法失败的原因是因为存在随机退避(BACKOFF_RANDOM
,设置为 5 秒)在 MySimpleHandshakeMac
中,而您在 fshrc
中的超时仅为 1 秒。因此,您可能甚至在发送 RTS 之前就超时了,更不用说收到 CTS 了。
关于unetstack - Unetstack 上的 RTS/CTS 协议(protocol)实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55552719/
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!