コード例 #1
0
ファイル: Models.cs プロジェクト: raghavsethi/bounce-client
        public DownloadProgress(PendingResponse pr)
        {
            transferID          = pr.transferID;
            mac                 = pr.uploader;
            hash                = pr.fileHash;
            fileName            = pr.fileName;
            symKey              = pr.symKey;
            fileSize            = pr.fileSize;
            type                = pr.type;
            nick                = pr.nick;
            averageTransferRate = 0;
            isComplete          = false;
            isFailed            = false;
            isHashMismatch      = false;
            attempts            = 0;

            if (pr.type == "secondleg" || pr.type == "direct")
            {
                downloadedFilePath = Configuration.downloadFolder + "\\" + pr.fileName;
                visible            = true;
            }
            else
            {
                downloadedFilePath = Utils.getAppDataPath(@"\Bounces\" + pr.fileHash + ".bounce");
                visible            = false;
            }
            bytesDownloaded = 0;
            status          = "Starting..";
        }
コード例 #2
0
        public static string postDownload(DownloadProgress dp, PendingResponse pr, BackgroundWorker worker)
        {
            int percentComplete = (int)(100 * dp.bytesDownloaded / pr.fileSize);

            if (dp.isFailed)
            {
                dp.attempts = dp.attempts + 1;
                if (dp.attempts > 10)
                {
                    dp.status = "Failed";
                    dp.isFailedUnrecoverably = true;
                    worker.ReportProgress(percentComplete, dp);
                    return(null);
                }

                dp.status   = "Retrying.. (" + dp.attempts + ")";
                dp.isFailed = false;
                worker.ReportProgress(percentComplete, dp);

                System.Threading.Thread.Sleep(3000);

                return("FAILED");
            }

            BackgroundWorker updateWorker = new BackgroundWorker();

            updateWorker.DoWork             += Downloads.updateWorker_DoWork;
            updateWorker.RunWorkerCompleted += Downloads.updateWorker_RunWorkerCompleted;

            // Set update parameters
            UpdateRequest updateRequest = new UpdateRequest();

            updateRequest.transferID = dp.transferID;
            updateRequest.uploader   = dp.mac;

            if (dp.isCanceled)
            {
                try
                { File.Delete(dp.downloadedFilePath); }
                catch (Exception e2)
                { } // Do nothing. We only want to try and delete the file.

                // Remove from pendingToDownload
                DownloadProgress temp = null;
                pendingToDownload.TryRemove(pr, out temp);

                updateRequest.newHash = dp.hash;
                updateRequest.status  = "canceled";

                updateWorker.RunWorkerAsync(updateRequest);
                return(null);
            }

            // Download neither canceled nor failed

            String newHash = Indexer.GenerateHash(dp.downloadedFilePath);

            if (dp.type == "secondleg" || dp.type == "direct")
            {
                if (newHash == dp.hash)
                {
                    Utils.writeLog("download: Hash verified");
                    dp.isComplete = true;
                    dp.status     = "Completed";
                    worker.ReportProgress(100, dp);

                    // Removing from partially-downloaded-files list
                    Settings.Default.partiallyDownloadedFiles.Replace(dp.downloadedFilePath + "; ", "");
                }
                else
                {
                    Utils.writeLog("download: Hash verification failed");
                    dp.status                = "Failed integrity check";
                    dp.isHashMismatch        = true;
                    dp.isFailed              = true;
                    dp.isFailedUnrecoverably = true;
                    worker.ReportProgress(100, dp);

                    try
                    { File.Delete(dp.downloadedFilePath); }
                    catch (Exception e2)
                    { } // Do nothing. We only want to try and delete the file.
                }

                updateRequest.newHash = newHash;
                updateRequest.status  = "done";

                updateWorker.RunWorkerAsync(updateRequest);

                return(newHash);
            }

            if (dp.type == "firstleg")
            {
                // Rename the file to the new hash

                String newPath = dp.downloadedFilePath.Substring(0, dp.downloadedFilePath.LastIndexOf(@"\"));
                newPath = newPath + "\\" + newHash + ".bounced";

                // Removing from partially-downloaded-files list
                Settings.Default.partiallyDownloadedFiles.Replace(dp.downloadedFilePath + "; ", "");

                try
                {
                    File.Move(dp.downloadedFilePath, newPath);
                }
                catch (Exception e)
                {
                    Utils.writeLog("download: Critical. Unable to rename file to the new hash.");
                }

                dp.status     = "Completed";
                dp.isComplete = true;
                worker.ReportProgress(100, dp);
            }

            updateRequest.newHash = newHash;
            updateRequest.status  = "done";

            updateWorker.RunWorkerAsync(updateRequest);

            return(newHash);
        }
コード例 #3
0
        public static string download(BackgroundWorker worker, PendingResponse pr, DownloadProgress dp, long startByte)
        {
            TcpClient     tcpClient    = new TcpClient();
            NetworkStream clientStream = null;

            try
            {
                tcpClient.Connect(pr.uploaderIP, 8002);

                clientStream = tcpClient.GetStream();
                Utils.writeLog("download: Sending download instruction to peer " + pr.uploaderIP + "...");

                //Format: fileHash | transfer ID | transfer-type
                Utils.writeLog("tid is " + pr.transferID);
                ASCIIEncoding encoder = new ASCIIEncoding();
                byte[]        buffer  = encoder.GetBytes(pr.fileHash + "|" + pr.transferID + "|" + pr.type + "|" + startByte);

                clientStream.Write(buffer, 0, buffer.Length);
                clientStream.Flush();
                Utils.writeLog("download: Download started.");
            }
            catch (Exception e)
            {
                Utils.writeLog("download: Could not establish connection. Error : " + e);
                dp.isFailed = true;
                return(postDownload(dp, pr, worker));
            }

            // Begin file transfer
            FileStream strLocal = null;

            Downloads.currentDownloads.Add(dp);

            // Add the download to the gridview
            worker.ReportProgress(0, dp);

            #region initvars

            long bytesDownloaded = startByte; //Total bytes downloaded for the file
            int  bytesSize;                   //Number of bytes read by the stream reader
            int  tempTransferRate  = 0;       //Instantaneous (for 1 refresh cycle) download rate
            long downloadedInCycle = 0;       //Total bytes downloaded in the last refresh cycle
            int  percentComplete   = 0;

            DateTime startTime = DateTime.Now;  //To track total download time
            DateTime refresh   = DateTime.Now;  //To track time since last refresh

            byte[] downBuffer = new byte[4096];

            bool appendToExistingFile = false;

            // Find a free filename

            if (File.Exists(dp.downloadedFilePath))
            {
                long existingFileLength = new FileInfo(dp.downloadedFilePath).Length;

                // First file found should be appended to
                if (startByte > 0 && startByte == existingFileLength)
                {
                    appendToExistingFile = true;
                }
                else
                {
                    String candidatePath = "";
                    for (int i = 2; i < 100; i++) // 100 here is arbitrary, just want to make sure it doesnt loop forever
                    {
                        candidatePath  = dp.downloadedFilePath.Substring(0, dp.downloadedFilePath.LastIndexOf('.'));
                        candidatePath += " (" + i + ")";
                        candidatePath += dp.downloadedFilePath.Substring(dp.downloadedFilePath.LastIndexOf('.'));

                        if (!File.Exists(candidatePath))
                        {
                            Utils.writeLog("download: Found free file path " + candidatePath);
                            dp.downloadedFilePath = candidatePath;
                            dp.fileName           = dp.downloadedFilePath.Substring(dp.downloadedFilePath.LastIndexOf(@"\") + 1);
                            break;
                        }
                        else
                        {
                            existingFileLength = new FileInfo(candidatePath).Length;
                            if (startByte > 0 && startByte == existingFileLength)
                            {
                                dp.downloadedFilePath = candidatePath;
                                appendToExistingFile  = true;
                                break;
                            }
                        }
                    }
                }
            }

            try
            {
                if (appendToExistingFile)
                {
                    strLocal = new FileStream(dp.downloadedFilePath,
                                              FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
                }
                else
                {
                    strLocal = new FileStream(dp.downloadedFilePath,
                                              FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                }
            }
            catch (Exception e)
            {
                Utils.writeLog("download: Error creating file : " + e);
                // Attempt to recover from error that download folder doesn't exist.
                String filePath   = dp.downloadedFilePath;
                String folderPath = filePath.Substring(0, filePath.LastIndexOf("\\"));
                try
                {
                    System.IO.Directory.CreateDirectory(folderPath);
                    strLocal = new FileStream(dp.downloadedFilePath,
                                              FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                }
                catch (Exception e2)
                {
                    Utils.writeLog("download: Unrecoverable error while creating folder to hold file");
                    MessageBox.Show("Could not download file as the download folder could not be found or created",
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(null);
                }
            }

            Settings.Default.partiallyDownloadedFiles = dp.downloadedFilePath + "; " +
                                                        Settings.Default.partiallyDownloadedFiles;

            #endregion

            try
            {
                // Perform file transfer.
                clientStream.ReadTimeout = 6000; // Need to timeout now to prevent stalled appearance in UI

                while ((bytesSize = clientStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
                {
                    // In case user cancels download
                    if (pendingToDownload[pr] == null || worker.CancellationPending)
                    {
                        throw new DownloadCanceledException("Download canceled");
                    }

                    downloadedInCycle += bytesSize;
                    bytesDownloaded    = bytesDownloaded + bytesSize;
                    dp.bytesDownloaded = bytesDownloaded;
                    strLocal.Write(downBuffer, 0, bytesSize);

                    if (pr.fileSize != 0)
                    {
                        percentComplete = (int)(100 * bytesDownloaded / pr.fileSize);
                    }

                    // Report progress to UI at intervals
                    double msElapsedSinceRefresh = (DateTime.Now - refresh).TotalMilliseconds;
                    if (msElapsedSinceRefresh > 1000)
                    {
                        tempTransferRate = (int)((downloadedInCycle / 1024.0) / (DateTime.Now - refresh).TotalSeconds);

                        dp.status = "Downloading";

                        // Initialize download speed
                        if (dp.averageTransferRate == 0)
                        {
                            dp.averageTransferRate = tempTransferRate;
                        }

                        // Compute download speed with smoothing factor
                        dp.transferRate        = tempTransferRate;
                        dp.averageTransferRate = (0.01) * tempTransferRate + (0.99) * dp.averageTransferRate;

                        worker.ReportProgress(percentComplete, dp);

                        refresh           = DateTime.Now;
                        downloadedInCycle = 0;
                    }
                }

                dp.bytesDownloaded = bytesDownloaded;
                dp.transferRate    = tempTransferRate;
                worker.ReportProgress(100, dp);

                Utils.writeLog("download: Completed download of " + pr.fileName +
                               " (" + dp.fileSize + ") Type:" + dp.type);
                dp.status = "Checking file..";
            }
            catch (DownloadCanceledException dce) // Occurs when user cancels
            {
                Utils.writeLog("download: Canceled by user");
                dp.status     = "Canceled";
                dp.isCanceled = true;
            }
            catch (Exception e) // Should only occur due to poor network/peer going offline
            {
                Utils.writeLog("download: Error:" + e.ToString());
                dp.status   = "Failed";
                dp.isFailed = true;
            }
            finally
            {
                worker.ReportProgress(percentComplete, dp);
                strLocal.Close();
                clientStream.Close();
            }

            return(postDownload(dp, pr, worker));
        }