Le Coin Wiki
d'Olivier Dalle
$WikiTagline
 

L’objectif de ce TP est de modéliser le protocole d’établissement d’une connexion TCP.

Ce TP se deroulera en deux parties comptant chacune pour moitié de la note: d’abord la modélisation d’un lien et ensuite la modélisation des deux automates TCP qui cherchent a établir la connexion et l’assemblage (couplage) d’un exemple.

Modélisation d’un lien

Pour modéliser un objet il faut bien comprendre comment il marche!

Commencez par vous renseigner sur les notions de délais de transmission, délai de propagation, bande passante et trouvez une expression pour calculer le délai de livraison d’un paquet (delivery time) en fonction de la bande passante et du délai de propagation du lien.

Considérez ensuite le schéma suivant et déterminez s’il permet de répondre au besoin ou de quelle façon vous devriez éventuellement l’adapter à vos besoins.

Passez ensuite à l’implémentation.

Pour vous aider, voici la correction du DEVS que vous aviez à faire lors du dernier TP:

/**
 * Cours Simulation et Modele Discret
 *
 * (c) 2016 Université Nice Sophia Antipolis
 *
 * Author: O. Dalle
 * email: olivier.dalle@unice.fr
 */


package TCP;

import genDevs.modeling.message;
import GenCol.entity;
import simView.ViewableAtomic;


/**
 * A processor in which the processing time is associated
 * with each job instead of being fixed with the processor.
 *
 * <p> The job received on the input port are given in job
 * format.
 *
 * <p> An input in job format is a two-compounds string with
 * colon separator in which the first compound is a string id
 * and the second is a floating point value representing a
 * duration in seconds.
 * <p> Examples:  "SYN-14:4e-5" or "xyzt:1.2742734"
 *
 * @author odalle
 *
 */

public class TimedProc extends ViewableAtomic {

    // Avoid inlined constants using static finals
    public static final entity NONE_ENTITY = new entity("none");
    public static final String PASSIVE_PHASE = "passive";
    public static final String BUSY_PHASE = "busy";
    public static final String IN_PORT = "in";
    public static final String OUT_PORT = "out";

    protected entity job_;
    protected double processing_time_=0.0;

    public TimedProc() {
        this("timedProc");
    }

    public static entity makeTimedEntity(String name, float time) {
        return new entity(name+":"+time);
    }

    protected static final String [] entitySplit(entity ent) {
        return ent.getName().split(":");
    }

    public TimedProc(String name) {
        super(name);
        addInport(IN_PORT);
        addOutport(OUT_PORT);

        addTestInput(IN_PORT, makeTimedEntity("job1",3.5F));
        addTestInput(IN_PORT, makeTimedEntity("job2",12.7F), 5);
        addTestInput(IN_PORT, makeTimedEntity("job",3.8F), 20);


    }

    public void initialize() {
        phase = PASSIVE_PHASE;
        sigma = INFINITY;
        job_ = NONE_ENTITY;
        super.initialize();
    }

    public void deltext(double e, message x) {
        // If a delay was already scheduled, decrement elapsed time
        Continue(e);

        if (phaseIs(PASSIVE_PHASE)) {
            for (int i = 0; i < x.getLength(); i++) {
                // If multiple jobs are received simultaneously, only last one counts.
                if (messageOnPort(x, "in", i)) {
                    job_ = x.getValOnPort("in", i);
                    processing_time_ = Float.parseFloat(entitySplit(job_)[1]);
                    holdIn(BUSY_PHASE, processing_time_);
                }
            }
        }
    }

    public void deltint() {
        job_ = NONE_ENTITY;
        passivate();
    }

    public void deltcon(double e, message x) {
        deltint();
        deltext(0, x);
    }

    public message out() {

        message m = new message();
        if (phaseIs(BUSY_PHASE)) {
            m.add(makeContent(OUT_PORT, job_));
        }
        return m;
    }

    public String getTooltipText() {
        return super.getTooltipText() + "\n" + "job: " + job_.getName();
    }
}

Et pour vous aider encore un peu, voici une version “a trous” du DEVS Translator:

/**
 * Cours Simulation et Modele Discret
 *
 * (c) 2016 Université Nice Sophia Antipolis
 *
 * Author: O. Dalle
 * email: olivier.dalle@unice.fr
 */


package TCP;

import genDevs.modeling.message;

import java.util.LinkedList;
import java.util.List;

import GenCol.entity;
import simView.ViewableAtomic;


/**
 * A translator from packet format to job format and conversely.
 *
 * <p> An input in packet format is a two-compounds string with
 * colon separator in which the first compound is a string id and
 * the second is a integer value representing the packet length in
 * bytes.
 * <p> Examples:  "SYN-14:40" or "foobar:324"
 *
 * <p> An input in job format is a two-compounds string with colon
 * separator in which the first compound is a string id and the
 * second is a floating point value representing a duration in seconds.
 * <p> Examples:  "SYN-14:4e-5" or "xyzt:1.2742734"
 *
 *
 * @author odalle
 *
 */

public class Translator extends ViewableAtomic {

    // Avoid inlined constants using static finals
    public static final entity NONE_ENTITY = new entity("none");
    public static final String PASSIVE_PHASE = "passive";
    public static final String JOB_PHASE = "jobPhase";
    public static final String OUT_PHASE = "donePhase";
    public static final String JOB_AND_OUT_PHASE = "jobAndOutPhase";
    public static final String JOB_PORT = "job";
    public static final String DONE_PORT = "done";
    public static final String IN_PORT = "in";
    public static final String OUT_PORT = "out";

    // A counter to generate unique ids, initialized to any value
    public static int counter_ = 123;

    protected List<entity> inputList_ = new LinkedList<entity>();

    protected entity inPkt_;
    protected entity donePkt_;
    protected double propagation_delay_;
    protected double bandwidth_;

    /**
     * A default constructor with pre-set bandwidth and propagation
     * delay (1 mbps, 10ms)
     */

    public Translator() {
        this("translator", 1e6, 1e-2);
    }

    /**
     * Constructor
     *
     * @param name
     *      Name of this DEVS
     * @param bandwidth
     *      Bandwidth, unit=bps (bit per second)
     * @param propagation_delay
     *      Proagation delay, unit=s (seconds)
     */

    public Translator(String name, double bandwidth, double propagation_delay) {
        super(name);
        propagation_delay_ = propagation_delay;
        bandwidth_ = bandwidth;
        inPkt_ = donePkt_ = NONE_ENTITY;

        // AJOUTER DES PORTS

        // AJOUTER DES ENTREE DE TEST

    }

    public void initialize() {
        phase = PASSIVE_PHASE;
        sigma = INFINITY;
        super.initialize();
    }


    protected static final String [] entitySplit(entity ent) {
        return ent.getName().split(":");
    }

    public void deltext(double e, message x) {
        // If a delay was already scheduled, decrement elapsed time
        Continue(e);

        for (int i = 0; i < x.getLength(); i++) {

            // Receiving a message "pktid:size" on in port
            if (messageOnPort(x, IN_PORT, i)) {
                entity val = x.getValOnPort(IN_PORT, i);
                String fields[] = entitySplit(val);

                String pktId = fields[0];
                int pktLen = Integer.parseInt(fields[1]);

                double transmission_time= ?? // A COMPLETER

                // Prepare output of new job
                inPkt_  = new entity(pktId + ":"+ transmission_time);

                // Save original input for identical output when
                // job is done
                inputList_.add(val);

                // trigger output(s) immediately
                if (phaseIs(OUT_PHASE))
                    // A COMPLETER
                else
                    // A COMPLETER
            }

            // Receiving a "jobid:delay" on done port
            if (messageOnPort(x, DONE_PORT, i)) {

                // Retrieve saved input at head of list
                try {
                    donePkt_ = inputList_.remove(0);
                } catch (IndexOutOfBoundsException ioobe) {
                    throw new RuntimeException(
                            "Done event received but input list is empty!",
                            ioobe);
                }

                // trigger output(s) immediately
                if (phaseIs(JOB_PHASE))
                    // A COMPLETER
                else
                    // A COMPLETER
            }
        }
    }

    public void deltint() {

        if (phaseIs(JOB_PHASE) || phaseIs(JOB_AND_OUT_PHASE))
            inPkt_ = NONE_ENTITY;
        // A COMPLETER

        // return to PASSIVE_PHASE
        passivate();
    }

    public void deltcon(double e, message x) {
        deltint();
        deltext(0, x);
    }

    public message out() {
        message m = new message();

        // Output pending message on corresponding port
        if (phaseIs(JOB_PHASE) || phaseIs(JOB_AND_OUT_PHASE)) {
            m.add(makeContent(JOB_PORT, inPkt_));
        }

        if (phaseIs(OUT_PHASE) || phaseIs(JOB_AND_OUT_PHASE)) {
            // A COMPLETER
        }
        return m;
    }

    public String getTooltipText() {
        return super.getTooltipText() + "\n" + "inPkt: " + inPkt_.getName()
                + "\n" + "donePkt: " + donePkt_.getName();
    }
}

Modélisation de l’automate TCP

Vous trouverez ici un schéma représentant le fonctionnement d’une connexion TCP:

https://upload.wikimedia.org/wikipedia/commons/f/f6/Tcp_state_diagram_fixed_new.svg

Dans cet exercice nous allons nous contenter de la partie concernant l’établissement de la connexion, appelée three-way-handshake (poignée de main en trois temps).

Une simulation complète

Construisez une simulation complète avec 2 agents TCP reliés par un lien et suivez son exécution pas à pas pour vérifiez qu’elle suit bien les étapes du protocole TCP.