Пример #1
0
        public void SendFile()
        {
            SharedObject shared = new SharedObject(this.socket, this.connectionNumber, this.inFile, this.measure);

            Task timeoutChecker = new Task(TimeoutCheckerThread, shared);
            Task receive        = new Task(ReceiveThread, shared);
            Task dataProccess   = new Task(ProccessDataThread, shared);

            Task[] tasks = new Task[] { timeoutChecker, receive, dataProccess };

            try
            {
                measure.Start();

                foreach (Task t in tasks)
                {
                    t.Start();
                }

                Task <Task> waiter = Task.WhenAny(timeoutChecker, receive, dataProccess);
                waiter.Wait();

                Task whoEndIt = waiter.Result;
                Logger.WriteLine($"Thread {whoEndIt.Id} ended his work");
                if (whoEndIt.Exception != null)
                {
                    throw whoEndIt.Exception.InnerException;
                }
            }
            catch (MaximumAttempException)
            {
                Logger.WriteLine("Maximum attemp of send, sending RST packet", ConsoleColor.Yellow);
                CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, 0, (byte)Flag.RST, new byte[] { }));
                throw;
            }
            catch (InvalidPacketException e)
            {
                Logger.WriteLine($"Invalid packet ({e.Message}), sending RST packet", ConsoleColor.Yellow);
                CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, 0, (byte)Flag.RST, new byte[] { }));
                throw;
            }
            catch (CommunicationException)
            {
                Logger.WriteLine($"Error occurs during communication", ConsoleColor.Yellow);
                throw;
            }
            finally
            {
                shared.Ended = true;
                foreach (Task t in tasks)
                {
                    if (t.Status == TaskStatus.Running)
                    {
                        t.Wait();
                    }
                    t.Dispose();
                }
                this.measure.ShowSpeed(shared.Confirmed);
            }
        }
Пример #2
0
        static private void ReceiveThread(object Param)
        {
            Logger.WriteLine($"Receive thread started with id {Task.CurrentId}");
            SharedObject data = (SharedObject)Param;

            while (!data.Ended)
            {
                data.Socket.ReceiveTimeout = (int)PacketsProps.WAIT_TIME;
                try
                {
                    CommunicationPacket p = CommunicationFacade.Receive(data.Socket);
                    UInt64 currentPoint;
                    lock (data.CountersLocker)
                        currentPoint = data.Confirmed;

                    UInt64           confirmationNumber = CommunicationFacade.ComputeRealNumber(p.ConfirmationNumber, currentPoint, UInt16.MaxValue, (uint)Sizes.WINDOW_SIZE);
                    UploadRecvPacket recv = new UploadRecvPacket(p.ConnectionNumber, p.Flags, p.Data, confirmationNumber);

                    lock (data.ArriveQueue)
                        data.ArriveQueue.Enqueue(recv);
                }
                catch (SocketException e) when(e.SocketErrorCode == SocketError.TimedOut)
                {
                }
            }
        }
Пример #3
0
        public static UInt32 InitConnection(Socket socket, Command action)
        {
            int i = 0;

            socket.ReceiveTimeout = 100;

            while (i < 20)
            {
                CommunicationFacade.Send(socket, new CommunicationPacket(0, 0, 0, (byte)Flag.SYN, new byte[] { (byte)action }));
                try
                {
                    while (true)
                    {
                        CommunicationPacket recived = CommunicationFacade.Receive(socket);
                        if (recived.Flags == (byte)Flag.SYN && recived.Data[0] == (byte)action && recived.SerialNumber == 0 && recived.ConfirmationNumber == 0)
                        {
                            Logger.WriteLine($"Connection established - communication {recived.ConnectionNumber:X}");
                            socket.ReceiveTimeout = 0;
                            return(recived.ConnectionNumber);
                        }
                        else
                        {
                            Console.WriteLine("Data obtained before connection packet received, ignoring");
                        }
                    }
                }
                catch (SocketException e) when(e.SocketErrorCode == SocketError.TimedOut)
                {
                    Logger.WriteLine($"Connection timeouted, attemp number {i + 1}");
                    i++;
                }
            }
            throw new Exceptions.MaximumAttempException();
        }
Пример #4
0
        private DownloadPacket receive(CommunicationPacket p)
        {
            UInt64         realSerial = CommunicationFacade.ComputeRealNumber(p.SerialNumber, this.required, UInt16.MaxValue, (uint)Sizes.WINDOW_SIZE);
            DownloadPacket toReturn   = new DownloadPacket(p.Data, p.ConnectionNumber, p.Flags, realSerial);;

            Logger.WriteLine($"Downloader recive packet with serial={toReturn.SerialNumber}");
            return(toReturn);
        }
Пример #5
0
        static private void TimeoutCheckerThread(object Param)
        {
            Logger.WriteLine($"TimeoutChecker thread started with id {Task.CurrentId}");
            SharedObject     data = (SharedObject)Param;
            UploadSendPacket p;

            while (!data.Ended)
            {
                p = null;

                //check the oldest packet
                lock (data.SendedPackets)
                {
                    if (data.SendedPackets.Count > 0)
                    {
                        TimeSpan diff = DateTime.Now - data.SendedPackets.First.Value.LastSend;
                        if (Math.Abs(diff.TotalMilliseconds) >= (ushort)PacketsProps.WAIT_TIME)
                        {
                            p = data.SendedPackets.First.Value;
                            data.SendedPackets.RemoveFirst();
                        }
                    }
                }

                //if expires oldes packet
                if (p != null)
                {
                    //check if is required to send it
                    UInt64 currentConfirmed;
                    lock (data.CountersLocker)
                    {
                        currentConfirmed = data.Confirmed;
                    }
                    bool sendIt = p.SerialNumber >= currentConfirmed;

                    //send it if needed
                    if (sendIt)
                    {
                        //socket have highter serial number that is confirmed number
                        p.Sended++;
                        p.LastSend = DateTime.Now;
                        if (p.Sended == (ushort)PacketsProps.MAX_ATTEMPS)
                        {
                            throw new MaximumAttempException();
                        }
                        Logger.WriteLine($"Packet {p.SerialNumber} timeouted, sends again");
                        CommunicationFacade.Send(data.Socket, p.CreatePacketToSend());
                        lock (data.SendedPackets)
                            data.SendedPackets.AddLast(p);
                    }
                }
                else //timeout not expired for the oldest packet
                {
                    Thread.Sleep(0);
                }
            }
        }
Пример #6
0
        public void AcceptFile()
        {
            try
            {
                byte[] empty = new byte[] { };
                IPriorityQueue <DownloadPacket, UInt64> queue = new SimplePriorityQueue <DownloadPacket, UInt64>();
                //TODO add priority queue

                while (true)
                {
                    DownloadPacket pack = this.receive(CommunicationFacade.Receive(this.socket));
                    pack = this.validatePacket(pack);

                    if (pack.Flags == (byte)Flag.FIN)
                    {
                        Logger.WriteLine("All data arrive", ConsoleColor.Cyan);
                        CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, Convert.ToUInt16(this.required & UInt16.MaxValue), (byte)Flag.FIN, empty));
                        return;
                    }


                    queue.Enqueue(pack, pack.SerialNumber);

                    //Attach into priority queue
                    while (queue.Count > 0 && queue.First.SerialNumber <= this.required)
                    {
                        DownloadPacket toProccess = queue.Dequeue();
                        if (toProccess.SerialNumber < this.required)
                        {
                            continue;
                        }
                        Logger.WriteLine($"Accepted packet {toProccess.SerialNumber}");
                        this.outFile.Write(toProccess.Data);
                        this.required += (uint)toProccess.Data.Length;
                        if (toProccess.Data.Length != 255)
                        {
                            Logger.WriteLine("Last packet arrive, waiting to FIN packet", ConsoleColor.Cyan);
                            this.waitingToFin = true;
                        }
                    }
                    Logger.WriteLine($"Waiting for packet {this.required}");
                    CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, Convert.ToUInt16(this.required & UInt16.MaxValue), 0, empty));
                }
            }
            catch (CommunicationException)
            {
                Logger.WriteLine("Occurs error during communication", ConsoleColor.Yellow);
                throw new TerminateException();
            }
            catch (InvalidPacketException e)
            {
                Logger.WriteLine($"Obtained invalid packet: {e.Message}", ConsoleColor.Yellow);
                CommunicationFacade.Send(this.socket, new CommunicationPacket(this.connectionNumber, 0, Convert.ToUInt16(this.required & UInt16.MaxValue), (byte)Flag.RST, new byte[] { }));
                throw new TerminateException();
            }
        }
Пример #7
0
 public void InitConnection()
 {
     this.connectionNumber = CommunicationFacade.InitConnection(this.socket, Command.UPLOAD);
 }