Esempio n. 1
0
        void Run(string[] args)
        {
            try
            {
                consoleWidth = Console.WindowWidth;
            }
            catch (IOException)
            {
                consoleWidth = 80;
            }

            Transport            tsp          = Transport.TCP;
            string               endpoint     = "*";
            string               subscription = String.Empty;
            DirectoryInfo        tmpDir       = null;
            List <DirectoryInfo> uploadDirs   = new List <DirectoryInfo>();
            DirectoryInfo        baseDir      = null;
            string               basePath     = null;
            bool             recurseMode      = true;
            List <FileInfo>  files            = new List <FileInfo>();
            HashSet <string> ignoreFiles      = new HashSet <string>();
            HashSet <string> ignoreExtensions = new HashSet <string>();
            bool             listFiles        = false;

            // Set default chunk size to 1MB:
            int chunkSize = 1024 * 1000;
            int ioThreads = 1;
            int hwm       = 32;
            int pgmRate   = 819200;

            Queue <string> argQueue = new Queue <string>(args);

            while (argQueue.Count > 0)
            {
                string arg = argQueue.Dequeue();

                switch (arg)
                {
                case "-a":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-a expects a transport name argument");
                        return;
                    }
                    tsp = (Transport)Enum.Parse(typeof(Transport), argQueue.Dequeue(), true);
                    break;

                case "-e":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-e expects an endpoint argument");
                        return;
                    }
                    endpoint = argQueue.Dequeue();
                    break;

                case "-r":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-r expects a rate limit in kilobits per second argument");
                        return;
                    }

                    Int32.TryParse(argQueue.Dequeue(), out pgmRate);
                    break;

                case "-d":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-d expects a path argument");
                        return;
                    }

                    tmpDir = new DirectoryInfo(argQueue.Dequeue());
                    if (!tmpDir.Exists)
                    {
                        Console.Error.WriteLine("Directory '{0}' does not exist!", tmpDir.FullName);
                        return;
                    }

                    uploadDirs.Add(tmpDir);
                    // Set the base directory to this directory if the base was not already set:
                    if ((baseDir == null) && (uploadDirs.Count == 1))
                    {
                        baseDir  = tmpDir;
                        basePath = baseDir.FullName.EndsWith(Path.DirectorySeparatorChar.ToString()) ? baseDir.FullName : baseDir.FullName + Path.DirectorySeparatorChar;
                    }

                    // Add all files from the given directory, recursively or not, excluding any special '.lcc' download state folders/files:
                    files.AddRange(
                        from fi in (recurseMode ? tmpDir.GetFiles("*.*", SearchOption.AllDirectories) : tmpDir.GetFiles())
                        where fi.Directory.Name != ".lcc"
                        where !ignoreFiles.Contains(fi.FullName.Substring(basePath.Length))
                        where !ignoreFiles.Contains(fi.Name)
                        where !ignoreExtensions.Contains(fi.Extension)
                        select fi
                        );

                    // Now reorder the entire files list:
                    files = (
                        from fi in files
                        orderby fi.FullName
                        select fi
                        ).ToList();
                    break;

                case "-b":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-b expects a path argument");
                        return;
                    }
                    string tmpS = argQueue.Dequeue();
                    baseDir = new DirectoryInfo(tmpS);
                    if (!baseDir.Exists)
                    {
                        Console.Error.WriteLine("Directory '{0}' does not exist!", baseDir.FullName);
                        return;
                    }
                    basePath = baseDir.FullName.EndsWith(Path.DirectorySeparatorChar.ToString()) ? baseDir.FullName : baseDir.FullName + Path.DirectorySeparatorChar;
                    break;

                case "-i":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-i expects a path argument");
                        return;
                    }

                    string ignorePath = argQueue.Dequeue();
                    if (!File.Exists(ignorePath))
                    {
                        Console.Error.WriteLine("Could not open ignore file '{0}'", ignorePath);
                        return;
                    }

                    // Set the ignoreFiles set to all the unique filenames found in the file:
                    string[] lines = File.ReadAllLines(ignorePath);
                    ignoreExtensions = new HashSet <string>(
                        (
                            from line in lines
                            where line.StartsWith("*.")
                            select line.Substring(1)
                        ).Distinct(StringComparer.OrdinalIgnoreCase),
                        StringComparer.OrdinalIgnoreCase
                        );

                    ignoreFiles = new HashSet <string>(
                        lines.Except(ignoreExtensions).Distinct(StringComparer.OrdinalIgnoreCase),
                        StringComparer.OrdinalIgnoreCase
                        );
                    break;

                case "-m":
                    recurseMode = true;
                    break;

                case "-M":
                    recurseMode = false;
                    break;

                case "-s":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-s expects a subscription name argument");
                        return;
                    }
                    subscription = argQueue.Dequeue();
                    break;

                case "-c":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-c expects a chunk size argument");
                        return;
                    }
                    // Override the config with the commandline arg if it can be parsed:
                    Int32.TryParse(argQueue.Dequeue(), out chunkSize);
                    break;

                case "-n":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-s expects a subscription name argument");
                        return;
                    }
                    Int32.TryParse(argQueue.Dequeue(), out ioThreads);
                    break;

                case "-w":
                    if (argQueue.Count == 0)
                    {
                        Console.Error.WriteLine("-w expects a high-water mark argument");
                        return;
                    }
                    Int32.TryParse(argQueue.Dequeue(), out hwm);
                    break;

                case "-t":
                    testMode = true;
                    break;

                case "-?":
                    DisplayUsage();
                    return;

                case "-l":
                    listFiles = true;
                    break;

                default:
                    break;
                }
            }

            if ((uploadDirs.Count == 0) || String.IsNullOrEmpty(subscription))
            {
                DisplayUsage();
                return;
            }

            foreach (var fi in files)
            {
                if (!fi.FullName.StartsWith(basePath, StringComparison.OrdinalIgnoreCase))
                {
                    Console.Error.WriteLine("Directory '{0}' is not underneath the base directory '{1}'!", fi.Directory.FullName, baseDir.FullName);
                    return;
                }
            }

            Console.WriteLine("Serving {0} files from '{1}':", files.Count, basePath);
            Console.WriteLine("{0,15} {1}", "Size (bytes)", "Path");
            foreach (var fi in files)
            {
                string fiName = fi.FullName.Substring(basePath.Length);
                Console.WriteLine("{0,15} {1}", fi.Length.ToString("##,#"), fiName);
            }
            if (listFiles)
            {
                return;
            }

            using (var serverTarball = new TarballStreamWriter(files))
            {
                var server = new LanCaster.ServerHost(tsp, endpoint, subscription, serverTarball, basePath, chunkSize, hwm, pgmRate, testMode);

                Console.WriteLine();
                Console.WriteLine("{0,15} chunks @ {1,13} bytes/chunk", server.NumChunks.ToString("##,#"), server.ChunkSize.ToString("##,#"));

                server.ChunkSent    += new Action <ServerHost, int>(ChunkSent);
                server.ChunksACKed  += new Action <ServerHost>(ChunksACKed);
                server.ClientJoined += new Action <ServerHost, Guid>(ClientJoined);
                server.ClientLeft   += new Action <ServerHost, Guid, ServerHost.ClientLeaveReason>(ClientLeft);

                // Begin the server thread:
                var serverThread = new Thread(server.Run);
                using (Context ctx = new Context(ioThreads))
                {
                    serverThread.Start(ctx);
                    serverThread.Join();
                }
            }
        }
Esempio n. 2
0
        void Run(string[] args)
        {
            try
            {
                consoleWidth = Console.WindowWidth;
            }
            catch (IOException)
            {
                consoleWidth = 80;
            }

            Transport tsp = Transport.TCP;
            string endpoint = "*";
            string subscription = String.Empty;
            DirectoryInfo tmpDir = null;
            List<DirectoryInfo> uploadDirs = new List<DirectoryInfo>();
            DirectoryInfo baseDir = null;
            string basePath = null;
            bool recurseMode = true;
            List<FileInfo> files = new List<FileInfo>();
            HashSet<string> ignoreFiles = new HashSet<string>();
            HashSet<string> ignoreExtensions = new HashSet<string>();
            bool listFiles = false;

            // Set default chunk size to 1MB:
            int chunkSize = 1024 * 1000;
            int ioThreads = 1;
            int hwm = 32;
            int pgmRate = 819200;

            Queue<string> argQueue = new Queue<string>(args);
            while (argQueue.Count > 0)
            {
                string arg = argQueue.Dequeue();

                switch (arg)
                {
                    case "-a":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-a expects a transport name argument");
                            return;
                        }
                        tsp = (Transport)Enum.Parse(typeof(Transport), argQueue.Dequeue(), true);
                        break;
                    case "-e":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-e expects an endpoint argument");
                            return;
                        }
                        endpoint = argQueue.Dequeue();
                        break;
                    case "-r":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-r expects a rate limit in kilobits per second argument");
                            return;
                        }

                        Int32.TryParse(argQueue.Dequeue(), out pgmRate);
                        break;
                    case "-d":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-d expects a path argument");
                            return;
                        }

                        tmpDir = new DirectoryInfo(argQueue.Dequeue());
                        if (!tmpDir.Exists)
                        {
                            Console.Error.WriteLine("Directory '{0}' does not exist!", tmpDir.FullName);
                            return;
                        }

                        uploadDirs.Add(tmpDir);
                        // Set the base directory to this directory if the base was not already set:
                        if ((baseDir == null) && (uploadDirs.Count == 1))
                        {
                            baseDir = tmpDir;
                            basePath = baseDir.FullName.EndsWith(Path.DirectorySeparatorChar.ToString()) ? baseDir.FullName : baseDir.FullName + Path.DirectorySeparatorChar;
                        }

                        // Add all files from the given directory, recursively or not, excluding any special '.lcc' download state folders/files:
                        files.AddRange(
                            from fi in (recurseMode ? tmpDir.GetFiles("*.*", SearchOption.AllDirectories) : tmpDir.GetFiles())
                            where fi.Directory.Name != ".lcc"
                            where !ignoreFiles.Contains(fi.FullName.Substring(basePath.Length))
                            where !ignoreFiles.Contains(fi.Name)
                            where !ignoreExtensions.Contains(fi.Extension)
                            select fi
                        );

                        // Now reorder the entire files list:
                        files = (
                            from fi in files
                            orderby fi.FullName
                            select fi
                        ).ToList();
                        break;
                    case "-b":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-b expects a path argument");
                            return;
                        }
                        string tmpS = argQueue.Dequeue();
                        baseDir = new DirectoryInfo(tmpS);
                        if (!baseDir.Exists)
                        {
                            Console.Error.WriteLine("Directory '{0}' does not exist!", baseDir.FullName);
                            return;
                        }
                        basePath = baseDir.FullName.EndsWith(Path.DirectorySeparatorChar.ToString()) ? baseDir.FullName : baseDir.FullName + Path.DirectorySeparatorChar;
                        break;
                    case "-i":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-i expects a path argument");
                            return;
                        }

                        string ignorePath = argQueue.Dequeue();
                        if (!File.Exists(ignorePath))
                        {
                            Console.Error.WriteLine("Could not open ignore file '{0}'", ignorePath);
                            return;
                        }

                        // Set the ignoreFiles set to all the unique filenames found in the file:
                        string[] lines = File.ReadAllLines(ignorePath);
                        ignoreExtensions = new HashSet<string>(
                            (
                                from line in lines
                                where line.StartsWith("*.")
                                select line.Substring(1)
                            ).Distinct(StringComparer.OrdinalIgnoreCase),
                            StringComparer.OrdinalIgnoreCase
                        );

                        ignoreFiles = new HashSet<string>(
                            lines.Except(ignoreExtensions).Distinct(StringComparer.OrdinalIgnoreCase),
                            StringComparer.OrdinalIgnoreCase
                        );
                        break;
                    case "-m":
                        recurseMode = true;
                        break;
                    case "-M":
                        recurseMode = false;
                        break;
                    case "-s":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-s expects a subscription name argument");
                            return;
                        }
                        subscription = argQueue.Dequeue();
                        break;
                    case "-c":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-c expects a chunk size argument");
                            return;
                        }
                        // Override the config with the commandline arg if it can be parsed:
                        Int32.TryParse(argQueue.Dequeue(), out chunkSize);
                        break;
                    case "-n":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-s expects a subscription name argument");
                            return;
                        }
                        Int32.TryParse(argQueue.Dequeue(), out ioThreads);
                        break;
                    case "-w":
                        if (argQueue.Count == 0)
                        {
                            Console.Error.WriteLine("-w expects a high-water mark argument");
                            return;
                        }
                        Int32.TryParse(argQueue.Dequeue(), out hwm);
                        break;
                    case "-t":
                        testMode = true;
                        break;
                    case "-?":
                        DisplayUsage();
                        return;
                    case "-l":
                        listFiles = true;
                        break;
                    default:
                        break;
                }
            }

            if ((uploadDirs.Count == 0) || String.IsNullOrEmpty(subscription))
            {
                DisplayUsage();
                return;
            }

            foreach (var fi in files)
            {
                if (!fi.FullName.StartsWith(basePath, StringComparison.OrdinalIgnoreCase))
                {
                    Console.Error.WriteLine("Directory '{0}' is not underneath the base directory '{1}'!", fi.Directory.FullName, baseDir.FullName);
                    return;
                }
            }

            Console.WriteLine("Serving {0} files from '{1}':", files.Count, basePath);
            Console.WriteLine("{0,15} {1}", "Size (bytes)", "Path");
            foreach (var fi in files)
            {
                string fiName = fi.FullName.Substring(basePath.Length);
                Console.WriteLine("{0,15} {1}", fi.Length.ToString("##,#"), fiName);
            }
            if (listFiles) return;

            using (var serverTarball = new TarballStreamWriter(files))
            {
                var server = new LanCaster.ServerHost(tsp, endpoint, subscription, serverTarball, basePath, chunkSize, hwm, pgmRate, testMode);

                Console.WriteLine();
                Console.WriteLine("{0,15} chunks @ {1,13} bytes/chunk", server.NumChunks.ToString("##,#"), server.ChunkSize.ToString("##,#"));

                server.ChunkSent += new Action<ServerHost, int>(ChunkSent);
                server.ChunksACKed += new Action<ServerHost>(ChunksACKed);
                server.ClientJoined += new Action<ServerHost, Guid>(ClientJoined);
                server.ClientLeft += new Action<ServerHost, Guid, ServerHost.ClientLeaveReason>(ClientLeft);

                // Begin the server thread:
                var serverThread = new Thread(server.Run);
                using (Context ctx = new Context(ioThreads))
                {
                    serverThread.Start(ctx);
                    serverThread.Join();
                }
            }
        }