2012-10-12 20 views
0

我想寫一個程序來實現距離矢量算法。 所以我需要節點充當服務器和客戶端。如何在無限循環中獲取UDP連接?

基本上我使用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; 

} 
+1

看起來你想一次做兩件事,所以我建議你使用另一個線程。 –

+0

「UDP連接」不存在。你的頭銜至少需要修改。 – EJP

回答

2

網絡幾乎是99.8%線程。爲了解決您的問題,您可以創建一個線程來接收消息,第二個線程每5秒發送一次消息。

有一個關於這個很多問題:

Java: Multithreading & UDP Socket Programming

How can I implement a threaded UDP based server in Java?

java2s也不錯:

Server

Client

+0

也許你可以用一個例子來改進你的答案? – Kev

+0

我對多線程編程完全陌生,但我會嘗試先閱讀。 所以假設我可以創建2個線程,一個接收,一個廣播,我可以通過數據.. 是否意味着我需要在2個不同的端口上創建2個獨立的套接字用於2個目的? – Victor

+0

我只是想知道如果有一種方法來停止接收過程而不殺死整個程序..然後重新啓動.. 如果這是可能的,那麼我真的不得不有2個線程運行..對不對? – Victor