src/SftpServer.java
private static byte[] receiveDataPacket(DatagramSocket socket, DatagramPacket packet, byte seq)
            throws IOException, InterruptedException, IllegalStateException {
        // Receive a new packet from client
        socket.receive(packet);
        byte[] receivedData = packet.getData();
        if (DEBUG) System.out.println("Packet " + (++packet_count) + " received, size = " + (packet.getLength() - 1));

        Random random = new Random();
        // Simulate Packet Loss
        if (random.nextDouble() < LOSS_RATE) throw new IllegalStateException("Reply ACK not sent.");

        // Simulate network delay
        Thread.sleep((int) (random.nextDouble() * 2 * AVERAGE_DELAY));

        // Send ACK
        DatagramPacket transmitAck = new DatagramPacket(new byte[] {seq}, 1, packet.getSocketAddress());
        socket.send(transmitAck);

        // check sequence number, invalid data if incorrect seq number
        if (seq != receivedData[0]) {
            // Out-of-order Packet Received
            throw new IllegalStateException("Out-of-order Packet Received.");
        }

        // Extract actual file data and return
        byte[] data = new byte[packet.getLength() - 1];
        System.arraycopy(receivedData, 1, data, 0, data.length);
        return data;
    }
/**
     * Receive a data packet from designated socket and expected sequence number.
     * Packet Loss is simulated by intentionally not replying to received packets with a rate of {@value LOSS_RATE}.
     * A random network delay is added before sending ACK packets, the delay has an average of {@value AVERAGE_DELAY} ms.
     * @param socket UDP socket which the program listens to
     * @param packet Data packet to be received
     * @param seq Expected sequence number
     * @return Extracted data from packet (without sequence number byte)
     * @throws IOException Receiving and sending packets in socket produces this Exception
     * @throws InterruptedException Thread.sleep() produces this Exception
     * @throws IllegalStateException when packet is dropped intentionally and out-of-order packet is received
     */
Receive a data packet from designated socket and expected sequence number.
Packet Loss is simulated by intentionally not replying to received packets with a rate of  LOSS_RATE.
A random network delay is added before sending ACK packets, the delay has an average of  AVERAGE_DELAY ms.
Receive a data packet from designated socket and expected sequence number . Packet Loss is simulated by intentionally not replying to received packets with a rate of LOSS_RATE . A random network delay is added before sending ACK packets the delay has an average of AVERAGE_DELAY ms .
private static byte[] receiveDataPacket(DatagramSocket socket, DatagramPacket packet, byte seq)
            throws IOException, InterruptedException, IllegalStateException {
        socket.receive(packet);
        byte[] receivedData = packet.getData();
        if (DEBUG) System.out.println("Packet " + (++packet_count) + " received, size = " + (packet.getLength() - 1));
        Random random = new Random();
        if (random.nextDouble() < LOSS_RATE) throw new IllegalStateException("Reply ACK not sent.");
        Thread.sleep((int) (random.nextDouble() * 2 * AVERAGE_DELAY));
        DatagramPacket transmitAck = new DatagramPacket(new byte[] {seq}, 1, packet.getSocketAddress());
        socket.send(transmitAck);
        if (seq != receivedData[0]) {
            throw new IllegalStateException("Out-of-order Packet Received.");
        }
        byte[] data = new byte[packet.getLength() - 1];
        System.arraycopy(receivedData, 1, data, 0, data.length);
        return data;
    }
private static byte [ ] receiveDataPacket ( DatagramSocket socket , DatagramPacket packet , byte seq ) throws IOException , InterruptedException , IllegalStateException { socket . receive ( packet ) ; byte [ ] receivedData = packet . getData ( ) ; if ( DEBUG ) System . out . println ( "Packet " + ( ++ packet_count ) + " received, size = " + ( packet . getLength ( ) - 1 ) ) ; Random random = new Random ( ) ; if ( random . nextDouble ( ) < LOSS_RATE ) throw new IllegalStateException ( "Reply ACK not sent." ) ; Thread . sleep ( ( int ) ( random . nextDouble ( ) * 2 * AVERAGE_DELAY ) ) ; DatagramPacket transmitAck = new DatagramPacket ( new byte [ ] { seq } , 1 , packet . getSocketAddress ( ) ) ; socket . send ( transmitAck ) ; if ( seq != receivedData [ 0 ] ) { throw new IllegalStateException ( "Out-of-order Packet Received." ) ; } byte [ ] data = new byte [ packet . getLength ( ) - 1 ] ; System . arraycopy ( receivedData , 1 , data , 0 , data . length ) ; return data ; }
Receive a data packet from designated socket and expected sequence number.
Receive a data packet from designated socket and expected sequence number .
// Receive a new packet from client // Simulate Packet Loss // Simulate network delay // Send ACK // check sequence number, invalid data if incorrect seq number // Out-of-order Packet Received // Extract actual file data and return