Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不丢弃数据包的距离向量线程_Java_Algorithm_Multithreading_Vector_Distance - Fatal编程技术网

Java 不丢弃数据包的距离向量线程

Java 不丢弃数据包的距离向量线程,java,algorithm,multithreading,vector,distance,Java,Algorithm,Multithreading,Vector,Distance,我在网络体系结构1中完成我的任务,我必须在每个节点上实现距离向量路由 在每个节点上,我都有一个线程,用于侦听传入的DatagramPackets,其中包含仅在特定端口上来自相邻节点的路由信息。当数据报到达时,线程处理该数据报,如果其内部路由表中有更新,则它将其路由信息发送给所有邻居 我正在尝试用Java做这件事 我面临的问题是,当数据报到达时,我需要处理它。如果在此期间任何其他数据报到达,它将被丢弃,因为线程当前正在处理信息。这意味着我失去了信息 有人能帮我吗 我使用的是java中从套接字读取的

我在网络体系结构1中完成我的任务,我必须在每个节点上实现距离向量路由

在每个节点上,我都有一个线程,用于侦听传入的
DatagramPacket
s,其中包含仅在特定端口上来自相邻节点的路由信息。当数据报到达时,线程处理该数据报,如果其内部路由表中有更新,则它将其路由信息发送给所有邻居

我正在尝试用Java做这件事

我面临的问题是,当数据报到达时,我需要处理它。如果在此期间任何其他数据报到达,它将被丢弃,因为线程当前正在处理信息。这意味着我失去了信息

有人能帮我吗

我使用的是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();
    }
}

您可以在一个线程中处理接收到的数据报,这样您的带有套接字侦听器的线程就可以继续接收新的数据报。

我在Java中没有这样做,但是,您可以(或应该)同时向套接字传递多个数据报缓冲区(多个线程分别调用Synchronous接收方法,或者最好是一个线程多次调用Asynchronous接收方法)

将多个同步数据报缓冲区传递给套接字的优点是显而易见的:即套接字仍然有一个缓冲区(接收下一个数据报),即使它已经填充了一个缓冲区(使用以前的数据报)并将该缓冲区传递回给您


您可能会问,“缓冲区将以什么顺序传递给我?”答案是,“这不重要。”如果处理数据报的顺序很重要,那么数据报本身应该包含一个序列号(因为数据报在网络上路由时可能会失去顺序,无论您是否同时将多个数据报传递到本地套接字,从而可能导致“同时”接收被无序地传递回您)。

DatagramSocket socket=new DatagramSocket(4445,InetAddress.getByName(“127.0.0.1”); while(true){ 试一试{ //注最后。。 最终字节[]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();
}

}

值得记住的是,UDP是有损传输,而最小化数据包丢失是一个好主意,您永远不要假设您将获得每个数据包(或者数据包将按照您发送的顺序到达)

这是我提交的最后一个项目。 它可能有一些不正确的文档和一些糟糕的Java用法。 由于这个项目在本地系统上运行,所以我没有使用不同的IP地址和相同的端口号,而是用另一种方式

java向每个路由器提供初始邻居详细信息

谢谢 -桑尼·詹

enter code here
/* *文件名:Router.java *公共类名:路由器 * */

//~--JDK导入------------------------------------------------------------

导入java.io.IOException

导入java.net.DatagramPacket

导入java.net.DatagramSocket

导入java.net.InetAddress

导入java.util.HashMap

导入java.util.Iterator

导入java.util.Set

导入java.util.concurrent.LinkedBlockingQueue

导入javax.swing.SwingUtilities

/** * *NA1项目2 2009年春季学期 *@作者sunny jain * * */

公共类路由器扩展线程{

/**
 * 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.
 */
私有类路由跟踪{

    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

导入java.net.DatagramPacket

导入java.net.DatagramSocket

导入java.net.InetAddress

/** * *NA1项目2 2009年春季学期 *@作者sunny jain * * */

公共类网络引导{

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();
    }
}
publicstaticvoidmain(字符串[]args){
试一试{
DatagramSocket dSoc=新的DatagramSocket(4000,InetAddress.getByName(“127.0.0.1”);
字符串[]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;”;
对于(int i=0,端口=4005;i<5;i++){
send(新数据包(sendD[i].getBytes(),sendD[i].length(),InetAddress.getByName(“127.0.0.1”),port++);
}
}捕获(IOEX异常){
例如printStackTrace();
}
}

}

性能说明:为每个数据包实例化一个新线程肯定不是很有效。如果处理顺序很重要,请使用BlockingQueue并让预实例化的处理线程以FIFO方式读取缓冲区。如果顺序不相关,请使用执行者。(如果你真的想压缩循环,考虑重新使用那些字节[]缓冲器……)