2009-05-09 2 views
1

네트워크 아키텍처 1에서 각 노드에서 거리 벡터 라우팅을 구현해야하는 과제를 수행하고 있습니다.패킷을 버리지 않는 거리 벡터에 대한 스레딩

각 노드에서 특정 포트에서만 인접 노드의 라우팅 정보를 포함하는 들어오는 DatagramPacket을 수신하는 스레드가 있습니다. 데이터 그램이 도착하면 스레드는 해당 데이터 그램을 처리하고 내부 라우팅 테이블에 업데이트가 있으면 해당 라우팅 정보를 모든 인접 라우터로 보냅니다.

나는 자바로 해보려고한다.

내가 직면하는 문제는 데이터 그램이 도착할 때 처리해야한다는 것입니다. 이 시간 동안 다른 데이터 그램이 도착하면 스레드는 현재 정보를 처리하고 있으므로 삭제됩니다. 그건 내가 정보가 손실되었다는 것을 의미한다.

아무도 도와 드릴 수 있습니까?

java의 소켓에서 일반적인 읽기 방법을 사용하고 있습니다.

DatagramSocket socket = new DatagramSocket(4445, InetAddress.getByName("127.0.0.1")); 
while (true) { 
    try { 
     byte[] buf = new byte[2000]; 

     // receive request 
     DatagramPacket recvRequest = new DatagramPacket(buf, buf.length); 

     socket.receive(recvRequest); 

     //Some process of data in datagram 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

답변

0

DatagramSocket socket = new DatagramSocket (4445, InetAddress.getByName ("127.0.0.1")); while (true) { try { // 최종 메모 ... 최종 바이트 [] buf = 새 바이트 [2000];

// receive request 
    DatagramPacket recvRequest = new DatagramPacket(buf, buf.length); 

    socket.receive(recvRequest); 

    //Some process of data in datagram 
    (new Thread(new Runnable() { 
     public void run() { 
      // do stuff with data in buf 
      ... 
     } 
    })).start(); 

} catch (IOException e) { 
    e.printStackTrace(); 
} 

}

+0

성능 참고 : 확실히 모든 패킷에 대해 새 스레드를 인스턴스화하는 것은 효율적이지 않습니다. 처리 순서가 중요한 경우 BlockingQueue 을 사용하고 FIFO로 미리 버퍼링 된 버퍼를 미리 인스턴스화해야합니다. 주문과 관련이없는 경우 집행자를 사용하십시오. (실제로 사이클을 짜내려면 해당 바이트 [] 버퍼를 재활용하는 것이 좋습니다 ..) – alphazero

2

수신 된 데이터 그램을 스레드에서 처리 할 수 ​​있으므로 소켓 수신기가있는 스레드가 새 데이터 그램을 계속 수신 할 수 있습니다.

0

Java에서는이 작업을 수행하지 않았지만 소켓에 동시 데이터 그램 버퍼를 여러 개 전달할 수 있습니다 (각각 동기화 된 수신 방법을 호출하는 여러 스레드 또는 바람직하게는 하나의 스레드가 비동기식 수신 방법).

소켓에 여러 개의 동시 데이터 그램 버퍼를 전달할 때의 이점은 분명합니다. 즉, 소켓에 이미 하나의 버퍼 (이전 데이터 그램 포함)가 채워져있는 동안에도 소켓에 여전히 다음 데이터 그램을 수신 할 버퍼가 있고 그 버퍼를 다시 당신에게 넘겼습니다.

"버퍼가 어떤 순서로 전달 되나요?" 그 대답은 "중요하지 않아야합니다."입니다. 데이터 그램을 처리하는 순서가 중요한 경우 데이터 그램 자체에 시퀀스 번호가 포함되어야합니다 (데이터 그램은 네트워크를 통해 라우팅 될 때 순서가 바뀔 수 있으므로 로컬 소켓에 여러 번 동시에 전달했는지 여부에 관계없이 결과적으로 "동시"수신 가능성이 다시 사용자에게 전달됩니다.

0

그것은 패킷 손실을 최소화하는 것은 당신이 모든 패킷을 얻을 것이다 (또는 패킷이 순서에 도착할 것이라고 가정해서는 안 좋은 생각 인 반면, UDP는 손실 전송입니다 기억할만한 가치가 당신 그들을 보냈습니다)

1

내가 제출 한 마지막 프로젝트. 부적절한 문서 및 Java의 잘못된 사용이있을 수 있습니다. 이 프로젝트는 로컬 시스템에서 실행되므로 다른 IP 주소와 포트 번호를 사용하는 대신 다른 방식으로 수행합니다.

NetworkBoot.java는 각 라우터에 초기 인접 항목을 제공합니다.

감사 -Sunny 자이나교

enter code here 

/* * 파일 이름 : Router.java * 공공 클래스 이름 : 라우터 * */

// ~ --- JDK 수입 -------------------------------------------------- ----------

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Set;

import java.util.concurrent.LinkedBlockingQueue;

import javax.swing.SwingUtilities;

/** * * NA1 사업이 2009 년 봄 학기 * @author 화창한 자이나교 * * */

공용 클래스 라우터 확장 스레드 {

/** 
* HashMap containing list of neighbors and cost to reach them. 
*/ 
private HashMap<Integer, Integer> hmapDirectNeighbours = new HashMap<Integer, Integer>(61); 
/** 
* HashMap containing list of destination as key and routing info to them as value. 
* Routing info contains RouteDetail object. 
* @see RouteDetail 
*/ 
private HashMap<Integer, RouteDetail> hmapRoutes = new HashMap<Integer, RouteDetail>(); 
/** 
* DatagramSocket 
*/ 
private DatagramSocket dSoc; 
/** 
* DatagramPacket 
*/ 
private DatagramPacket dpackReceive, dpackSend; 
/** 
* Inetaddress of system on which runs this algorithm. 
*/ 
private InetAddress localAddress; 
/** 
* port to listen at for incoming route info from neighbors. 
*/ 
int port; 
private LinkedBlockingQueue<DatagramPacket> lbq = new LinkedBlockingQueue<DatagramPacket>(); 

/** 
* Made constructor private to force initialization by specifying port 
* compulsory. 
*/ 
private Router() { 
} 

/** 
* Constuctor taking port number as parameter and creates a datagramSocket 
* to listen for incoming DatagramPacket on that socket. 
* @param port 
*/ 
public Router(int port) { 
    try { 
     this.port = port; 
     localAddress = InetAddress.getByName("127.0.0.1"); 
     dSoc = new DatagramSocket(port, localAddress); 
    } catch (Exception ex) { 
     System.out.println("Error while creating socket : " + ex.getMessage()); 
    } 
    this.start(); 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      while (true) { 
       try { 
        received_Route_Info(lbq.take()); 
       } catch (InterruptedException ex) { 
        System.out.println("Error while reading elements from datagram queue"); 
       }}}}); 
} 

public void setRouterBootInfo(String strNeighboursInfo) { 
    String[] strNeighbouringNodes = strNeighboursInfo.split(";"); 

    for (int i = 0; i < strNeighbouringNodes.length; i++) { 

     String[] strNodeIpAndPort = strNeighbouringNodes[i].split(":"); 

     hmapDirectNeighbours.put(Integer.valueOf(strNodeIpAndPort[0]), Integer.valueOf(strNodeIpAndPort[1])); 
     hmapRoutes.put(Integer.valueOf(strNodeIpAndPort[0]), new RouteDetail(null, Integer.valueOf(strNodeIpAndPort[1]))); 
    } 
    propagateChanges(); 
// entry in Route table....No need for infinity as we creat entry when a node is reachable. 
} 

@Override 
public void run() { 
    while (true) { 
     try { 
      byte[] buf = new byte[250]; 
      // receive request 
      dpackReceive = new DatagramPacket(buf, buf.length); 
      dSoc.receive(dpackReceive); 
      lbq.put(dpackReceive); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
      dSoc.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      dSoc.close(); 
     } 
    } 


} 

/** 
* This method is called for each DatagramPacket received containing new 
* routing information. 
* 
* This method checks whether this packet came from neighboring node 
* (routers) only. If true it applies Distance vector algorithm on data 
* present in datagram packet and due to this information if their is any 
* change in local routing information that it displays current local 
* updated routing information and also sends this updated information to 
* other neighbours only. 
* 
* @param dataPckt 
* @see #validate_Is_Packet_From_Neighbor(java.net.DatagramPacket) 
* @see #apply_Routing_Algorithm(java.net.DatagramPacket, java.util.HashMap) 
* @see #print_route_info() 
* @see #send_Updates_To_Neighbors(routesInfo) 
*/ 
private void received_Route_Info(DatagramPacket dataPckt) { 
    if (dataPckt.getPort() == 4000) { 
     setRouterBootInfo(getStringFromBytes(dataPckt)); 
    } else if (validate_Is_Packet_From_Neighbor(dataPckt)) { 
     if (apply_Routing_Algorithm(dataPckt, create_HashMap_Routes(getStringFromBytes(dataPckt)))) { 

      // if their is change in routing information. 
      propagateChanges(); 
     } 
    } 
} 

/** 
* Validates whether the Datagram packet received is from the neighbors only. 
* @param datagrampckt DatagramPacket comtaining routing information. 
* @return true if datagrampckt is from neighbors only otherwise false. 
*/ 
private boolean validate_Is_Packet_From_Neighbor(DatagramPacket datagrampckt) { 
    return hmapDirectNeighbours.containsKey(Integer.valueOf(datagrampckt.getPort())); 
} 

/** 
* Returns byte representaion of data contained in DatagramPacket pkt. 
* @param pkt DatagramPacket 
* @return byte representation of data contained in pkt 
*/ 
private String getStringFromBytes(DatagramPacket pkt) { 
    String strData = new String(pkt.getData()); 
    return strData.substring(0, strData.lastIndexOf(';')); 
} 

/** 
* Applies Distance Vector algorithm using newly received routing information 
* and information presently with this node (Router). 
* @param datagrampckt DatagramPacket containing routing information. 
* @param newRoutes HashMap of routes new information received with 
* destination as key and cost to that destination as value. 
*/ 
private boolean apply_Routing_Algorithm(DatagramPacket dataPckt, HashMap<Integer, Integer> newRoutes) { 
    boolean updated = false; 
    Integer pktSourse = Integer.valueOf(dataPckt.getPort()); 

    // Get a set of the routes 
    Set<Integer> set = newRoutes.keySet(); 

    // Get an iterator 
    Iterator<Integer> iterator = set.iterator(); 

    // Display elements. 
    while (iterator.hasNext()) { 
     Integer key = iterator.next(); 
     Integer nextHopCost = hmapRoutes.get(pktSourse).getPathCost(); 
     int optionalCost = newRoutes.get(key) + (nextHopCost == null ? 0 : nextHopCost); 
     if (hmapRoutes.containsKey(key)) { 
      RouteDetail routeDetail = hmapRoutes.get(key); 

      if (routeDetail.getPathCost().compareTo(optionalCost) > 0) { 
       routeDetail.setNextHop(pktSourse); 
       routeDetail.setPathCost(optionalCost); 
       hmapRoutes.put(key, routeDetail); 
       updated = true; 

      // try to verify above statement 
      } 
     } else { 
      if (!key.equals(port)) { 
       RouteDetail newRouteDetail = new RouteDetail(pktSourse, optionalCost); 
       hmapRoutes.put(key, newRouteDetail); 
       updated = true; 
      } 
     } 
    } 

    return updated; 
} 

/** 
* When internal routing information is chaged, send this information to 
* other neighbors. 
* @param routesInfo byte representaion of routing information. 
*/ 
private void send_Updates_To_Neighbors(byte[] routesInfo) { 

    // Get a set of the routes 
    Set<Integer> set = hmapDirectNeighbours.keySet(); 

    // Get an iterator 
    Iterator<Integer> iterator = set.iterator(); 

    // Display elements. 
    while (iterator.hasNext()) { 
     dpackSend = new DatagramPacket(routesInfo, routesInfo.length, localAddress, iterator.next().intValue()); 

     try { 
      dSoc.send(dpackSend); 
     } catch (IOException ex) { 
      System.out.println("Error while sending route updates : " + ex.getMessage()); 
     } 
    } 
} 

/** 
* Parses routeInfo to creat an HashMap based on this informationin the 
* format as HashMap of <<Integer:Destination>,<Integer: Cost to this destination>> 
* @param routeInfo contains routing information as String in the syntax 
* of {<Destination>:<Cost to destination>;} 
* @return Hashmap<<Integer:Destination>,<Integer: Cost to this destination>> 
*/ 
private HashMap<Integer, Integer> create_HashMap_Routes(String routeInfo) { 
    HashMap<Integer, Integer> routes = new HashMap<Integer, Integer>(); 
    String[] straRoute = routeInfo.split(";"); 

    for (int i = 0; i < straRoute.length; i++) { 
     String[] straDestAndCost = straRoute[i].split(":"); 

     routes.put(Integer.parseInt(straDestAndCost[0]), Integer.parseInt(straDestAndCost[1])); 
    } 

    return routes; 
} 

/** 
* Converts current routing information stored as HashMap to String 
* presentation in format as {<Destination>:<Cost to destination>;} 
* 
* @return String representaion of routing information. 
* @see #hmapRoutes. 
*/ 
private String create_String_Of_Routes() { 
    StringBuilder strB = new StringBuilder(); 

    // Get a set of the routes 
    Set<Integer> set = hmapRoutes.keySet(); 

    // Get an iterator 
    Iterator<Integer> iterator = set.iterator(); 

    // Display elements. 
    while (iterator.hasNext()) { 
     Integer destination = iterator.next(); 

     strB.append(destination); 
     strB.append(":"); 
     strB.append(hmapRoutes.get(destination).getPathCost()); 
     strB.append(";"); 
    } 

    return strB.toString(); 
} 

/** 
* Prints the current routing information stored in <code>hmapRoutes</code> 
* to default output stream of this program. 
* @see #hmapRoutes. 
*/ 
public void print_route_info() { 
    RouteDetail route; 
    StringBuilder builder; 

    // PRINT THE CURRENT ROUTING INFO AT THIS NODE 
    System.out.println(""); 
    System.out.println(" TABLE AT NODE WITH PORT : " + port); 
    System.out.println("--------------------------------------------------------------------------------"); 
    System.out.println("\t\tTo \t|\t Via\t|\tCost\t\t"); 
    System.out.println("--------------------------------------------------------------------------------"); 

    // Get a set of the routes 
    Set<Integer> set = hmapRoutes.keySet(); 

    // Get an iterator 
    Iterator<Integer> iterator = set.iterator(); 

    // Display elements. 
    while (iterator.hasNext()) { 
     Integer key = iterator.next(); 

     route = hmapRoutes.get(key); 
     builder = new StringBuilder(); 
     builder.append("\t\t" + key.intValue()); 
     builder.append("\t|\t" + (route.getNextHop() == null ? " -" : route.getNextHop())); 
     builder.append("\t|\t" + route.getPathCost() + "\t\t"); 
     System.out.println(builder.toString()); 
    } 
} 

/** 
* This class provides details for each destination. 
* It provides detail of cost that will be incurred to reach that 
* destination and next router on that path. 
*/ 

개인 클래스 RouteDetail {

Integer nextHop; 
    Integer pathCost; 

    public RouteDetail(Integer nextHop, Integer pathCost) { 
     this.nextHop = nextHop; 
     this.pathCost = pathCost; 
    } 

    public Integer getNextHop() { 
     return nextHop; 
    } 

    public void setNextHop(Integer nextHop) { 
     this.nextHop = nextHop; 
    } 

    public Integer getPathCost() { 
     return pathCost; 
    } 

    public void setPathCost(Integer pathCost) { 
     this.pathCost = pathCost; 
    } 
} 

private void propagateChanges() { 
    print_route_info(); 
    send_Updates_To_Neighbors(create_String_Of_Routes().getBytes()); 
} 

public static void main(String[] args) { 
    new Router(Integer.parseInt(args[0])); 
} 

}

/* * 파일 이름 : NetworkBoot.java * 공공 클래스 이름 : NetworkBoot * */

수입 때 java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

/** * * NA1 사업이 2009 년 봄 학기 * @author 화창한 자이나교 * * */

공용 클래스 NetworkBoot {

public static void main(String[] args) { 
    try { 
     DatagramSocket dSoc = new DatagramSocket(4000, InetAddress.getByName("127.0.0.1")); 
     String[] sendD = {"4006:3;4007:5;4009:2;", "4005:3;4007:3;4008:6;", "4005:5;4006:3;", "4009:2;4006:6;", "4008:2;4005:2;"}; 
     for (int i = 0, port = 4005; i < 5; i++) { 
      dSoc.send(new DatagramPacket(sendD[i].getBytes(), sendD[i].length(), InetAddress.getByName("127.0.0.1"), port++)); 
     } 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } 
} 

}

관련 문제