public static void startListenOnSocketAsync(Socket socket, ReceivedPacketCallback callbackLambda)
        {
            UDPListener udpl = delegate()
            {
                try
                {
                    while (true)
                    {
                        IPEndPoint sender             = new IPEndPoint(IPAddress.Any, 0);
                        EndPoint   Remote             = (EndPoint)sender;
                        byte[]     receive_byte_array = new byte[1399];
                        socket.ReceiveFrom(receive_byte_array, ref Remote);
                        sender = (IPEndPoint)Remote;

                        callbackLambda(TCPCopycatPacket.parse(receive_byte_array), sender);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            };
            Task taskA = new Task(() => udpl());

            taskA.Start();
        }
        public void ClientSocketReceivedPacketCallback(TCPCopycatPacket packet, IPEndPoint sender)
        {
            Console.WriteLine("Received Packet numbered: " + packet.header.sequenceNumber.ToString());

            if (!packetReceived[GetClientSocketFromEndpoint(sender)].Contains(packet.header.sequenceNumber))
            {
                if (packet.header.FIN == 1)
                {
                    Console.WriteLine("Packet FIN received");
                }
                filePacketList[GetClientSocketFromEndpoint(sender)].Add(packet);
                packetReceived[GetClientSocketFromEndpoint(sender)].Add(packet.header.sequenceNumber);
            }

            packet.header.acknowledgeNumber = packet.header.sequenceNumber + 1;
            TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);

            /*
             * if (packet.header.acknowledgeNumber == 30)
             * {
             *  Console.WriteLine("********** SENDING MULTIPLE TIME SAME PACKET *************");
             *  latency(250, 1251);
             *  TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);
             *  latency(250, 1251);
             *  TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);
             *  latency(250, 1251);
             *  TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);
             * }*/
            /*
             * if (packet.header.acknowledgeNumber != 28)
             * {
             *  TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);
             * }
             * if (packet.header.acknowledgeNumber == 31)
             * {
             *  Console.WriteLine("*** GoingTo send packet 30 ack ***");
             *  Thread.Sleep(10000);
             *  packet.header.acknowledgeNumber = 28;
             *  TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);
             *  Console.WriteLine("*** SENT PACKET ***");
             * }
             */
            if (packet.header.FIN == 1)
            {
                filePacketList[GetClientSocketFromEndpoint(sender)].Sort(delegate(TCPCopycatPacket a, TCPCopycatPacket b)
                {
                    if (a.header.sequenceNumber < b.header.sequenceNumber)
                    {
                        return(-1);
                    }
                    return(1);
                });

                TCPCopycatPacketManager.TCPCopycatPacketArrayToFile(@"./" + sender.Port.ToString(), filePacketList[GetClientSocketFromEndpoint(sender)].ToArray());
            }
        }
        private void registerPacket(TCPCopycatPacket packet, TCPCopycatReceiveMessageCallback lambda, int waitTime)
        {
            if (waitTime < 0)
            {
                throw new Exception("waitTime must be positive");
            }

            //Console.WriteLine("registering packet: " + packet.header.sequenceNumber);
            if (dictionaryRegisteredPacket.ContainsKey(packet.header.sequenceNumber + 1))
            {
                dictionaryRegisteredPacket[packet.header.sequenceNumber + 1] = lambda;
            }
            else
            {
                dictionaryRegisteredPacket.Add(packet.header.sequenceNumber + 1, lambda);
            }
            //Console.WriteLine(dictionaryRegisteredPacket.Count.ToString() + " packets registered");


            setPacketResponse(packet.header.sequenceNumber + 1, TCPCopyCatController.responseCode.NONE);

            ElapsedEventHandler timerCallbackLambda = delegate(object state, System.Timers.ElapsedEventArgs e)
            {
                TaskTimer        t                 = (TaskTimer)state;
                TCPCopycatPacket packetToSend      = t.packetToSend;
                TCPCopycatReceiveMessageCallback l = t.lambda;
                int w = t.waitTime;
                t.Dispose();
                if (dictionaryRegisteredPacketResponse[packetToSend.header.sequenceNumber + 1] == TCPCopyCatController.responseCode.OK) //unregister timer is called before the timer is even initialized
                {
                    return;
                }
                Console.WriteLine("packet: " + packetToSend.header.sequenceNumber.ToString() + " lost");
                unregisterPacket(packetToSend.header.sequenceNumber + 1);
                setPacketResponse(packetToSend.header.sequenceNumber + 1, TCPCopyCatController.responseCode.NONE);
                TCPCopyCatController.sendMessageToEndPoint(socket, serverEndpoint, packetToSend);
                registerPacket(packetToSend, l, w);
            };


            TaskTimer timer = new TaskTimer();

            timer.Interval  = waitTime;                                                   // set the interval as 10000 ms
            timer.Elapsed  += new System.Timers.ElapsedEventHandler(timerCallbackLambda); // set the event to execute
            timer.AutoReset = false;                                                      // false: only execute once
            timer.Enabled   = true;                                                       // to decide if execute the event of timer specified

            timer.packetToSend = packet;
            timer.lambda       = lambda;
            timer.waitTime     = waitTime;


            registerTimer(packet.header.sequenceNumber + 1, timer);
        }
        public async Task <TCPCopyCatController.responseCode> connectToServer(IPEndPoint serverEndpoint)
        {
            const int connectionSequenceNumber = 0;

            if (socket == null)
            {
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            }
            else if (socket.IsBound)
            {
                return(await getPacketResponse(connectionSequenceNumber + 1));
            }
            TCPCopyCatController.startListenOnSocketAsync(socket, onPacketReceive);

            IPEndPoint test = new IPEndPoint(IPAddress.Any, 0);

            socket.Bind(test);

            this.serverEndpoint = serverEndpoint;

            TCPCopycatPacket.TCPCopycatHeader header = new TCPCopycatPacket.TCPCopycatHeader();

            header.SYN            = 1;
            header.sequenceNumber = connectionSequenceNumber;
            header.ACK            = 0;
            header.dataLenght     = 0;

            TCPCopycatPacket connectionPacket = new TCPCopycatPacket(header, new byte[1]);

            TCPCopycatReceiveMessageCallback receivedMessageCallbackLambda = delegate(TCPCopycatPacket packet, IPEndPoint sender)
            {
                if (packet.header.SYN == 1 && packet.header.acknowledgeNumber == (connectionSequenceNumber + 1))
                {
                    this.serverEndpoint = sender;
                    return(TCPCopyCatController.responseCode.OK);
                }
                return(TCPCopyCatController.responseCode.UNKNOWN_ERROR);
            };



            if (!TCPCopyCatController.sendMessageToEndPoint(socket, serverEndpoint, connectionPacket))
            {
                registerPacket(connectionPacket, receivedMessageCallbackLambda, 1000);
                return(await getPacketResponse(connectionSequenceNumber + 1));
            }
            else
            {
                return(TCPCopyCatController.responseCode.BAD_REQUEST);
            }
        }
 public void onPacketReceive(TCPCopycatPacket packet, IPEndPoint sender)
 {
     Console.WriteLine("---Received packet number: " + (packet.header.acknowledgeNumber - 1).ToString());
     if (dictionaryRegisteredPacket.ContainsKey(packet.header.acknowledgeNumber))
     {
         dictionaryRegisteredPacketResponse[packet.header.acknowledgeNumber] = dictionaryRegisteredPacket[packet.header.acknowledgeNumber](packet, sender);
         unregisterPacket(packet.header.acknowledgeNumber);
         Console.WriteLine("Response: " + dictionaryRegisteredPacketResponse[packet.header.acknowledgeNumber].ToString());
     }
     else
     {
         Console.WriteLine("************** Already received packet " + (packet.header.sequenceNumber).ToString() + " ***********");
     }
 }
        public void ServerReceivedPacketCallback(TCPCopycatPacket packet, IPEndPoint sender)
        {
            Console.WriteLine("Received new connection from " + sender.Address + " port: " + sender.Port);

            clientSockets.Add(sender, new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp));
            IPEndPoint qwe = new IPEndPoint(IPAddress.Any, 0);

            clientSockets[sender].Bind(qwe);
            packetReceived.Add(GetClientSocketFromEndpoint(sender), new HashSet <int>());
            filePacketList.Add(GetClientSocketFromEndpoint(sender), new List <TCPCopycatPacket>());
            Console.WriteLine("Client socket listening on port: " + sender.Port.ToString());
            TCPCopyCatController.startListenOnSocketAsync(GetClientSocketFromEndpoint(sender), ClientSocketReceivedPacketCallback);
            packet.header.acknowledgeNumber = packet.header.sequenceNumber + 1;
            TCPCopyCatController.sendMessageToEndPoint(GetClientSocketFromEndpoint(sender), sender, packet);
        }
        public void sendFilePacket(TCPCopycatPacket packet)
        {
            if (packet == null)
            {
                return;
            }

            if (packet.header.sequenceNumber == filePackets[filePackets.Length - 1].header.sequenceNumber)
            {
                packet.header.FIN = 1;
            }

            packet.header.sequenceNumber += sequenceNumberOffset;

            TCPCopycatReceiveMessageCallback receivedMessageCallbackLambda = delegate(TCPCopycatPacket _packet, IPEndPoint sender)
            {
                unregisterPacket(_packet.header.acknowledgeNumber);
                setPacketResponse(_packet.header.acknowledgeNumber, TCPCopyCatController.responseCode.OK);

                // this ensure we only send 10 files at a time and also respect the selective repeat structure
                if (_packet.header.sequenceNumber < windowLowerbound)
                {
                    Console.WriteLine("************** Already received packet " + (_packet.header.sequenceNumber).ToString() + " ***********");
                }
                else if (_packet.header.sequenceNumber > windowLowerbound)
                {
                    Console.WriteLine("************** Not in order packet received " + (_packet.header.sequenceNumber).ToString() + " ***********");
                }
                else if (_packet.header.sequenceNumber == windowLowerbound)
                {
                    Console.WriteLine("************** In order " + (_packet.header.sequenceNumber).ToString() + " ***********");
                }
                translateWindow();


                return(TCPCopyCatController.responseCode.OK);
            };

            //Console.WriteLine("Sending file to port: " + serverEndpoint.Port.ToString());
            if (!TCPCopyCatController.sendMessageToEndPoint(socket, serverEndpoint, packet))
            {
                registerPacket(packet, receivedMessageCallbackLambda, 2500);
            }
        }
        public static bool sendMessageToEndPoint(Socket socket, IPEndPoint receiver, TCPCopycatPacket packet)
        {
            Boolean exception_thrown = false;

            try
            {
                //Console.WriteLine("Sending packet: " + packet.header.acknowledgeNumber.ToString() + " to endpoint: " + receiver.Address.ToString() + ":" + receiver.Port.ToString());
                socket.SendTo(packet.serialize(), receiver);
            }
            catch (Exception send_exception)
            {
                exception_thrown = true;
                Console.WriteLine(" Exception {0}", send_exception.Message);
            }
            if (exception_thrown == true)
            {
                exception_thrown = false;
                Console.WriteLine("The exception indicates the message was not sent.");
            }
            return(exception_thrown);
        }
        public static TCPCopycatPacket[] FileToTCPCopycatPacket(string filePath)
        {
            byte[] fileBytes = System.IO.File.ReadAllBytes(@filePath);

            int nbPacket = fileBytes.Length / maxBytePerPacket + 1;

            byte[][] ret = new byte[nbPacket][];

            for (int i = 0; i < nbPacket - 1; ++i)
            {
                ret[i] = new byte[maxBytePerPacket];
                for (int j = 0; j < maxBytePerPacket; ++j)
                {
                    ret[i][j] = fileBytes[i * maxBytePerPacket + j];
                }
            }

            ret[nbPacket - 1] = new byte[fileBytes.Length % maxBytePerPacket];

            for (int i = 0; i < fileBytes.Length % maxBytePerPacket; i++)
            {
                ret[nbPacket - 1][i] = fileBytes[(nbPacket - 1) * maxBytePerPacket + i];
            }


            TCPCopycatPacket[] copycatPacketArray = new TCPCopycatPacket[nbPacket];

            for (int i = 0; i < nbPacket; i++)
            {
                copycatPacketArray[i] = new TCPCopycatPacket(new TCPCopycatPacket.TCPCopycatHeader {
                    dataLenght = ret[i].Length, sequenceNumber = i
                }, ret[i]);
            }

            return(copycatPacketArray);
        }
 public void sendMessageToEndPoint(Socket socket, IPEndPoint receiver, TCPCopycatPacket packet, TCPCopycatReceiveMessageCallback callbackLambda, int timeoutTime = 1000)
 {
     sendMessageToEndPoint(socket, receiver, packet);
 }