Question

Je suis conscient du fait que le code suivant peut sembler vulgaire, mais je suis nouveau dans ces choses et j'ai tout essayé pour le faire fonctionner.

Problème: même si j'utilise (possible de manière erronée) un barrage cyclique, un - et semble toujours être le même - le fil s'arrête trop tôt et imprime son vecteur, laissant 1 sur 11 de ces messages "entrants de connexion entrants" . Il y a probablement quelque chose de terriblement mal avec la dernière itération de ma boucle, mais je n'arrive pas à trouver quoi exactement .. Maintenant, le programme boucles attend pour traiter la dernière connexion.

public class VectorClockClient implements Runnable {
/*
 * Attributes
 */

/*
 * The client number is store to provide fast
 * array access when, for example, a thread's own
 * clock simply needs to be incremented.
 */
private int clientNumber;
private File configFile, inputFile;
int[] vectorClock;

/*
 * Constructor
 * @param
 * - File config
 * - int line
 * - File input
 * - int clients
 */
public VectorClockClient(File config, int line, File input, int clients) {
    /*
     * Make sure that File handles aren't null and that
     * the line number is valid.
     */
    if (config != null && line >= 0 && input != null) {
        configFile = config;
        inputFile = input;
        clientNumber = line;
        /*
         * Set the array size to the number of lines found in the
         * config file and initialize with zero values.
         */
        vectorClock = new int[clients];
        for (int i = 0; i < vectorClock.length; i++) {
            vectorClock[i] = 0;
        }
    }
}

private int parsePort() {
    int returnable = 0;
    try {
        FileInputStream fstream = new FileInputStream(configFile.getName());
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String strLine = "";
        for (int i = 0; i < clientNumber + 1; i++) {
            strLine = br.readLine();
        }
        String[] tokens = strLine.split(" ");
        returnable = Integer.parseInt(tokens[1]);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("[" + clientNumber + "] returned with " + returnable + ".");
    return returnable;
}

private int parsePort(int client) {
    int returnable = 0;
    try {
        FileInputStream fstream = new FileInputStream(configFile.getName());
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String strLine = "";
        for (int i = 0; i < client; i++) {
            strLine = br.readLine();
        }
        String[] tokens = strLine.split(" ");
        returnable = Integer.parseInt(tokens[1]);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return returnable;
}

private int parseAction(String s) {
    int returnable = -1;
    try {
        FileInputStream fstream = new FileInputStream(configFile.getName());
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String[] tokens = s.split(" ");
        if (!(Integer.parseInt(tokens[0]) == this.clientNumber + 1)) {
            return -1;
        }
        else {
            if (tokens[1].equals("L")) {
                vectorClock[clientNumber] += Integer.parseInt(tokens[2]);
            }
            else {
                returnable = Integer.parseInt(tokens[2]);
            }
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    return returnable;
}

/*
 * Do the actual work.
 */
public void run() {
    try {
        InitClients.barrier.await();
    }
    catch (Exception e) {
        System.out.println(e);
    }
    int port = parsePort();
    String hostname = "localhost";
    String strLine;
    ServerSocketChannel ssc;
    SocketChannel sc;
    FileInputStream fstream;
    DataInputStream in;
    BufferedReader br;
    boolean eof = false;
    try {
        ssc = ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(hostname, port));
        ssc.configureBlocking(false);
        fstream = new FileInputStream("input_vector.txt");
        in = new DataInputStream(fstream);
        br = new BufferedReader(new InputStreamReader(in));

        try {
            InitClients.barrier.await();
        }
        catch (Exception e) {
            System.out.println(e);
        }

        while (true && (eof == false)) {
            sc = ssc.accept();

            if (sc == null) {
                if ((strLine = br.readLine()) != null) {
                    int result = parseAction(strLine);
                    if (result >= 0) {
                        //System.out.println("[" + (clientNumber + 1)
                        //+ "] Send a message to " + result + ".");
                        try {
                            SocketChannel client = SocketChannel.open();
                            client.configureBlocking(true);
                            client.connect(
                                    new InetSocketAddress("localhost",
                                    parsePort(result)));
                            //ByteBuffer buf = ByteBuffer.allocateDirect(32);
                            //buf.put((byte)0xFF);
                            //buf.flip();
                            //vectorClock[clientNumber] += 1;
                            //int numBytesWritten = client.write(buf);
                            String obj = Integer.toString(clientNumber+1);
                            ObjectOutputStream oos = new 
                                    ObjectOutputStream(
                                    client.socket().getOutputStream());
                            oos.writeObject(obj);
                            oos.close();
                        }
                        catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                else {
                    eof = true;
                }
            }
            else {
                ObjectInputStream ois = new 
                        ObjectInputStream(sc.socket().getInputStream());
                String clientNumberString = (String)ois.readObject();
                System.out.println("At {Client[" + (clientNumber + 1)
                        + "]}Incoming connection from: "
                        + sc.socket().getRemoteSocketAddress()
                        + " from {Client[" + clientNumberString + "]}");
                sc.close();
            }
            try {
                InitClients.barrier.await();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    printVector();
}

private void printVector() {
    System.out.print("{Client[" + (clientNumber + 1) + "]}{");
    for (int i = 0; i < vectorClock.length; i++) {
        System.out.print(vectorClock[i] + "\t");
    }
    System.out.println("}");
}

}
Pour clarifier, voici les formats des fichiers utilisés. Config contient des noms d'hôte et des ports utilisés par les clients qui sont des threads et des lignes du fichier d'entrée signifient que "ce client envoie un message à ce client" ou "ce client incréments son horloge logique par une valeur constante".

1 m 2 (m signifie envoyer un message)
2 m 3
3 m 4
2 L 7 (l Horloge d'incrémentation signifie)
2 m 1
...
127.0.0.1 9000
127.0.0.1 9001
127.0.0.1 9002
127.0.0.1 9003
...

Était-ce utile?

La solution

Je regarderais la logique liée au moment où vous vous attendez à une connexion de socket entrante. D'après votre question, il semble que vous vous attendiez à un certain nombre de connexions de socket entrantes (potentiellement une connexion entrante après chaque message sortant?). Étant donné que vous utilisez des E / S non bloquantes sur la prise entrante, il est toujours possible que vos boucles de relevé Whiled avant une prise entrante puissent être établies. En conséquence, un thread pourrait continuer et lire la ligne suivante à partir du fichier sans recevoir de connexion. Étant donné que votre état final est atteint une fois la fin du fichier atteint, il est possible que vous manquiez une connexion de socket entrante.

J'ajouterais des impressions simples qui s'affichent lorsque vous lisez à partir du fichier, lorsque vous envoyez un message et lorsque vous recevez une connexion entrante. Cela devrait vous dire rapidement si un thread particulier manque ou non une connexion entrante attendue. S'il s'avère que le problème est dû aux E / S non bloquantes, vous devrez peut-être désactiver les E / S non bloquantes et continue jusqu'à ce que cet objectif soit atteint.

J'espère que cela t'aides.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top