Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

network download speed is too slow


  • Please log in to reply
1 reply to this topic

#1 Serkan Polat

Serkan Polat

    Member

  • Members
  • PipPip
  • 17 posts

Posted 15 December 2011 - 07:19 PM

hi everyone,
i wrote my custom ftp client class and try to download a file from my ftp server.
also i tried httpwebrequest and download a file from http server..
but the speed is about 16kbit per second, is this the speed limit? or am i making mistake?
here is my ftp class

using System;
using System.IO;
using Microsoft.SPOT;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;



namespace smg.ftp
{

    public class FtpClient
    {

        public class FtpException : Exception
        {
            public FtpException(string message) : base(message) { }
            public FtpException(string message, Exception innerException) : base(message, innerException) { }
        }

        private static int BUFFER_SIZE = 2048;
        private static Encoding ASCII = Encoding.UTF8;

        private bool verboseDebugging = false;

        // defaults
        private string server = "localhost";
        private string remotePath = ".";
        private string username = "anonymous";
        private string password = "anonymous@anonymous.net";
        private string message = null;
        private string result = null;

        private int port = 21;
        private int bytes = 0;
        private int resultCode = 0;

        private bool loggedin = false;
        private bool binMode = false;

        private Byte[] buffer = new Byte[BUFFER_SIZE];
        private Socket clientSocket = null;

        private int timeoutSeconds = 300;

        /// <summary>
        /// Default contructor
        /// </summary>
        public FtpClient()
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="server"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public FtpClient(string server, string username, string password)
        {
            this.server = server;
            this.username = username;
            this.password = password;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="server"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="timeoutSeconds"></param>
        /// <param name="port"></param>
        public FtpClient(string server, string username, string password, int timeoutSeconds, int port)
        {
            this.server = server;
            this.username = username;
            this.password = password;
            this.timeoutSeconds = timeoutSeconds;
            this.port = port;
        }

        /// <summary>
        /// Display all communications to the debug log
        /// </summary>
        public bool VerboseDebugging
        {
            get
            {
                return this.verboseDebugging;
            }
            set
            {
                this.verboseDebugging = value;
            }
        }
        /// <summary>
        /// Remote server port. Typically TCP 21
        /// </summary>
        public int Port
        {
            get
            {
                return this.port;
            }
            set
            {
                this.port = value;
            }
        }
        /// <summary>
        /// Timeout waiting for a response from server, in seconds.
        /// </summary>
        public int Timeout
        {
            get
            {
                return this.timeoutSeconds;
            }
            set
            {
                this.timeoutSeconds = value;
            }
        }
        /// <summary>
        /// Gets and Sets the name of the FTP server.
        /// </summary>
        /// <returns></returns>
        public string Server
        {
            get
            {
                return this.server;
            }
            set
            {
                this.server = value;
            }
        }
        /// <summary>
        /// Gets and Sets the port number.
        /// </summary>
        /// <returns></returns>
        public int RemotePort
        {
            get
            {
                return this.port;
            }
            set
            {
                this.port = value;
            }
        }
        /// <summary>
        /// GetS and Sets the remote directory.
        /// </summary>
        public string RemotePath
        {
            get
            {
                return this.remotePath;
            }
            set
            {
                this.remotePath = value;
            }

        }
        /// <summary>
        /// Gets and Sets the username.
        /// </summary>
        public string Username
        {
            get
            {
                return this.username;
            }
            set
            {
                this.username = value;
            }
        }
        /// <summary>
        /// Gets and Set the password.
        /// </summary>
        public string Password
        {
            get
            {
                return this.password;
            }
            set
            {
                this.password = value;
            }
        }

        /// <summary>
        /// If the value of mode is true, set binary mode for downloads, else, Ascii mode.
        /// </summary>
        public bool BinaryMode
        {
            get
            {
                return this.binMode;
            }
            set
            {
                if (this.binMode == value) return;

                if (value)
                    sendCommand("TYPE I");

                else
                    sendCommand("TYPE A");

                if (this.resultCode != 200) throw new FtpException(result.Substring(4));
            }
        }
        /// <summary>
        /// Login to the remote server.
        /// </summary>
        public void Login()
        {
            if (this.loggedin) this.Close();

            Debug.Print("Opening connection to " + this.server + "FtpClient");


            IPEndPoint ep = null;

            try
            {
                this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ep = new IPEndPoint(IPAddress.Parse(this.server), this.port);
                this.clientSocket.Connect(ep);
            }
            catch (Exception ex)
            {
                // doubtfull

                if (this.clientSocket != null) this.clientSocket.Close();

                throw new FtpException("Couldn't connect to remote server", ex);
            }

            this.readResponse();

            if (this.resultCode != 220)
            {
                this.Close();
                throw new FtpException(this.result.Substring(4));
            }

            this.sendCommand("USER " + username);

            if (!(this.resultCode == 331 || this.resultCode == 230))
            {
                this.cleanup();
                throw new FtpException(this.result.Substring(4));
            }

            if (this.resultCode != 230)
            {
                this.sendCommand("PASS " + password);

                if (!(this.resultCode == 230 || this.resultCode == 202))
                {
                    this.cleanup();
                    throw new FtpException(this.result.Substring(4));
                }
            }

            this.loggedin = true;

            Debug.Print("Connected to " + this.server + "FtpClient");


        }

        /// <summary>
        /// Close the FTP connection.
        /// </summary>
        public void Close()
        {
            Debug.Print("Closing connection to " + this.server + "FtpClient");

            if (this.clientSocket != null)
            {
                this.sendCommand("QUIT");
            }

            this.cleanup();
        }



        /// <summary>
        /// Return the size of a file.
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public long GetFileSize(string fileName)
        {
            if (!this.loggedin) this.Login();

            this.sendCommand("SIZE " + fileName);
            long size = 0;

            if (this.resultCode == 213)
                size = long.Parse(this.result.Substring(4));

            else
                throw new FtpException(this.result.Substring(4));

            return size;
        }


        /// <summary>
        /// Download a file to the Assembly's local directory,
        /// keeping the same file name.
        /// </summary>
        /// <param name="remFileName"></param>
        public void Download(string remFileName)
        {
            this.Download(remFileName, "", false);
        }

        /// <summary>
        /// Download a remote file to the Assembly's local directory,
        /// keeping the same file name, and set the resume flag.
        /// </summary>
        /// <param name="remFileName"></param>
        /// <param name="resume"></param>
        public void Download(string remFileName, Boolean resume)
        {
            this.Download(remFileName, "", resume);
        }

        /// <summary>
        /// Download a remote file to a local file name which can include
        /// a path. The local file name will be created or overwritten,
        /// but the path must exist.
        /// </summary>
        /// <param name="remFileName"></param>
        /// <param name="locFileName"></param>
        public void Download(string remFileName, string locFileName)
        {
            this.Download(remFileName, locFileName, false);
        }

        /// <summary>
        /// Download a remote file to a local file name which can include
        /// a path, and set the resume flag. The local file name will be
        /// created or overwritten, but the path must exist.
        /// </summary>
        /// <param name="remFileName"></param>
        /// <param name="locFileName"></param>
        /// <param name="resume"></param>
        public void Download(string remFileName, string locFileName, Boolean resume)
        {
            if (!this.loggedin) this.Login();

           // this.BinaryMode = true;

            Debug.Print("Downloading file " + remFileName + " from " + server + "/" + remotePath + "FtpClient");

            if (locFileName.Equals(""))
            {
                locFileName = remFileName;
            }

            FileStream output = null;

            if (!File.Exists(locFileName))
                output = File.Create(locFileName);

            else
                output = new FileStream(locFileName, FileMode.Open);

            Socket cSocket = createDataSocket();

            long offset = 0;

            if (resume)
            {
                offset = output.Length;

                if (offset > 0)
                {
                    this.sendCommand("REST " + offset);
                    if (this.resultCode != 350)
                    {
                        //Server dosnt support resuming
                        offset = 0;
                        Debug.Print("Resuming not supported:" + result.Substring(4) + "FtpClient");
                    }
                    else
                    {
                        Debug.Print("Resuming at offset " + offset + "FtpClient");
                        output.Seek(offset, SeekOrigin.Begin);
                    }
                }
            }

            this.sendCommand("RETR " + remFileName);

            if (this.resultCode != 150 && this.resultCode != 125)
            {
                throw new FtpException(this.result.Substring(4));
            }

            DateTime timeout = DateTime.Now.AddSeconds(this.timeoutSeconds);

            while (timeout > DateTime.Now)
            {
                this.bytes = cSocket.Receive(buffer, buffer.Length, 0);
                //output.Write(this.buffer, 0, this.bytes);
                //Thread.Sleep(1);
                if (this.bytes <= 0)
                {
                    break;
                }
            }

            output.Close();

            try { cSocket.Close(); }
            catch (Exception) { }

            this.readResponse();

            if (this.resultCode != 226 && this.resultCode != 250)
                throw new FtpException(this.result.Substring(4));
        }







        /// <summary>
        /// 
        /// </summary>
        private void readResponse()
        {
            this.message = "";
            this.result = this.readLine();

            if (this.result.Length > 3)
                this.resultCode = int.Parse(this.result.Substring(0, 3));
            else
                this.result = null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private string readLine()
        {
            while (true)
            {
                this.bytes = clientSocket.Receive(this.buffer, this.buffer.Length, 0);
                char[] cc = ASCII.GetChars(this.buffer);
                this.message += new string(cc).Substring(0, this.bytes);
                //this.message += ASCII.GetString(this.buffer, 0, this.bytes);
                Thread.Sleep(10);
                if (this.bytes < this.buffer.Length)
                {
                    break;
                }
            }
            Thread.Sleep(100);
            string[] msg = this.message.Split('\n');

            if (this.message.Length > 2)
            {
                if (msg.Length>=2)
                {
                    this.message = msg[msg.Length - 2];
                }
                else
                {
                    this.message = msg[0];
                }
            }
            else
            {
                this.message = msg[0];
            }

            if (this.message.Length > 4 && !this.message.Substring(3, 1).Equals(" ")) return this.readLine();

            if (this.verboseDebugging)
            {
                for (int i = 0; i < msg.Length - 1; i++)
                {
                    Debug.Print(msg[i] + "FtpClient");
                }
            }

            return message;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        private void sendCommand(String command)
        {
            if (this.verboseDebugging) Debug.Print(command + "FtpClient");

            //Byte[] cmdBytes = Encoding.UTF8.GetBytes(command + "\r\n");

            Byte[] cmdBytes = ASCII.GetBytes(command + "\r\n");
            clientSocket.Send(cmdBytes, cmdBytes.Length, 0);
            this.readResponse();
        }


        /// <summary>
        /// when doing data transfers, we need to open another socket for it.
        /// </summary>
        /// <returns>Connected socket</returns>
        private Socket createDataSocket()
        {
            this.sendCommand("PASV");

            if (this.resultCode != 227) throw new FtpException(this.result.Substring(4));

            int index1 = this.result.IndexOf('(');
            int index2 = this.result.IndexOf(')');

            string ipData = this.result.Substring(index1 + 1, index2 - index1 - 1);

            int[] parts = new int[6];
            string[] sparts = ipData.Split(',');
            for (int i = 0; i < parts.Length; i++)
            {
                parts[i] = int.Parse(sparts[i]);
            }

            int len = ipData.Length;
            int partCount = 0;
            string buf = "";

            //for (int i = 0; i < len && partCount <= 6; i++)
            //{
            //    char[] charr = ipData.Substring(i, 1).ToCharArray();
            //    char ch = charr[0];

            //    if (int.Parse(ch.ToString()) >= 0)
            //        buf += ch;

            //    else if (ch != ',')
            //        throw new FtpException("Malformed PASV result: " + result);

            //    if (ch == ',' || i + 1 == len)
            //    {
            //        try
            //        {
            //            parts[partCount++] = int.Parse(buf);
            //            buf = "";
            //        }
            //        catch (Exception ex)
            //        {
            //            throw new FtpException("Malformed PASV result (not supported?): " + this.result, ex);
            //        }
            //    }
            //}

            string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3];

            int port = (parts[4] << 8) + parts[5];

            Socket socket = null;
            IPEndPoint ep = null;

            try
            {
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                ep = new IPEndPoint(IPAddress.Parse(ipAddress), port);
                socket.Connect(ep);
            }
            catch (Exception ex)
            {
                // doubtfull....
                if (socket != null) socket.Close();

                throw new FtpException("Can't connect to remote server", ex);
            }

            return socket;
        }

        /// <summary>
        /// Always release those sockets.
        /// </summary>
        private void cleanup()
        {
            if (this.clientSocket != null)
            {
                this.clientSocket.Close();
                this.clientSocket = null;
            }
            this.loggedin = false;
        }

        /// <summary>
        /// Destuctor
        /// </summary>
        ~FtpClient()
        {
            this.cleanup();
        }


        /**************************************************************************************************************/
        #region Async methods (auto generated)

        /*
				WinInetApi.FtpClient ftp = new WinInetApi.FtpClient();

				MethodInfo[] methods = ftp.GetType().GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Public);

				foreach ( MethodInfo method in methods )
				{
					string param = "";
					string values = "";
					foreach ( ParameterInfo i in  method.GetParameters() )
					{
						param += i.ParameterType.Name + " " + i.Name + ",";
						values += i.Name + ",";
					}
					

					Debug.Print("private delegate " + method.ReturnType.Name + " " + method.Name + "Callback(" + param.TrimEnd(',') + ");");

					Debug.Print("public System.IAsyncResult Begin" + method.Name + "( " + param + " System.AsyncCallback callback )");
					Debug.Print("{");
					Debug.Print("" + method.Name + "Callback ftpCallback = new " + method.Name + "Callback(" + values + " this." + method.Name + ");");
					Debug.Print("return ftpCallback.BeginInvoke(callback, null);");
					Debug.Print("}");
					Debug.Print("public void End" + method.Name + "(System.IAsyncResult asyncResult)");
					Debug.Print("{");
					Debug.Print(method.Name + "Callback fc = (" + method.Name + "Callback) ((AsyncResult)asyncResult).AsyncDelegate;");
					Debug.Print("fc.EndInvoke(asyncResult);");
					Debug.Print("}");
					//Debug.Print(method);
				}
*/


        private delegate void LoginCallback();
        public System.IAsyncResult BeginLogin(System.AsyncCallback callback)
        {
            LoginCallback ftpCallback = new LoginCallback(this.Login);
            return ftpCallback.BeginInvoke(callback, null);
        }
        private delegate void CloseCallback();
        public System.IAsyncResult BeginClose(System.AsyncCallback callback)
        {
            CloseCallback ftpCallback = new CloseCallback(this.Close);
            return ftpCallback.BeginInvoke(callback, null);
        }

        private delegate Int64 GetFileSizeCallback(String fileName);
        public System.IAsyncResult BeginGetFileSize(String fileName, System.AsyncCallback callback)
        {
            GetFileSizeCallback ftpCallback = new GetFileSizeCallback(this.GetFileSize);
            return ftpCallback.BeginInvoke(fileName, callback, null);
        }
        private delegate void DownloadCallback(String remFileName);
        public System.IAsyncResult BeginDownload(String remFileName, System.AsyncCallback callback)
        {
            DownloadCallback ftpCallback = new DownloadCallback(this.Download);
            return ftpCallback.BeginInvoke(remFileName, callback, null);
        }
        private delegate void DownloadFileNameResumeCallback(String remFileName, Boolean resume);
        public System.IAsyncResult BeginDownload(String remFileName, Boolean resume, System.AsyncCallback callback)
        {
            DownloadFileNameResumeCallback ftpCallback = new DownloadFileNameResumeCallback(this.Download);
            return ftpCallback.BeginInvoke(remFileName, resume, callback, null);
        }
        private delegate void DownloadFileNameFileNameCallback(String remFileName, String locFileName);
        public System.IAsyncResult BeginDownload(String remFileName, String locFileName, System.AsyncCallback callback)
        {
            DownloadFileNameFileNameCallback ftpCallback = new DownloadFileNameFileNameCallback(this.Download);
            return ftpCallback.BeginInvoke(remFileName, locFileName, callback, null);
        }
        private delegate void DownloadFileNameFileNameResumeCallback(String remFileName, String locFileName, Boolean resume);
        public System.IAsyncResult BeginDownload(String remFileName, String locFileName, Boolean resume, System.AsyncCallback callback)
        {
            DownloadFileNameFileNameResumeCallback ftpCallback = new DownloadFileNameFileNameResumeCallback(this.Download);
            return ftpCallback.BeginInvoke(remFileName, locFileName, resume, callback, null);
        }





        #endregion
    }
}


here how i use it
FtpClient ftp = new FtpClient("192.168.1.21", "mtest", "mtest", 1000, 21);


            ftp.Download("test.MP3", "\\SD\\bb.mp3", true);


before i start ftp download
here is my dhcp configuration
static private void InitNetwork()
        {
            // write your code here
            NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

            foreach (NetworkInterface networkInterface in networkInterfaces)
            {
                if (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
                {
                    if (!networkInterface.IsDhcpEnabled)
                    {
                        // Switch to DHCP ...
                        networkInterface.EnableDhcp();
                        networkInterface.RenewDhcpLease();
                        Thread.Sleep(10000);
                    }

                    Debug.Print("IP Address: " + networkInterface.IPAddress);
                    Debug.Print("Subnet mask " + networkInterface.SubnetMask);
                    Debug.Print("Gateway " + networkInterface.GatewayAddress);
                    Debug.Print("DNS " + networkInterface.DnsAddresses[0]);
                }
            }
        }



also as i told, i write an http downloader, speed is the same with it..

here is the http downloader
using System;
using Microsoft.SPOT;
using System.IO;
using System.Net;
using System.Net.Sockets;


namespace smg.utulity.downloader
{
    class downloader
    {

        public static event Progress onProgress;
        public delegate void Progress(long currentSize, long TotalSize, string Filename);

        public static event DownloadFinished onDownloadFinished;
        public delegate void DownloadFinished(string errMsg);

        public static int DownloadFile(String remoteFilename,
                               String localFilename)
        {

            string fname = localFilename.Split('\\')[localFilename.Split('\\').Length - 1];
            // Function will return the number of bytes processed
            // to the caller. Initialize to 0 here.
            int bytesProcessed = 0;

            // Assign values to these objects here so that they can
            // be referenced in the finally block
            Stream remoteStream = null;
            Stream localStream = null;
            WebResponse response = null;

            // Use a try/catch/finally block as both the WebRequest and Stream
            // classes throw exceptions upon error
            try
            {
                // Create a request for the specified remote file name
                WebRequest request = WebRequest.Create(remoteFilename);
                if (request != null)
                {
                    // Send the request to the server and retrieve the
                    // WebResponse object 
                    // request.ContentLength
                    response = request.GetResponse();
                    if (response != null)
                    {
                        // Once the WebResponse object has been retrieved,
                        // get the stream object associated with the response's data
                        remoteStream = response.GetResponseStream();
                        long total = response.ContentLength;

                        // Create the local file
                        localStream = File.Create(localFilename);

                        // Allocate a 1k buffer

                        byte[] buffer = new byte[1024];
                        int bytesRead;

                        // Simple do/while loop to read from stream until
                        // no bytes are returned
                        do
                        {
                            // Read data (up to 1k) from the stream
                            bytesRead = remoteStream.Read(buffer, 0, buffer.Length);

                            // Write the data to the local file
                            localStream.Write(buffer, 0, bytesRead);

                            // Increment total bytes processed
                            bytesProcessed += bytesRead;

                            if (onProgress != null) { onProgress(bytesProcessed, total, fname); }
                        } while (bytesRead > 0);
                    }
                }
                if (onDownloadFinished != null) { onDownloadFinished("finished"); }
            }
            catch (WebException webEx)
            {
                Debug.Print("Web Exception Occured");
                if (webEx.InnerException is SocketException)
                {
                    SocketException sock = webEx.InnerException as SocketException;
                    Debug.Print("Socket error code: " + sock.ErrorCode.ToString());
                }
            }
            catch (Exception ex)
            {
                Debug.Print("Exception of type: " + ex.GetType().FullName);
                Debug.Print(ex.Message);
                if (onDownloadFinished != null) { onDownloadFinished(ex.Message); }
            }
            finally
            {
                // Close the response and streams objects here 
                // to make sure they're closed even if an exception
                // is thrown at some point
                if (response != null) response.Close();
                if (remoteStream != null) remoteStream.Close();
                if (localStream != null) localStream.Close();
            }

            // Return total bytes processed to caller.
            return bytesProcessed;
        }
    }
}



here is how i used it
public static void Main()
        {
downloader.onProgress += new downloader.Progress(downloader_onProgress);
            downloader.onDownloadFinished += new downloader.DownloadFinished(downloader_onDownloadFinished);
            int filesize = downloader.DownloadFile("http://192.168.1.21/test.MP3", "\\SD\\deneme1.mp3");
}
static void downloader_onDownloadFinished(string errMsg)
        {
            Debug.Print("download finished" + errMsg);
        }

        static void downloader_onProgress(long currentSize, long TotalSize, string Filename)
        {
            Debug.Print("c:" + currentSize + "-t:" + TotalSize + "-f:" + Filename);
        }


my network connection is 100mbit..
my internet speed is 10 mbit.. my pc downloads the same file with 800-900kbit/s
but netduino plus downloads at 16-20kbit/s

how can i improve speed?

note: i am using MF 4.2 and when using system.ftp (also adding system.http) , i cant deploy the application..
can anyone show me a better way?

#2 Serkan Polat

Serkan Polat

    Member

  • Members
  • PipPip
  • 17 posts

Posted 19 December 2011 - 03:31 PM

still no answer from anyone.. what is the download speed limit of lwip and parallel bus? i need help about speed improvement with netduino plus devices.. chris helppppp! :)




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.