Our Products:   CompleteFTP  edtFTPnet/Free  edtFTPnet/PRO  edtFTPj/Free  edtFTPj/PRO
0 votes
4.2k views
in .NET FTP by (180 points)
/// <summary>Put as binary, i.e. read and write raw bytes.</summary>
      /// <param name="srcStream">Input stream of data to put.</param>
      /// <param name="remoteFile">Name of remote file in current directory.</param>
      /// <param name="append"><c>true</c> if appending, <c>false</c> otherwise</param>
      private void PutBinary(Stream srcStream, string remoteFile, bool append)
        {   
            BufferedStream input = null;
            BinaryWriter output = null;
            SystemException storedEx = null;
            long size = 0;
            try
            {
                input = new BufferedStream(srcStream);
                
                if (TransferStarted != null)
                    TransferStarted(this, new EventArgs());
                if (TransferStartedEx != null)
                    TransferStartedEx(this, new TransferEventArgs(remoteFile, TransferDirection.UPLOAD, FTPTransferType.BINARY));

                InitPut(remoteFile, append);
                
                // get an output stream
                output = new BinaryWriter(data.DataStream);
                
                // if resuming, we skip over the unwanted bytes
                if (resume)
                {
                    input.Seek(resumeMarker, SeekOrigin.Current);
                }
                
                byte[] buf = new byte[transferBufferSize];
                

            /*
             * Es metodo de control de ancho de banda utiliza Sleep variable
             * que cambia segun las mediciones de tiempo obtenidas en el envio
             * de bytes. El valor del sleep varia siempre en 0.0 y 1.0 segundos.
             * */
            // read a chunk at a time and write to the data socket            
            int SEND_PORTION   = 512;
            long monitorCount   = 0;
            int count         = input.Read(buf, 0, buf.Length);
            int countSended   = 0;
            int countRest      = count;
            int   partialCount   = 0;
            long partialTotalSended = 0;
            
            long ticksBegin = DateTime.Now.Ticks;
            TimeSpan tsElapsed;
            
            while (count > 0 && !cancelTransfer)
            {   
               if (bytesPerSecond > 0)
               {
                  if (countRest < SEND_PORTION)
                     partialCount = countRest;
                  else
                     partialCount = SEND_PORTION;
               }
               else
                  partialCount = count;

               if (partialCount > 0)
               {
                  output.Write(buf, countSended, partialCount);

                  countSended += partialCount;

                  if (bytesPerSecond > 0)
                  {
                     partialTotalSended += partialCount;

                     tsElapsed = TimeSpan.FromTicks(DateTime.Now.Ticks - ticksBegin);
                  
                     // Se hace unas comprobaciones dentro del periodo de un 1 seg.
                     // Si dentro de ese segundo, se han superado el limite
                     // de ancho de banda, se provoca una pausa.
                     if ((tsElapsed.TotalSeconds <= 1.0) && 
                        (bytesPerSecond > 0 && (partialTotalSended >= bytesPerSecond)))
                     {
                        int iTimeToSleep = Convert.ToInt32(1000.0 - tsElapsed.TotalMilliseconds);
                        //Console.WriteLine("Time sleep : "+ iTimeToSleep + "("+ tsElapsed.TotalMilliseconds +")");
                        System.Threading.Thread.Sleep(iTimeToSleep);
                        ticksBegin = DateTime.Now.Ticks;
              

5 Answers

0 votes
by (51.4k points)
Hi Oleiros

This is tremendously generous of you. Thank you very much indeed. This is a very useful feature which we would like to add to our client, so having this code will prove very useful.

- Hans (EDT Support)
0 votes
by (1.9k points)
Hello oleiros..I am trying to accomplish the same. Control upload speed to adapt to my 256Kbps uplink. I am just a bit lost in your code. I can see you have put a lot of effort into this. Could you please guide me through it.

Thanks
0 votes
by (161k points)
You will need to extensively modify the edtFTPnet code to use the above - and it is only for one method out of many.

It is far simpler to use the BytesTransferred event.
0 votes
by (180 points)
Hello oleiros..I am trying to accomplish the same. Control upload speed to adapt to my 256Kbps uplink. I am just a bit lost in your code. I can see you have put a lot of effort into this. Could you please guide me through it.

Thanks


Hi, Leedo. Sorry for the delay, but now im very disconnected of the forum. Well, i will try (with my pathetic english) to clarify a little the philosophy of my modification.

The method is to check the transfered bytes in a leap of time (in this case, 1 second), and if the amount of transfered bytes is superior to the upload limit, we insert a proportional pause, calculated to match with the expected upload bytes per second. The goal is to maintain a specific value of uploaded bytes inside a second.

I hope the explication help you. See you next time.

P.D.: I believe emule's code uses the same way. isn't it?

Daniel J.
0 votes
by (1.9k points)
Yes I noticed the emule and many other P2P applications have the same feature. Not sure whether they use the same technique though. I'll try to convert your code to VB and give it a try. Thanks for responding.

Categories

...