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

📄 simplegobacknagent.java

📁 The Java Network Simulator is a Java implementation of the ns-2 simulator originally from Berkeley.n
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            return;
        }

        // Create a properly filled out packet
        SimpleGoBackNPacket packet = new SimpleGoBackNPacket();

        // Todo: set sequence numbers+acks properly
        packet.source_port = m_local_port;
        packet.destination_port = m_local_port;
        packet.sequence = m_seq_data++;
        packet.ack = 0;
        packet.flags = 0;
        packet.length = SimpleGoBackNPacket.HEADER_SIZE + length;
        packet.data = data;

        // Put the packet in the send queue
        m_send_array.addElement(packet);
        //      m_sgn.send(m_local_ip,m_remote_ip,length,packet,m_local_port);

        Simulator.getInstance().schedule(new SGNUpdateCommand(
                Simulator.getInstance().getTime() + 0.0001, this));
    }


    public Object read(int unique_id)
    {
        return null;
    }


    /**
     This is an agent that serves the application layer. We will thus always
     allow packets to be sent for convenience and buffer them ourselves.
     @param destination ignored
     @param length ignored
     @return true
     */
    public boolean canSend(IPAddr destination, int length)
    {
        return true;
    }


    /**
     Indicate an event to this agent.
     @see jns.agent.Agent
     */
    public void indicate(int status, Object indicator)
    {
        if(status == Agent.READY_TO_SEND)
        {
            //	System.out.println("         SGN RTS");

            if(m_send_array.size() > 0 && m_window_pos < m_window_size &&
                    m_window_pos < m_send_array.size())
            {
                Simulator.getInstance().schedule(new SGNUpdateCommand(
                        Simulator.getInstance().getTime() + 0.0001, this));
            }
        }
        else if(status == Agent.PACKET_AVAILABLE)
        {

            // Get a packet from the multiplexer

            IPPacket ippacket = (IPPacket) m_sgn.read(m_local_port);
            SimpleGoBackNPacket packet = (SimpleGoBackNPacket) ippacket.data;

            // Treat the packet according to the current state. Note that it is
            // not a terribly good use of ones time to try to understand this
            // piece of code without having the chart of the tcp finite state
            // machine within sight.

            switch(m_state)
            {
                case CLOSED:
                    Simulator.warning("SGN received a packet in the closed" +
                                      " state. Ignored.");
                    break;

                case LISTEN:
                    if(packet.flags == SimpleGoBackNPacket.SYN)
                    {
                        // Extract the port & IP of the sender
                        m_remote_port = packet.source_port;
                        m_remote_ip = ippacket.source;

                        Simulator.verbose("            SGN got SYN in listen");
                        sendPacket(SimpleGoBackNPacket.SYN |
                                   SimpleGoBackNPacket.ACK,
                                   m_seq_data, packet.sequence);
                        m_state = SYN_RECVD;
                    }
                    break;

                case SYN_SENT:
                    if(packet.flags == SimpleGoBackNPacket.SYN)
                    {
                        sendPacket(SimpleGoBackNPacket.SYN |
                                   SimpleGoBackNPacket.ACK, m_seq_data,
                                   packet.sequence);
                        m_state = SYN_RECVD;
                    }
                    else if(packet.flags == (SimpleGoBackNPacket.SYN |
                            SimpleGoBackNPacket.ACK))
                    {
                        sendPacket(SimpleGoBackNPacket.ACK, m_seq_data,
                                   packet.sequence);
                        m_state = ESTABLISHED;
                        m_user.indicate(Agent.CONNECTION_ESTABLISHED, this);
                        Simulator.verbose("            SGN connection established");
                    }
                    break;

                case SYN_RECVD:
                    if(packet.flags == SimpleGoBackNPacket.ACK)
                    {
                        m_state = ESTABLISHED;
                        m_user.indicate(Agent.CONNECTION_ESTABLISHED, this);
                        Simulator.verbose("            SGN connection established");
                    }
                    break;

                case ESTABLISHED:
                    // If it's a FIN packet, send an ACK and go to the next
                    // state.

                    if(packet.flags == SimpleGoBackNPacket.FIN)
                    {
                        sendPacket(SimpleGoBackNPacket.ACK, m_seq_data, 0);
                        m_state = CLOSE_WAIT;
                    }

                    // If it's an ACK for a packet we sent, move the window

                    if(packet.flags == SimpleGoBackNPacket.ACK &&
                            m_send_array.size() > 0)
                    {
                        if(packet.ack == ((SimpleGoBackNPacket)
                                m_send_array.elementAt(0)).sequence)
                        {
                            m_send_array.removeElementAt(0);

                            if(m_window_pos > 0)
                                m_window_pos--;
                        }
                    }

                    // Otherwise we just received some data. Send back an
                    // ACK and stick it in the receive queue

                    if(packet.data != null)
                    {
                        sendPacket(SimpleGoBackNPacket.ACK, m_seq_data,
                                   packet.sequence);
                        m_recv_array.addElement(packet);
                    }
                    break;

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

                case LAST_ACK:
                    if(packet.flags == SimpleGoBackNPacket.ACK)
                        m_state = CLOSED;
                    break;

                case FIN_WAIT1:
                    if(packet.flags == SimpleGoBackNPacket.FIN)
                    {
                        sendPacket(SimpleGoBackNPacket.ACK, m_seq_data,
                                   packet.sequence);
                        m_state = CLOSING;
                    }
                    else if(packet.flags == SimpleGoBackNPacket.ACK)
                    {
                        m_state = FIN_WAIT2;
                    }
                    else if(packet.flags == (SimpleGoBackNPacket.FIN |
                            SimpleGoBackNPacket.ACK))
                    {
                        sendPacket(SimpleGoBackNPacket.ACK, m_seq_data,
                                   packet.sequence);
                        m_state = TIME_WAIT;
                    }
                    break;

                case FIN_WAIT2:
                    if(packet.flags == SimpleGoBackNPacket.FIN)
                        m_state = TIME_WAIT;
                    break;

                case CLOSING:
                    if(packet.flags == SimpleGoBackNPacket.ACK)
                        m_state = TIME_WAIT;
                    break;
            }

        }
    }


    /**
     Internal function to which calls are scheduled with the simulator.
     On each call, update will try to send a packet (if the window size
     and ACKs permit it)
     */
    protected void update()
    {
        if(m_send_array.size() > 0 && m_window_pos < m_window_size &&
                m_window_pos < m_send_array.size())
        {
            SimpleGoBackNPacket packet =
                    (SimpleGoBackNPacket) m_send_array.elementAt(m_window_pos);

            m_sgn.send(m_local_ip, m_remote_ip, packet.length, packet, m_local_port);
            m_window_pos++;
        }
    }

    // ------------- Convenience functions to make life easy -----------

    /**
     sendPacket is used to send control packets (SYN, etc.). Those packets
     contain no data.
     */
    private void sendPacket(int flags, int seq, int ack)
    {

        // Create a properly filled out packet
        SimpleGoBackNPacket packet = new SimpleGoBackNPacket();

        // Todo: set sequence numbers+acks properly
        packet.source_port = m_local_port;
        packet.destination_port = m_remote_port;
        packet.sequence = seq;
        packet.ack = ack;
        packet.flags = flags;
        packet.length = SimpleGoBackNPacket.HEADER_SIZE;
        packet.data = null;

        // Send the packet
        m_sgn.send(m_local_ip, m_remote_ip, packet.length, packet, m_local_port);
    }


}


/**
 A command class that will simply call the update() function of the
 SimpleGoBackNAgent at a specific time.
 */
class SGNUpdateCommand extends Command
{
    SimpleGoBackNAgent m_agent;

    public SGNUpdateCommand(double time, SimpleGoBackNAgent agent)
    {
        super("SGN update", time);
        m_agent = agent;
    }

    public void execute()
    {
        m_agent.update();
    }
}

⌨️ 快捷键说明

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