我正在尝试编写一个程序来实现距离矢量算法。所以我需要节点同时充当服务器和客户端。
基本上我使用 UDP 协议来发送和接收消息。我正在尝试收听来自相邻节点的消息,同时每 5 秒发送一次节点的距离向量。
我的主要问题是我希望停止收听消息,以便我可以广播我的距离矢量。我尝试使用setSoTimeout
,但后来我得到了各种我不知道如何处理的异常。而且我不太确定如何再次“重新打开”套接字以再次等待消息或继续广播消息....
有人可以指出我正确的方向吗?
我的代码如下:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class dv_routing {
public static void main(String[] args) throws Exception {
//initialise variables to default value
int NodeID = 0;
int NodePort = 6000;
String configFile = "A.txt";
int numNbr = 0; // zero neighbour
double[] CostList = new double[10]; //Self cost list
Arrays.fill(CostList, Double.POSITIVE_INFINITY);
int[] ViaList = new int[10]; //Self cost list
Arrays.fill(ViaList, 9999);
double[] Cost = new double[10]; //Inf cost array for Nbr initialization
Arrays.fill(Cost, Double.POSITIVE_INFINITY);
Neighbour Nbr = new Neighbour(); //create Nbr
boolean ischanged = false;
//read user input
if (args.length >= 3) {
System.out.println("i'm here!");
String tmp = args[0];
char tmpchar = tmp.charAt(0);
NodeID = ((int)tmpchar - 65);
NodePort = Integer.parseInt(args[1]);
configFile = args[2];
CostList[NodeID] = 0;
System.out.println(NodeID);
System.out.println(NodePort);
System.out.println(configFile);
//poison reverse
if (args.length <= 4) {
// TODO: poison reverse
}
else
System.out.println("Incorrect Input Format! Please try again!");
}
//reading config file for neighbour data
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream(configFile);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//capture the number neighbours
if ((strLine = br.readLine()) != null){
numNbr = Integer.parseInt(strLine);
System.out.println (numNbr);
}
int elementcnt = 0;
while ((strLine = br.readLine()) != null) {
//separate data
String[] temp = strLine.split(" ");
//get neighbour Node ID
char tmpchar = temp[0].trim().charAt(0);
int ID = (int)(tmpchar - 65);
//NbrIDList.add(new NbrID((int)tmpchar - 65));
//get neighbour cost
CostList[ID] = Double.parseDouble(temp[1].trim());
ViaList[ID] = ID;
//get neighbour port number
int Port = Integer.parseInt(temp[2].trim());
//create entry for neighbour
Nbr.addData(ID, Port);
Nbr.addCost(Cost);
//debugging
//System.out.println((char)(Nbr.getID(elementcnt)+65));
//System.out.println(Nbr.getPort(elementcnt));
//System.out.println(Nbr.getCost(elementcnt)[0]);
elementcnt++;
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
//set timers
long now = System.currentTimeMillis();
long end = now + 50 * 1000;
long broadcast = now + 1 * 1000;
long current = System.currentTimeMillis();
while(current < end) {
System.out.println("in first layer");
//open UDP socket for listening..
DatagramSocket nodeSocket = new DatagramSocket(NodePort);
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
//braodcast...
String OutMsg = CostList[0]+"\t"+CostList[1]+"\t"+CostList[2]+"\t"+CostList[3]+"\t"+CostList[4]+"\t"+CostList[5]+"\t"+CostList[6]+"\t"+CostList[7]+"\t"+CostList[8]+"\t"+CostList[9];
sendData = OutMsg.getBytes();
for (int i = 0; i < numNbr; i++){
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, Nbr.getPort(i));
nodeSocket.send(sendPacket);
}
nodeSocket.setSoTimeout(1000);
while(current < broadcast){
if (nodeSocket.isClosed()){
nodeSocket = new DatagramSocket(NodePort);
}
System.out.println("in receiving layer");
current = System.currentTimeMillis();
ischanged = false;
//get MSG
// Msg format.. "cost1"\t"cost2"\t"cost3"...
try{DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
nodeSocket.receive(receivePacket);
System.out.println("we got here");
String Msg = new String( receivePacket.getData());
System.out.println("RECEIVED: " + Msg);
int NbrPort = receivePacket.getPort();
System.out.println("From: " + NbrPort);
//process the MSG
String[] tmpstr = Msg.split("\t");
for (int i = 0; i<10; i++) {
Cost[i] = Double.parseDouble(tmpstr[i]);
}
int Idx = Nbr.indexOfPort(NbrPort);
System.out.println("From: " + NbrPort);
Nbr.updateCost(Idx, Cost);
//compare cost and update list
for (int i = 0; i<10;i++) {
double NbrNodeCost = (Nbr.getCost(Idx)[i] + CostList[Nbr.getID(Idx)]);
if (!(Double.isInfinite(NbrNodeCost)) && CostList[i] > NbrNodeCost) {
CostList[i] = NbrNodeCost;
ViaList[i] = Nbr.getID(Idx);
ischanged = true;
}
}
System.out.println("Is the list changed? " + ischanged);
System.out.println(CostList[0]+" "+CostList[1]+" "+CostList[2]+" "+CostList[3]+" "+CostList[4]+" "+CostList[5]+" "+CostList[6]+" "+CostList[7]+" "+CostList[8]+" "+CostList[9]);
System.out.println(ViaList[0]+" "+ViaList[1]+" "+ViaList[2]+" "+ViaList[3]+" "+ViaList[4]+" "+ViaList[5]+" "+ViaList[6]+" "+ViaList[7]+" "+ViaList[8]+" "+ViaList[9]);
}catch (SocketTimeoutException e) {
//System.err.println("Caught SocketException: " + e.getMessage());
System.out.println("Timeout reached!!! " + e);
nodeSocket.close();
nodeSocket = new DatagramSocket(NodePort);
current = System.currentTimeMillis();
}
catch (SocketException e1){
System.out.println("Socket closed " + e1);
}
}
//Broadcast List
System.out.println("broadcast");
broadcast = current + 1 * 1000;
current = System.currentTimeMillis();
if (ischanged) {
end = current + 10 * 1000;
}
//braodcast...
OutMsg = CostList[0]+"\t"+CostList[1]+"\t"+CostList[2]+"\t"+CostList[3]+"\t"+CostList[4]+"\t"+CostList[5]+"\t"+CostList[6]+"\t"+CostList[7]+"\t"+CostList[8]+"\t"+CostList[9];
sendData = OutMsg.getBytes();
for (int i = 0; i < numNbr; i++){
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, Nbr.getPort(i));
nodeSocket.send(sendPacket);
}
}
//Print List
//Shortest path to node B: the next hop is C and the cost is 5
for(int i = 0; i <10; i++) {
if(ViaList[i] != 9999){
System.out.println("Shortest path to node "+(char)(i+65)+": the next hop is "+(char)(ViaList[i])+" and the cost is "+CostList[i]);
}
}
System.out.println("end");
}
}
class Neighbour {
public Neighbour(){
NbrIDList = new ArrayList<Integer>();
NbrPortList = new ArrayList<Integer>();
NbrCostList = new ArrayList<double[]>();
}
public void addData(int ID, int Port){
NbrIDList.add(ID);
NbrPortList.add(Port);
}
public void addCost(double[] Cost){
NbrCostList.add(Cost);
}
public int getID(int idx){
return (Integer) NbrIDList.get(idx);
}
public int getPort(int idx){
return (Integer) NbrPortList.get(idx);
}
public int indexOfPort(int Port){
return (Integer) NbrPortList.indexOf(Port);
}
public double[] getCost(int idx){
return (double[]) NbrCostList.get(idx);
}
public void updateCost(int idx, double[] Cost){
NbrCostList.set(idx,Cost);
}
private ArrayList<Integer> NbrIDList;
private ArrayList<Integer> NbrPortList;
private ArrayList<double[]> NbrCostList;
}