如何修复在Java中读取文件

时间:2018-11-24 05:11:42

标签: java networking udp

使用Java进行网络连接方面的新功能。因此,在用Java构建自己的网络UDP协议时遇到了问题。该程序应读取两个文件,即itc-1和itc-2,但面临的问题是我的程序仅读取itc-1并在读取itc-2时摇摇欲坠,我不知道问题所在!我不能在这里放置所有代码,因为它太长了,所以我认为这个课程中的问题您可以检查一下!!

客户端类:

public class Client {

    public static final String MESSAGETONODE = "message to node";
    public static final String CHECK = "checking message";
    public static final String ACK = "ACK message";
    public static final String CHECKMESSAGE = "Are you alive?";
    public static final String ACKMESSAGE = "I'm okay";
    public static final String DEATHNOTE = "Death note";
    public static final String BIRTHCERT = "Birth cert";

    public static ArrayList<Node> linkNode = new ArrayList<Node>();
    private static int sourceNode;
    static int destPort;
    static int destNode;
    private int neighborCounts;
    private static int sourcePort;
    static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static BlockingQueue<QueueMessage> blockingQueue;
    private static ArrayList<BlockingQueue<QueueMessage>> ACKQueue;

    private static NetworkLayer networkLayer;

    public Client(int nodeID, String itcFile) throws IOException {

        blockingQueue = new ArrayBlockingQueue<>(100);
        ACKQueue = new ArrayList<>();

        assignFromFile(itcFile);

        networkLayer = new NetworkLayer(itcFile, nodeID, linkNode);

        neighborCounts = networkLayer.getNeighborsCount();
        for (int i = 0; i < neighborCounts; ++i) ACKQueue.add(new ArrayBlockingQueue<>(100));
 System.out.println(nodeID + " " + itcFile);
        sourceNode = nodeID;
for (Node n : linkNode) {
            if (n.getNodeID() == nodeID)
                sourcePort = n.getPortNumber();
        }
        startServer(sourcePort);
        startSender();
        messagePrompt(reader, blockingQueue);
        for (int i = 0; i < neighborCounts; ++i)
            networkLayer.checkNeighbors(blockingQueue, ACKQueue.get(i), i);

    }


    public void messagePrompt(BufferedReader reader, BlockingQueue<QueueMessage> blockingQueue) {
        (new Thread(() -> {
            while (true) {
                BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
                System.out.print("Enter message: ");
                String message = null;
                try {
                    message = inFromUser.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
 System.out.print("Enter destination node: ");
                int destNode = 0;
                try {
                    destNode = Integer.parseInt(reader.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                // TODO this is supposed to be wrapped in headers to avoid what I'm doing in this next line
                message = MESSAGETONODE + " " + destNode + " " + sourceNode + " " + message;
                blockingQueue.add(new QueueMessage(Client.MESSAGETONODE, message, destNode, sourceNode, getTimeInMS()));
            }
        })).start();
    }


    public static void assignFromFile(String itcFile) throws FileNotFoundException {
Scanner docScan = new Scanner(new File(itcFile + ".txt"));
        String data;
 while (docScan.hasNextLine()) {

            data = docScan.nextLine();
String[] word = data.split(" ");
final Node NODE = new Node(Integer.parseInt(word[0]), word[1], Integer.parseInt(word[2]),
                    Integer.parseInt(word[3]), Integer.parseInt(word[4]), Integer.parseInt(word[5]));
            linkNode.add(NODE);

        }
    }

    public static void startSender() {
        (new Thread() {
            @Override
            public void run() {
                try {
 BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
for (Node n : linkNode) {
                        if (destNode == n.getNodeID())
                            destPort = n.getPortNumber();

                    }

                    DatagramSocket socket = new DatagramSocket();
 DatagramPacket msg = new DatagramPacket(new byte[0], 0, InetAddress.getByName("localhost"), destPort);
while (true) {
 QueueMessage queueMessage = blockingQueue.take();
                        String type = queueMessage.getMessageType();
 byte[] bbuf;
                        if (type != null) {
int destNode = queueMessage.getDestinationNID();
 int destPort = networkLayer.routeMessage(queueMessage);
                            if (destPort == NetworkLayer.INF) continue;
 if (queueMessage.getMessage() == null) break;
TransportLayer transportLayer = new TransportLayer(queueMessage.getSourceNID(),
                                    networkLayer.getNodePort(queueMessage.getSourceNID()),
                                    queueMessage.getDestinationNID(), destPort, queueMessage.getMessage());
String message = transportLayer.sendData(queueMessage.getDestinationNID(),
                                    queueMessage.getMessage());
transportLayer.setMessage(message);
                            bbuf = message.getBytes();
                            msg.setData(bbuf);
 msg.setLength(message.length());
                            msg.setPort(destPort);
                            try {
                                socket.send(msg);
                            } catch (IOException ioe) {
 System.err.println("send() failed");
                                return;
                            }
                        }
 }
                    socket.close();
 } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static void startServer(int port) {
 new Thread() {
            @Override
            public void run() {
                ServerSocket ss;
                ServerSocket destSocket;
                DatagramSocket dSocket;
                int bufSize = 512;

                try {
dSocket = new DatagramSocket(port);
                } catch (SocketException se) {
                    System.err.println("cannot create socket with port: " + port);
                    return;
                }

                try {
                    dSocket.setSoTimeout(15000);
                } catch (SocketException se) {
                    System.err.println("Socekt exception: timeout not set");
                }

                DatagramPacket msg = new DatagramPacket(new byte[bufSize], bufSize);

                while (true) {
                    try {
                        msg.setLength(bufSize);
                        dSocket.receive(msg);

                    } catch (SocketTimeoutException ste) {
                        System.err.println("response timed out");
                        continue;
                    } catch (IOException ioe) {
                        System.err.println("Bad receive");
                        break;
                    }

                    String str = new String(msg.getData(), 0, msg.getLength());
TransportLayer transportLayer = new TransportLayer();

                    transportLayer.setMessage(str);
                    int checksum = transportLayer.receiveChecksum();
                    transportLayer.receiveHeaders();

                    str = transportLayer.getMessage();
if (str.startsWith(CHECKMESSAGE)) {
int senderNode = Integer.parseInt(str.substring(CHECKMESSAGE.length() + 1));

                        blockingQueue.add(new QueueMessage(ACK, ACKMESSAGE + " " + sourceNode, senderNode,
                                sourceNode, getTimeInMS()));
 } else if (str.startsWith(ACKMESSAGE)) {
 int senderNode = Integer.parseInt(str.substring(ACKMESSAGE.length() + 1));

                        int neighborIndex = networkLayer.getNeighborIndex(senderNode);
 ACKQueue.get(neighborIndex).add(new QueueMessage(ACK, ACKMESSAGE, 0, sourceNode,
                                getTimeInMS()));
                    } else {

                        if (str.startsWith(MESSAGETONODE)) {
                            Scanner stringstream = new Scanner(str);
                            String type, actualMessage;
                            int dest, src;
 type = stringstream.next();
                            type = stringstream.next();
                            type = stringstream.next();
                            dest = stringstream.nextInt();
                            src = stringstream.nextInt();
                            actualMessage = stringstream.next();
                            if (dest != sourceNode)
                                blockingQueue.add(new QueueMessage(MESSAGETONODE, str, dest, src, getTimeInMS()));
                            else {
                                System.err.println("message from <" + msg.getAddress().getHostAddress() + ","
                                        + msg.getPort() + ">");
                                System.out.println(actualMessage);
                                System.out.println("Checksum received = " + checksum);
                            }

                        } else {
                            Scanner stringstream = new Scanner(str);
String type = stringstream.next();
                            type = stringstream.next();
                            int nodeID = stringstream.nextInt();
                            int src = stringstream.nextInt();
                            int TTL = stringstream.nextInt();
                            int neighborIndex = networkLayer.getNeighborIndex(src);
                            if (str.startsWith(DEATHNOTE)) {
                                System.out.println("Node " + nodeID + " is dead");
 networkLayer.setNodeDead(nodeID);
if (TTL > 1) {
                                    for (int i = 0; i < networkLayer.getNeighborsCount(); ++i)
                                        if (i != neighborIndex)
                                            blockingQueue.add(new QueueMessage(DEATHNOTE, DEATHNOTE + " " +
                                                    nodeID + " " + src + " " + Integer.toString(TTL - 1),
                                                    networkLayer.getNeighborNID(i), sourceNode, getTimeInMS()));
                                }
                            } else {
                                System.out.println("Node " + nodeID + " is alive");
networkLayer.setNodeAlive(nodeID);
 if (TTL > 1) {
                                    for (int i = 0; i < networkLayer.getNeighborsCount(); ++i)
                                        if (i != neighborIndex)
                                            blockingQueue.add(new QueueMessage(BIRTHCERT, BIRTHCERT + " " +
                                                    nodeID + " " + src + " " + Integer.toString(TTL - 1),
                                                    networkLayer.getNeighborNID(i), sourceNode, getTimeInMS()));
                                }
                            }
                        }
                    }
                }
}
        }.start();
    }

    public static long getTimeInMS() {
        return System.currentTimeMillis();
    }


}

主类:

import java.io.*;

public class Main {



    public static void main(String[] args) throws NumberFormatException, IOException {

            Client client;

            if(args.length != 2)
                System.out.println("Usage: java Client host port");
            else 
                client = new Client(Integer.parseInt(args[0]), args[1]); // run as java Main (nodeID) (itc-[number])
            //java Main 1 itc-1

        }
    }

网络层

import java.io.*;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class NetworkLayer {
    private final int threshold = 5000;
    private final int waitingTime = 2000;
    public static final int INF = (int) 1e9;

    private String itcFile;
    private int nNodes;
    private int nodeID;
    private ArrayList<Node> linkNode;
    private int[] nextHop;
    private int[] shortestPath;

    private List<List<Neighbor>> adjList;

    private int aliveMsk = 4095;
    private int tmpMsk = 4095;

    public NetworkLayer(String itcFile, int nodeID, ArrayList<Node> linkNode) throws FileNotFoundException {
        this.itcFile = itcFile;
        this.nNodes = 0;
        this.nodeID = nodeID;
        this.linkNode = linkNode;

        init();
        nextHop = new int[nNodes + 1];
        shortestPath = new int[nNodes + 1];

        setupRoutingTable();
    }

    private void init() throws FileNotFoundException {
        this.nNodes = 0;
        Scanner scanner = new Scanner(new File(itcFile + ".txt"));
        while (scanner.hasNextInt()) {
            this.nNodes++;

            int ID = scanner.nextInt();
            String name = scanner.next();
            int port = scanner.nextInt();
            int n1 = scanner.nextInt();
            int n2 = scanner.nextInt();
            int mtu = scanner.nextInt();


        }
        linkNode.add(new Node(0, "", 0, 0, 0, 0));
        Collections.sort(linkNode, (lhs, rhs) -> lhs.getNodeID() < rhs.getNodeID() ? -1 : 1);

        fillAdjList();
    }

    private boolean notPresentInAdjList(int x, int y) {
        for (Neighbor n : adjList.get(x)) if (n.getID() == y) return false;
        return true;
    }

    private void addToAdjList(int x, int y) {
        if (notPresentInAdjList(x, y)) adjList.get(x).add(new Neighbor(y));
    }

    private void fillAdjList() {
        adjList = new ArrayList<>();
        for (int i = 0; i < nNodes + 5; ++i) adjList.add(new ArrayList<>());
//        System.out.println(adjList.size());

        for (Node n : linkNode) {
            addToAdjList(n.getNodeID(), n.getNodeOne());
            addToAdjList(n.getNodeOne(), n.getNodeID());
            addToAdjList(n.getNodeID(), n.getNodeTwo());
            addToAdjList(n.getNodeTwo(), n.getNodeID());
        }
//        printAdjList();
    }

    private void printAdjList() {
        System.out.println("\nSTARTED PRINTING");
        for (Neighbor i : adjList.get(nodeID)) System.out.print(i.getID() + " ");
        System.out.println("\nENDED PRINTING");
    }

    public void setupRoutingTable() {
        Arrays.fill(nextHop, INF);
        Arrays.fill(shortestPath, INF);

        dijkstra(nodeID);
//        System.out.println("BACK ");
        displayRoutingTable();
    }

    private void dijkstra(int src) {
        PriorityQueue<pqNode> pq = new PriorityQueue<>(1, Comparator.comparingInt(pqNode::getCost));
        nextHop[src] = src;
        shortestPath[src] = 0;
        pq.add(new pqNode(0, src));

        while (!pq.isEmpty()) {
            int top = pq.peek().getCurNode();
            pq.poll();

            for (Neighbor n : adjList.get(top)) {
                int node = n.getID();

                if (isNodeAlive(node) && shortestPath[top] + 1 < shortestPath[node]) {
                    shortestPath[node] = shortestPath[top] + 1;
                    if (nextHop[top] == src) nextHop[node] = node;
                    else nextHop[node] = nextHop[top];
                    pq.add(new pqNode(shortestPath[node], node));
                }
            }
        }
    }

    public void displayRoutingTable() {

        for (int x : shortestPath) System.out.print(x + " ");
        System.out.println();

        System.out.println("\n----------------\n");


        for (int x : nextHop) System.out.print(x + " ");
        System.out.println();

        System.out.println();


    }

    public void checkNeighbors(BlockingQueue<QueueMessage> blockingQueue, BlockingQueue<QueueMessage> ACKQueue,
                               int neighborIndex) {
        (new Thread(() -> {
            Neighbor neighbor = adjList.get(nodeID).get(neighborIndex);
            while (true) {
//                boolean changes = false;
                long curTime = getTimeInMS();
                if (neighbor.getSentMsg()) {
                    if (curTime - neighbor.getLastCheckTime() > waitingTime) {
                        neighbor.setSentMsg(false);
//                        sentMsg1 = false;
                        if (neighbor.getIsAlive()) {
                            System.out.println("Node " + neighbor.getID() + " is dead");
                            neighbor.setIsAlive(false);
//                            changes = true;
                            setNodeDead(neighbor.getID());
                            // eg: Death note 2(node ID) 4(TTL)
                            for (Neighbor n : adjList.get(nodeID))
                                if (neighbor.getID() != n.getID()) {
                                    blockingQueue.add(new QueueMessage(Client.DEATHNOTE, Client.DEATHNOTE + " "
                                            + neighbor.getID() + " " + nodeID + " 4", n.getID(), nodeID,
                                            getTimeInMS()));
                                }
                        }
                    } else {
                        try {
                            QueueMessage message = ACKQueue.poll(100, TimeUnit.MILLISECONDS);
                            if (message != null) {
                                if (message.getOriginatingTime() < neighbor.getLastCheckTime()) continue;
                                neighbor.setSentMsg(false);
                                if (!neighbor.getIsAlive()) {
                                    System.out.println("Node " + neighbor.getID() + " is alive");
                                    neighbor.setIsAlive(true);
//                                    changes = true;
                                    setNodeAlive(neighbor.getID());
                                    // eg: Birth cert 2(node ID) 4(TTL)
                                    for (Neighbor n : adjList.get(nodeID))
                                        if (neighbor.getID() != n.getID()) {
                                            blockingQueue.add(new QueueMessage(Client.BIRTHCERT,
                                                    Client.BIRTHCERT + " " + neighbor.getID() + " " + nodeID
                                                            + " 4", n.getID(), nodeID, getTimeInMS()));
                                        }
                                }
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    if (curTime - neighbor.getLastCheckTime() > threshold) {
                        neighbor.setSentMsg(true);
                        neighbor.setLastCheckTime(curTime);
                        blockingQueue.add(new QueueMessage(Client.CHECK, Client.CHECKMESSAGE + " " + nodeID,
                                neighbor.getID(), nodeID, getTimeInMS()));
                    }
                }
            }
        })).start();
    }

    public void setNodeAlive(int NID) {
        this.tmpMsk |= (1 << NID);
    }

    public void setNodeDead(int NID) {
        this.tmpMsk &= ~(1 << NID);
    }

    public int getNeighborNID(int neighbor) {
        return adjList.get(nodeID).get(neighbor).getID();
    }

    public long getTimeInMS() {
        return System.currentTimeMillis();
    }

    public boolean isNodeAlive(int NID) {
        return ((tmpMsk >>> NID) & 1) == 1;
    }

    public int routeMessage(QueueMessage queueMessage) {
        if (aliveMsk != tmpMsk) {
//            System.out.println("ALIVE MSK " + aliveMsk);
//            System.out.println("TMP MSK " + tmpMsk);
            aliveMsk = tmpMsk;
            setupRoutingTable();
        }
        int destNode = queueMessage.getDestinationNID();
        if (queueMessage.getMessageType() == Client.MESSAGETONODE) {
            if (nextHop[destNode] == INF) return INF;
            return getPort(nextHop[destNode]);
        }
//        System.out.println(destNode + " " + getPort(destNode));
        return getPort(destNode);
    }

    private int getPort(int i) {
        return linkNode.get(i).getPortNumber();
    }

    public int getNeighborsCount() {
        return adjList.get(nodeID).size();
    }

    public int getNeighborIndex(int senderNode) {
        for (int i = 0; i < getNeighborsCount(); i++)
            if (adjList.get(nodeID).get(i).getID() == senderNode) return i;
        return 0;
    }

    public int getNodePort(int sourceNID) {
        return linkNode.get(sourceNID).getPortNumber();
    }
}

0 个答案:

没有答案