⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplegobacknagent.java

📁 The Java Network Simulator is a Java implementation of the ns-2 simulator originally from Berkeley.n
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
TODO:
   - Data transfer
   - Timeouts, timeouts, timeouts..
 */
package jns.agent;

import jns.Simulator;
import jns.command.Command;
import jns.element.IPPacket;
import jns.util.IPAddr;

import java.util.Vector;

/**
 This is a (reasonably) simple protocol implementation that uses a
 'go-back-n' strategy for providing a error-correcting connection-oriented
 service. If an acknowledgement does not arrive in time, all packets from
 that ACK on are sent again. This particular implementation actually
 provides a two-way service, data transfer in both directions.
 <p>
 In order to handle connection setup and teardown properly, I chose to use
 the TCP finite state machine. The state machine is implemented by having
 the current state in a variable and acting depending on the value of this
 variable in the different functions.
 <p>
 For an overview of the TCP finite state machine, please refer to the
 "Internetworking with TCP/IP" book series. You can find the diagram both
 in Volume I ("Principles, Protocols and Architectures") and Volume II
 ("Design, Implementation and Internals"). In any case, every good TCP/IP
 book should have the finite state machine in it.
 <p>

 There are some <b>missing features</b>:
 <ul>
 <li>No timeouts. If packets are lost, this protocol will go awry. This is
 because there was no time to finish the class
 <li>The same is true for out-of-sequence delivery. Things will go awry.
 <li>The window size is hardcoded to four.
 </ul>

 <p>
 Nevertheless, this protocol should give you a clue as to how agents can be
 written in JNS.
 */
public class SimpleGoBackNAgent implements CO_Agent
{

    // Define constants for the states this protocol can be in. This defines
    // the TCP finite state machine

    // Waiting in idleness...
    private final static int CLOSED = 1;

    // Passive open, waiting for SYNs (in TCP speak anyway..)
    private final static int LISTEN = 2;

    // Active open. We have just sent a SYN and are waiting for a SYN+ACK.
    private final static int SYN_SENT = 3;

    // In passive mode, if we receive a SYN we go to this state.
    private final static int SYN_RECVD = 4;

    // We are connected if we are in this state.
    private final static int ESTABLISHED = 5;

    // If we receive a FIN in the ESTABLISHED state we go to this state
    private final static int CLOSE_WAIT = 6;

    // After leaving CLOSE_WAIT, we send an ACK and go to this state. If we
    // receive it, we leave this state and go to CLOSED again.
    private final static int LAST_ACK = 7;

    // When we are actively ending a connection, we send a FIN and go from
    // ESTABLISHED (or SYN_RECVD) to this state.
    private final static int FIN_WAIT1 = 8;

    // If we receive an ACK in FIN_WAIT1, we go to FIN_WAIT2.
    private final static int FIN_WAIT2 = 9;

    // If we received a FIN in FIN_WAIT1, we send an ACK and go to this state
    private final static int CLOSING = 10;

    // From CLOSING, if we get an ACK and from FIN_WAIT2 if we get a FIN, we
    // go to this state. We wait in there for a while and go back to CLOSED.
    private final static int TIME_WAIT = 11;

    // The local port of this connection and the remote port
    private int m_local_port;
    private int m_remote_port;

    // Our IP address and the remote end IP address
    private IPAddr m_local_ip;
    private IPAddr m_remote_ip;

    // The agent we are using for sending packets.
    private SimpleGoBackN m_sgn;

    // The current state we are in, one of the constants above.
    private int m_state;

    // The agent that is using us to send packets
    private Agent m_user;

    // Current data sequence number
    private int m_seq_data;

    // Current acknowledgement sequence number
    private int m_seq_ack;

    private Vector m_send_array;
    private Vector m_recv_array;

    private int m_window_pos;
    private int m_window_size;

    /**
     The only constructor, creates a new agent at a specific local port. This
     constructor is private to the outside world. If you want a new agent,
     use jns.agent.SimpleGoBackN.createNewAgent. This function will also
     take care of attaching everything correctly.
     */
    protected SimpleGoBackNAgent(int port)
    {
        m_local_port = port;
        m_remote_port = 0;
        m_sgn = null;
        m_user = null;
        m_local_ip = m_remote_ip = null;
        m_state = CLOSED;
        m_seq_data = 0;
        m_seq_ack = 0;

        m_send_array = new Vector();
        m_recv_array = new Vector();

        m_window_pos = 0;
        m_window_size = 4;
    }


    /**
     Attach an application layer agent to this agent.
     @param higher_level the agent to attach
     @param unique_id an id that will identify the agent
     @see jns.agent.Agent
     */
    public void attach(Agent higher_level, int unique_id)
    {
        m_user = higher_level;

        m_user.attach(this);
    }


    /**
     Callback function by which lower-level agents attach themselves to this
     agent.
     @see jns.agent.Agent
     */
    public void attach(Agent lower_level)
    {
        if(!(lower_level instanceof SimpleGoBackN))
            Simulator.error("You may attach SimpleGoBackNAgent only to " +
                            "SimpleGoBackN");

        m_sgn = (SimpleGoBackN) lower_level;
    }


    /**
     Set up a connection with a remote host. All the details can be found
     in the CO_Agent class. Calling this function initiates a three-way
     handshake. Note that it takes some time to do the handshake.
     @see jns.agent.CO_Agent
     */
    public void connect(IPAddr source, IPAddr destination,
                        int destination_port)
    {
        if(m_state != CLOSED)
        {
            Simulator.warning("Call to SGN connect() ignored because the protocol" +
                              " was not in the idle state");
            return;
        }

        // Set up our connection variables

        m_local_ip = source;
        m_remote_ip = destination;
        m_remote_port = destination_port;

        Simulator.verbose("            SGN sending SYN");

        // Send a SYN packet to the destination

        sendPacket(SimpleGoBackNPacket.SYN, m_seq_data, 0);

        // Go to the new state, SYN_SENT

        m_state = SYN_SENT;
    }


    /**
     Break up a connection. This causes FIN packets to be sent and
     connection-teardown to be initialised. Note that it will take some
     time to tear down a connection.
     */
    public void disconnect()
    {

        // Act according to the current state
        Simulator.verbose("            disconnecting");

        switch(m_state)
        {
            case LISTEN:
            case SYN_SENT:
                m_state = CLOSED;
                break;

            case CLOSE_WAIT:
                m_state = LAST_ACK;
                sendPacket(SimpleGoBackNPacket.FIN, m_seq_data,
                           0);
                break;

            case ESTABLISHED:
            case SYN_RECVD:
                m_state = FIN_WAIT1;
                sendPacket(SimpleGoBackNPacket.FIN, m_seq_data, 0);
                break;

            default:
                Simulator.warning("Disconnect already in progress " +
                                  "when called in SGN");
        }
    }


    /**
     Start listening at a specific IP address. The port to listen at has
     already been specified when the agent was created.
     @param local_ip the IP address to listen at
     @see jns.agent.CO_Agent
     */
    public void listen(IPAddr local_ip)
    {
        if(m_state != CLOSED)
        {
            Simulator.warning("Call to SGN listen() ignored because the protocol " +
                              "was not in the idle state");
            return;
        }

        Simulator.verbose("            SGN listening");

        m_local_ip = local_ip;

        // This one is easy...

        m_state = LISTEN;
    }


    public void send(int length, Object data, int unique_id)
    {
        if(m_state != ESTABLISHED)
        {
            Simulator.warning("Tried to send a packet using SGN without setting " +
                              "up a connection first. Packet LOST!");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -