public HttpResponseMessage GetInfo(ClientBasicInfo clientBasicInfo)
        {
            var productName           = clientBasicInfo.ProductName;
            var revitVersion          = clientBasicInfo.RevitVersion;
            var currentProductVersion = clientBasicInfo.CurrentProductVersion;

            //ProductName_RevitVersion_OldProductVersion_NewProductVersion
            var latestFilePath = ServerFileUtils.GetLatestFilePath(productName, revitVersion, currentProductVersion);

            if (string.IsNullOrEmpty(latestFilePath) || !File.Exists(latestFilePath))
            {
                return(null);
            }

            var latestFile   = new FileInfo(latestFilePath);
            var downloadInfo = new DownloadFileInfo()
            {
                LatestProductVersion  = ServerFileUtils.GetLatestVersion(Path.GetFileNameWithoutExtension(latestFilePath)),
                DownloadFileMd5       = Md5Utils.GetFileMd5(latestFilePath),
                DownloadFileTotalSize = latestFile.Length
            };
            HttpResponseMessage response = new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new StringContent(JsonConvert.SerializeObject(downloadInfo), Encoding.GetEncoding("UTF-8"), "application/json")
            };

            return(response);
        }
        //TestFile directory is used to Test socket
        //See Socket_APM-SAEA\TestFile
        static void Main(string[] args)
        {
            var mainFolder = AppDomain.CurrentDomain.BaseDirectory.Replace("bin", "TestFile");

            ClientBasicInfo basicInfo = new ClientBasicInfo()
            {
                ProductName           = "Airforce094",
                RevitVersion          = "Revit2016",
                CurrentProductVersion = "18.1.6"
            };

            var serverFilePath = Path.Combine(mainFolder, "Server\\Airforce094_Revit2016_18.1.6_18.1.7.zip");

            DownloadFileInfo dlInfo = new DownloadFileInfo()
            {
                LatestProductVersion  = "18.1.7",
                DownloadFileMd5       = Md5Utils.GetFileMd5(serverFilePath),
                DownloadFileTotalSize = new FileInfo(serverFilePath).Length
            };

            ClientLinkInfo clInfo = new ClientLinkInfo()
            {
                IpString = "127.0.0.1",
                Port     = 8885
            };

            var localSavePath = Path.Combine(mainFolder, "Local");
            var tempFilesDir  = Path.Combine(mainFolder, "TempFile");
            var cs            = new ClientSocket();
            var result        = cs.StartClient(basicInfo, dlInfo, clInfo, localSavePath, tempFilesDir);

            Console.WriteLine(result);
            Console.ReadKey();
        }
        public bool StartClient(ClientBasicInfo basicInfo, DownloadFileInfo dlInfo, ClientLinkInfo clInfo,
                                string localSaveFolderPath, string tempFilesDir)
        {
            if (basicInfo == null || dlInfo == null || clInfo == null ||
                string.IsNullOrEmpty(localSaveFolderPath) || string.IsNullOrEmpty(tempFilesDir))
            {
                return(false);
            }
            if (!Directory.Exists(localSaveFolderPath))
            {
                Directory.CreateDirectory(localSaveFolderPath);
            }
            if (!Directory.Exists(tempFilesDir))
            {
                Directory.CreateDirectory(tempFilesDir);
            }
            else
            {
                DirectoryInfo di = new DirectoryInfo(tempFilesDir);
                di.Delete(true);
                Directory.CreateDirectory(tempFilesDir);
            }


            var updateFileName = $"{basicInfo.ProductName}_{basicInfo.RevitVersion}_{basicInfo.CurrentProductVersion}_{dlInfo.LatestProductVersion}";

            _updateFileName = updateFileName;

            var localSavePath         = Path.Combine(localSaveFolderPath, $"{updateFileName}.zip");
            var downloadChannelsCount = DownloadSetting.DownloadChannelsCount;

            _downloadChannelsCount = downloadChannelsCount;

            try
            {
                IPAddress  ipAddress = IPAddress.Parse(clInfo.IpString);
                IPEndPoint remoteEp  = new IPEndPoint(ipAddress, clInfo.Port);

                int  packetCount = downloadChannelsCount;
                long packetSize  = dlInfo.DownloadFileTotalSize / packetCount;
                _packSize = packetSize;


                var tasks = new Task[packetCount];
                for (int index = 0; index < packetCount; index++)
                {
                    int packetNumber = index;
                    var task         = new Task(() =>
                    {
                        Socket client   = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        ComObject state = new ComObject {
                            WorkSocket = client, PacketNumber = packetNumber
                        };
                        client.BeginConnect(remoteEp, ConnectCallback, state);
                    });
                    tasks[packetNumber] = task;
                    task.Start();
                }
                Task.WaitAll(tasks);
                ReceiveDone.WaitOne();


                _isPacketsComplete = CheckPackets(TempReceivePacketDict, _downloadChannelsCount);
                CloseSockets(TempReceivePacketDict);
                if (_isPacketsComplete)
                {
                    GenerateTempFiles(ResultPacketDict, downloadChannelsCount, tempFilesDir);
                    FileUtils.CombineTempFiles(localSavePath, tempFilesDir);
                    return(Md5Utils.IsMd5Equal(dlInfo.DownloadFileMd5, Md5Utils.GetFileMd5(localSavePath)));
                }
                return(false);
            }
            catch (Exception ex)
            {
                return(false);
            }
        }