Java 如何模拟adhoc网络节点?
我有源类、中间类和目标类。源类有一个方法,该方法以一定的概率接收新的数据包进行发送。无论何时接收到数据包,都应将其广播(通过某些setPacket方法模拟)到所有相邻的中间节点。中间节点应该将这些数据包广播给它们的邻居,直到数据包到达目的地。问题是,每当数据包传输链启动时,源节点就停止运行其获取新数据包的方法。因此,基本上源类在函数链运行时被冻结。有没有办法同时运行这两个进程?(就像源节点将请求发送到中间类,中间类将独立完成其工作)我尝试了三个类中的每一个来扩展线程类,但传输链仍然冻结了源类。使用的语言是Java,但如果有其他语言可以完成这项工作,我可以切换到它们Java 如何模拟adhoc网络节点?,java,multithreading,networking,Java,Multithreading,Networking,我有源类、中间类和目标类。源类有一个方法,该方法以一定的概率接收新的数据包进行发送。无论何时接收到数据包,都应将其广播(通过某些setPacket方法模拟)到所有相邻的中间节点。中间节点应该将这些数据包广播给它们的邻居,直到数据包到达目的地。问题是,每当数据包传输链启动时,源节点就停止运行其获取新数据包的方法。因此,基本上源类在函数链运行时被冻结。有没有办法同时运行这两个进程?(就像源节点将请求发送到中间类,中间类将独立完成其工作)我尝试了三个类中的每一个来扩展线程类,但传输链仍然冻结了源类。使
public class Main {
public static void main(String[] args) {
// init nodes
SourceNode sourceNode = new SourceNode();
IntermediateNode intermediateNode1 = new IntermediateNode();
IntermediateNode intermediateNode2 = new IntermediateNode();
IntermediateNode intermediateNode3 = new IntermediateNode();
DestinationNode destinationNode = new DestinationNode();
// create network topology, S - I - I - I - D
sourceNode.setNextNode(intermediateNode1);
intermediateNode1.setNextNode(intermediateNode2);
intermediateNode2.setNextNode(intermediateNode3);
intermediateNode3.setNextNode(destinationNode);
// setup listeners
sourceNode.setSetupMessageListener(intermediateNode1);
intermediateNode1.setSetupMessageListener(intermediateNode2);
intermediateNode2.setSetupMessageListener(intermediateNode3);
intermediateNode3.setSetupMessageListener(destinationNode);
sourceNode.run();
}
}
public interface SetupMessageListener {
void onNewSetupMessage();
}
public class Node {
protected SetupMessageListener setupMessageListener;
protected Node nextNode;
public void setNextNode(Node nextNode) {
this.nextNode = nextNode;
}
public void setSetupMessageListener(SetupMessageListener setupMessageListener) {
this.setupMessageListener = setupMessageListener;
}
}
import java.util.Random;
public class SourceNode extends Node implements Runnable {
@Override
public void run() {
while(true) {
// simulate generating new setup message with probability 1/10
Random random = new Random();
int rv = random.nextInt(10);
if (rv == 0) {
createNewSetupMessage();
}
}
}
public void createNewSetupMessage() {
System.out.println("New setup message was created in Source Node");
if (setupMessageListener != null) {
setupMessageListener.onNewSetupMessage();
}
}
}
public class IntermediateNode extends Node implements SetupMessageListener {
public static int count = 0;
private int id;
public IntermediateNode() {
id = count++;
}
@Override
public void onNewSetupMessage() {
System.out.println("Intermediate Node " + id + " got notified about setup message");
// pass setup message to next neighbor
setupMessageListener.onNewSetupMessage();
}
}
public class DestinationNode extends Node implements SetupMessageListener {
@Override
public void onNewSetupMessage() {
System.out.println("Destination Node got notified about new setup message");
}
}
示例输出是
New setup message was created in Source Node
Intermediate Node 0 got notified about setup message
Intermediate Node 1 got notified about setup message
Intermediate Node 2 got notified about setup message
Destination Node got notified about new setup message
New setup message was created in Source Node
Intermediate Node 0 got notified about setup message
然而,我希望它像smth一样
New setup message was created in Source Node
Intermediate Node 0 got notified about setup message
New setup message was created in Source Node
Intermediate Node 1 got notified about setup message
Intermediate Node 0 got notified about setup message
Intermediate Node 2 got notified about setup message
Destination Node got notified about new setup message
问题是整个消息传递在主线程中完成……您需要实现
createNewSetupMessage
和onNewMessageSetup
的功能,作为Runnable
的实例,并启动新线程来运行它们
public class SetupMessageSender implements Runnable{
private SetupMessageListener setupMessageListener;
public SetupMessageSender(SetupMessageListener setupMessageListener){
this.setupMessageListener = setupMessageListener;
}
@Override
public void run() {
if (setupMessageListener != null) {
setupMessageListener.onNewSetupMessage();
}
}
public SetupMessageListener getSetupMessageListener() {
return this.setupMessageListener;
}
public void setSetupMessageListener(SetupMessageListener setupMessageListener) {
this.setupMessageListener = setupMessageListener;
}
}
然后
但是,在节点侦听器上要小心,因为它需要根据拓扑结构进行一些调整(例如,如果中间节点侦听多个不同节点),所以请进行调整
@Override
public synchronized void onNewSetupMessage() {
System.out.println("Intermediate Node " + id + " got notified about setup message");
// pass setup message to next neighbor
Thread smService = new Thread(new SetupMessageSender(this.setupMessageListener));
smService.start();
}
虽然这两个方法提供相同的功能,您可以在基类
节点上作为单个方法实现它们。如果不查看您的代码,就无法确定错误所在。添加了代码和示例输出
@Override
public synchronized void onNewSetupMessage() {
System.out.println("Intermediate Node " + id + " got notified about setup message");
// pass setup message to next neighbor
Thread smService = new Thread(new SetupMessageSender(this.setupMessageListener));
smService.start();
}