예제 #1
0
        public void RRQThread()
        {
            // Description des variables du thread
            byte[] bTrame = new byte[516];
            bool   bRead;

            byte[] bTamponReception = new byte[516];
            int    nRead = 0, nTimeOut = 0, nAckError = 0, nBlock = 0;

            if (File.Exists(fileRRQ))
            {
                // Ouverture du fichier avec un filestream
                fs = File.Open(fileRRQ, FileMode.Open, FileAccess.Read, FileShare.Read);
                do
                {
                    nRead = fs.Read(bTrame, 4, 512);
                    nBlock++;
                    bTrame[0] = 0;
                    bTrame[1] = 3;
                    bTrame[2] = (byte)(nBlock >> 8);
                    bTrame[3] = (byte)(nBlock % 256);
                    do
                    {
                        try  // Essayer d'envoyer la trame actuelle au serveur, sinon, afficher une erreur
                        {
                            sRRQ.SendTo(bTrame, 4 + nRead, SocketFlags.None, PointDistantRRQ);
                        }
                        catch (SocketException se)
                        {
                            f.Invoke(f.ServerStatus, new object[] { string.Format("Il y a eu une erreur lors de la réception, l'hôte distant a dû être fermé") });
                            return;
                        }

                        // Attendre une réponse du client
                        if (!(bRead = sRRQ.Poll(5000000, SelectMode.SelectRead)))
                        {
                            nTimeOut++;
                            f.Invoke(f.ServerStatus, new object[] { "Attente du client" });
                        }
                        else
                        {
                            nTimeOut = 0;
                            try
                            {
                                sRRQ.ReceiveFrom(bTamponReception, ref PointDistantRRQ);
                            }
                            catch (SocketException se)
                            {
                                f.Invoke(f.ServerStatus, new object[] { string.Format("Il y a eu une erreur lors de la réception. Transfert annulé...") });
                                fs.Close();
                                return;
                            }
                            // Verification dans une erreur de transfert de bloc
                            if (!(bTamponReception[0] == 0 && bTamponReception[1] == 4))
                            {
                                nAckError++;
                            }
                            else
                            {
                                nAckError = 0;
                                nBlock    = bTamponReception[2] << 8;
                                nBlock   += bTamponReception[3];
                            }
                        }
                    }while (!bRead && nTimeOut < 10 && nAckError < 3);
                }while (nRead == 512 && nTimeOut < 10 && nAckError < 3);
                // Detection du type d'erreur
                if (nAckError == 3)
                {
                    errorMsg = DetectionTypeErreur(sRRQ, PointDistantRRQ, 5);
                    f.Invoke(f.ServerStatus, new object[] { errorMsg });
                }
                fs.Close();
                f.Invoke(f.ServerStatus, new object[] { string.Format("Total de blocs transférés : {0} envoyés à {1}", nBlock, PointDistantRRQ.ToString()) });
                f.Invoke(f.ServerStatus, new object[] { "Le transfert s'est effectué avec succès.\r\n" });
            }
            else // Si le fichier n'existe pas
            {
                errorMsg = DetectionTypeErreur(sRRQ, PointDistantRRQ, 1);
                f.Invoke(f.ServerStatus, new object[] { errorMsg });
            }
        }
예제 #2
0
        public void WRQThread()
        {
            // Définition des variables pour le thread
            byte[] bTrame = new byte[4] {
                0, 4, 0, 0
            };                                          // Pour envoyer un premier ack et commencer le transfert
            bool bRead;

            byte[] bTamponReception = new byte[516];
            int    indice = 0, nRead = 0, nTimeOut = 0, nBlockError = 0, nBlock = 1;

            if (!(File.Exists(fileWRQ)))
            {
                // Ouverture du fichier avec filestream
                fs = File.Open(fileWRQ, FileMode.CreateNew, FileAccess.Write, FileShare.None);
                // Envoyer un ack pour commencer le transfert
                try
                {
                    sWRQ.SendTo(bTrame, 4, SocketFlags.None, PointDistantWRQ);
                }
                catch (SocketException se)
                {
                    f.Invoke(f.ServerStatus, new object[] { string.Format("Il y a eu une erreur lors de la transmission initiale {0]", se.Message) });
                }
                f.Invoke(f.ServerStatus, new object[] { "On envoit un premier ACK au client pour faire la demande" });
                do
                {
                    SendAck(bTrame);
                    if (!(bRead = sWRQ.Poll(5000000, SelectMode.SelectRead)))
                    {
                        nTimeOut++;
                        f.Invoke(f.ServerStatus, new object[] { "Attente du client" });
                    }
                    else
                    {
                        nTimeOut = 0;
                        // Recevoir les informations des blocs
                        sWRQ.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 15000);
                        try // Recevoir les informations des blocs
                        {
                            nRead = sWRQ.ReceiveFrom(bTamponReception, ref PointDistantWRQ);
                        }
                        catch (SocketException se)
                        {
                            f.Invoke(f.ServerStatus, new object[] { string.Format("Il y a eu une erreur lors de la réception. Transfert annulé...") });
                            fs.Close();
                            return;
                        }
                        if (!(bTamponReception[0] == 0 && bTamponReception[1] == 3 && bTamponReception[2] == (byte)(nBlock >> 8) && bTamponReception[3] == (byte)(nBlock % 256)))
                        {
                            nBlockError++;
                            f.Invoke(f.ServerStatus, new object[] { "Une erreur de block a été rencontrée." });
                            // Verification de nblock requise
                        }
                        else
                        {
                            nBlockError = 0;
                            // Écrire les octets dans le fichier à retranscrire
                            for (indice = 4; indice < nRead; indice++)
                            {
                                fs.WriteByte(bTamponReception[indice]);
                            }
                            // Envoi d'un ack
                            bTrame[2] = (byte)(nBlock >> 8);
                            bTrame[3] = (byte)(nBlock % 256);
                            SendAck(bTrame);
                            nBlock++;
                        }
                    }
                }while (nRead == 516 && nTimeOut < 10 && nBlockError < 3);
                f.Invoke(f.ServerStatus, new object[] { string.Format("Total de block transférés : {0}, dans le fichier {1}", nBlock, fileWRQ) });
                // Réagir à une erreur dans un transfert de bloc
                if (nBlockError == 3)
                {
                    // Envoi de l'erreur pour lier le bon type avec le code d'erreur
                    errorMsg = DetectionTypeErreur(sWRQ, PointDistantWRQ, 5);
                    f.Invoke(f.ServerStatus, new object[] { errorMsg });
                }
                fs.Close();
                f.Invoke(f.ServerStatus, new object[] { "Le transfert s'est effectué avec succès !\r\n" });
            }
            else
            {
                errorMsg = DetectionTypeErreur(sWRQ, PointDistantWRQ, 6);
                f.Invoke(f.ServerStatus, new object[] { errorMsg });
            }
        }
예제 #3
0
        public void ListenThread()
        {
            // Création de la chainequi va renfermer le nom du fichier a remplir
            string fileName, mode = null;

            // Création du point local et du point distant
            EndPoint LocalPoint   = new IPEndPoint(0, 69);
            EndPoint DistantPoint = new IPEndPoint(0, 0);

            // Création du tableau de byte qui va renfermer la réception
            byte[] bTamponReception = new byte[516];
            int    indice           = 0;

            // Écoute du serveur
            try
            {
                // Instanciation du socket
                socket = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Dgram, ProtocolType.Udp);
                socket.Bind(LocalPoint);

                //Boucle du thread
                while (!m_fin)
                {
                    if (socket.Available > 0)
                    {
                        socket.ReceiveFrom(bTamponReception, ref DistantPoint);

                        switch (TrameValidation(bTamponReception))
                        {
                        case 1:     // Read request
                            f.Invoke(f.ServerStatus, new object[] { "Une demande de lecture a été créée" });
                            fileName = null;
                            // Savoir le fichier a transporter
                            for (int i = 2; bTamponReception[i] != 0; i++)
                            {
                                fileName += (char)bTamponReception[i];
                            }
                            indice++;

                            // Savoir le mode de transmission du fichier
                            while (bTamponReception[indice] != 0)
                            {
                                mode += (char)bTamponReception[indice];
                                indice++;
                            }

                            // Instanciation de la classe RRQ
                            RRQ rrQ = new RRQ(f);
                            rrQ.SetFichier(fileName);
                            rrQ.SetPointDistant(DistantPoint);
                            f.Invoke(f.ServerStatus, new object[] { string.Format("Transfert du fichier {0} vers {1}", fileName, DistantPoint.ToString()) });
                            Thread threadRRQ = new Thread(new ThreadStart(rrQ.RRQThread));
                            threadRRQ.IsBackground = true;
                            threadRRQ.Start();
                            break;

                        case 2:     // Write Request
                            f.Invoke(f.ServerStatus, new object[] { "Une demande d'écriture a été créée" });
                            fileName = null;
                            // Savoir le fichier à transporter
                            for (int i = 2; bTamponReception[i] != 0; i++)
                            {
                                fileName += (char)bTamponReception[i];
                            }
                            indice++;

                            // Savoir le mode de transmission du fichier
                            while (bTamponReception[indice] != 0)
                            {
                                mode += (char)bTamponReception[indice];
                                indice++;
                            }
                            WRQ wrQ = new WRQ(f);
                            wrQ.SetFichier(fileName);
                            wrQ.SetPointDistant(DistantPoint);
                            f.Invoke(f.ServerStatus, new object[] { string.Format("Transfert du fichier {0} venant de {1}", fileName, DistantPoint.ToString()) });
                            Thread threadWRQ = new Thread(new ThreadStart(wrQ.WRQThread));
                            threadWRQ.Start();
                            threadWRQ.IsBackground = true;
                            break;

                        case 0:     // Ni RRQ, ni WRQ donc erreur
                            // Operation TFTP illégale
                            f.Invoke(f.ServerStatus, new object[] { "Une demande illégale a été rencontrée." });
                            DetectionTypeErreur(socket, DistantPoint, 4);
                            break;
                        }
                    }
                }
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.Message, "Problème avec le Socket",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
        }