Esempio n. 1
0
    // Use this for initialization
    public static void Main(String[] args)
    {
        // 83 is the base size (in bytes) of a serialized RDTPacket object
        byte[] receivedData = new byte[Sender.MSS + 83];

        int waitingFor            = 0;
        List <RDTPacket> received = new List <RDTPacket>();
        bool             end      = false;
        //
        UdpClient fromSender = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.1.15"), 8080));

        while (!end)
        {
            Console.WriteLine("Waiting for packet");

            // Receive packet
            IPEndPoint receivedPacket = new IPEndPoint(IPAddress.Parse("192.168.1.15"), 9876);

            byte [] bytes = fromSender.Receive(ref receivedPacket);


            // Unserialize to a RDTPacket object
            RDTPacket packet = (RDTPacket)BinaryFormat.Deserialize(bytes);

            Console.WriteLine("Packet with sequence number " + packet.getSeq() + " received (last: " + packet.isLast() + " )");

            if (packet.getSeq() == waitingFor && packet.isLast())
            {
                waitingFor++;
                received.Add(packet);

                Console.WriteLine("Last packet received");

                end = true;
            }
            else if (packet.getSeq() == waitingFor)
            {
                waitingFor++;
                received.Add(packet);
                Console.WriteLine("Packed stored in buffer");
            }
            else
            {
                Console.WriteLine("Packet discarded (not in order)");
            }

            // Create an RDTAck object
            RDTAck ackObject = new RDTAck(packet.getSeq());

            // Serialize
            byte[] ackBytes = BinaryFormat.Serialize(ackObject);


            IPEndPoint ackPacket = new IPEndPoint(IPAddress.Parse("192.168.1.15"), 9876);

            // Send with some probability of loss
            Random rand = new Random();
            if (rand.Next(2, 3) > PROBABILITY)
            {
                fromSender.Send(ackBytes, ackBytes.Length, ackPacket);
            }
            else
            {
                Console.WriteLine("[X] Lost ack with sequence number " + ackObject.getPacket());
            }

            Console.WriteLine("Sending ACK to seq " + packet.getSeq() + " with " + ackBytes.Length + " bytes");
        }

        Console.ReadKey();
    }
Esempio n. 2
0
    // Use this for initialization
    public static void Main(String[] args)
    {
        int lastSent      = 0;
        int waitingForAck = 0;

        byte[] fileBytes = System.Text.Encoding.Default.GetBytes("ABCDEFGHIJKLMNOPQRSTUVXZ");
        Console.WriteLine("Data size: " + fileBytes.Length + " bytes");
        int lastSeq = (int)Math.Ceiling((double)fileBytes.Length / MSS) - 1;// lastSent 从 0 开始 标记,这里要减去 1

        Console.WriteLine("Number of packets to send: " + lastSeq);
        string      HostName        = Dns.GetHostName(); //得到主机名
        IPHostEntry IpEntry         = Dns.GetHostEntry(HostName);
        IPAddress   receiverAddress = null;

        for (int i = 0; i < IpEntry.AddressList.Length; i++)
        {
            //从IP地址列表中筛选出IPv4类型的IP地址
            //AddressFamily.InterNetwork表示此IP为IPv4,
            //AddressFamily.InterNetworkV6表示此地址为IPv6类型
            if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
            {
                receiverAddress = IpEntry.AddressList[i];
                break;
            }
        }

        UdpClient toReceiver = new UdpClient(9876, AddressFamily.InterNetwork);

        List <RDTPacket> sent = new List <RDTPacket>();

        while (true)
        {
            // Sending loop
            while (lastSent - waitingForAck < WINDOW_SIZE && lastSent < lastSeq)
            {
                // Array to store part of the bytes to send
                byte[] filePacketBytes = new byte[MSS];

                // Copy segment of data bytes to array
                Array.Copy(fileBytes, lastSent * MSS, filePacketBytes, 0, MSS);

                // Create RDTPacket object
                RDTPacket rdtPacketObject = new RDTPacket(lastSent, filePacketBytes, (lastSent == lastSeq - 1) ? true : false);

                // Serialize the RDTPacket object
                byte[] sendData = BinaryFormat.Serialize(rdtPacketObject);

                Console.WriteLine("Sending packet with sequence number " + lastSent + " and size " + sendData.Length + " bytes");

                // Add packet to the sent list
                sent.Add(rdtPacketObject);

                // Send with some probability of loss

                Random rand = new Random();
                int    num  = rand.Next(0, 2);
                if (num > PROBABILITY)
                {
                    IPEndPoint IPPoint = new IPEndPoint(receiverAddress, 8080);
                    toReceiver.Send(sendData, sendData.Length, IPPoint);
                }
                else
                {
                    Console.WriteLine("[X] Lost packet with sequence number " + lastSent);
                }

                // Increase the last sent
                lastSent++;
            } // End of sending while

            // Byte array for the ACK sent by the receiver
            byte[] ackBytes = new byte[40];

            // Creating packet for the ACK
            IPEndPoint ack = new IPEndPoint(IPAddress.Any, 0);
            try
            {
                // If an ACK was not received in the time specified (continues on the catch clausule)
                toReceiver.Client.ReceiveTimeout = TIMER;
                // Receive the packet
                byte[] bytes = toReceiver.Receive(ref ack);


                // Unserialize the RDTAck object

                RDTAck ackObject = (RDTAck)BinaryFormat.Deserialize(bytes);

                Console.WriteLine("Received ACK for " + ackObject.getPacket());

                // If this ack is for the last packet, stop the sender (Note: gbn has a cumulative acking)
                if (ackObject.getPacket() == lastSeq)
                {
                    break;
                    //return;
                }

                waitingForAck = Math.Max(waitingForAck, ackObject.getPacket());
            }
            catch (SocketException e)
            {
                // then send all the sent but non-acked packets

                for (int i = waitingForAck; i < lastSent; i++)
                {
                    // Serialize the RDTPacket object
                    byte[] sendData = BinaryFormat.Serialize(sent[i]);

                    // Create the packet
                    IPEndPoint packet = new IPEndPoint(receiverAddress, 8080);

                    // Send with some probability
                    Random rand = new Random();
                    if (rand.Next(2, 5) > PROBABILITY)
                    {
                        toReceiver.Send(sendData, sendData.Length, packet);
                    }
                    else
                    {
                        Console.WriteLine("[X_Resending] Lost packet with sequence number " + sent[i].getSeq());
                    }

                    Console.WriteLine("REsending packet with sequence number " + sent[i].getSeq() + " and size " + sendData.Length + " bytes");
                }
            }
        }

        Console.ReadKey();
    }