Пример #1
0
            public SharedFileInfo(Stream s)
            {
                BincodingDecoder decoder = new BincodingDecoder(s, "FI");

                while (true)
                {
                    Bincoding value = decoder.DecodeNext();

                    if (value.Type == BincodingType.NULL)
                    {
                        break;
                    }

                    KeyValuePair <string, Bincoding> pair = value.GetKeyValuePair();

                    switch (pair.Key)
                    {
                    case "file_path":
                        _filePath = pair.Value.GetStringValue();
                        break;

                    case "file_metadata":
                        _fileMetaData = new SharedFileMetaData(pair.Value.GetValueStream());
                        break;

                    case "state":
                        _state = (SharedFileState)pair.Value.GetByteValue();
                        break;

                    case "block_available":
                        _blockAvailable = pair.Value.Value;
                        break;
                    }
                }
            }
Пример #2
0
 public SharedFileInfo(string filePath, SharedFileMetaData fileMetaData, byte[] blockAvailable, SharedFileState state)
 {
     _filePath       = filePath;
     _fileMetaData   = fileMetaData;
     _blockAvailable = blockAvailable;
     _state          = state;
 }
Пример #3
0
        public void Pause()
        {
            if (_state != SharedFileState.Paused)
            {
                _state = SharedFileState.Paused;

                Stop();

                //announce no participation in chats
                SendFileShareUnparticipate();
            }
        }
Пример #4
0
        private void StartSharing()
        {
            if (_state != SharedFileState.Sharing)
            {
                _state = SharedFileState.Sharing;

                //send advertisement
                SendFileAdvertisement();

                //start file transfer speed calculator
                _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000);
            }
        }
Пример #5
0
        private void OnDownloadComplete()
        {
            //verify if all blocks are available
            for (int i = 0; i < _blockAvailable.Length; i++)
            {
                if (_blockAvailable[i] == FILE_BLOCK_NOT_AVAILABLE)
                {
                    return; //found a pending block; do nothing
                }
            }

            //set variables
            _isComplete           = true;
            _state                = SharedFileState.Sharing;
            _availableBlocksCount = _blockAvailable.Length;

            //rename and open file again in read shared mode
            string filePath = _fileStream.Name;

            _fileStream.Close();
            File.SetLastWriteTimeUtc(filePath, _metaData.LastModified);

            string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));

            File.Move(filePath, newFilePath);

            _fileStream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);

            //remove seeders
            _seedersLock.EnterWriteLock();
            try
            {
                _seeders.Clear();
            }
            finally
            {
                _seedersLock.ExitWriteLock();
            }

            //announce advertisement for the complete file to all chats available with same file
            SendBroadcastFileAdvertisement();

            //notify event to UI
            if (FileDownloaded != null)
            {
                RaiseEventFileDownloaded();
            }
        }
Пример #6
0
        public void Pause()
        {
            if (_state != SharedFileState.Paused)
            {
                _state = SharedFileState.Paused;

                Stop();

                //announce no participation in chats
                SendBroadcastFileShareUnparticipate();

                if (FilePaused != null)
                {
                    RaiseEventFilePaused();
                }
            }
        }
Пример #7
0
        private void StartDownload()
        {
            if (_state != SharedFileState.Downloading)
            {
                _state = SharedFileState.Downloading;

                //get file
                if (_fileStream == null)
                {
                    BitChatProfile profile;

                    lock (_chats)
                    {
                        profile = _chats[0].Profile;
                    }

                    //find file name
                    string filePath = Path.Combine(profile.DownloadFolder, _metaData.FileName);

                    int nameCount = 0;

                    while (File.Exists(filePath))
                    {
                        if (nameCount > 10000)
                        {
                            throw new BitChatException("Cannot download file as local file name not available.");
                        }

                        nameCount++;
                        filePath = Path.Combine(profile.DownloadFolder, Path.GetFileNameWithoutExtension(_metaData.FileName) + " [" + nameCount + "]" + Path.GetExtension(_metaData.FileName));
                    }

                    //create file
                    _fileStream = new FileStream(filePath + ".downloading", FileMode.Create, FileAccess.ReadWrite);

                    //pre-allocate file
                    _fileStream.SetLength(_metaData.FileSize);

                    //init block available
                    _blockAvailable       = new byte[_blockAvailable.Length];
                    _availableBlocksCount = 0;
                }

                //list all pending blocks
                if (_pendingBlocks == null)
                {
                    _pendingBlocks   = new List <int>(_blockAvailable.Length);
                    _rndPendingBlock = new Random(DateTime.UtcNow.Second);
                }
                else
                {
                    _pendingBlocks.Clear();
                }

                for (int i = 0; i < _blockAvailable.Length; i++)
                {
                    if (_blockAvailable[i] == FILE_BLOCK_NOT_AVAILABLE)
                    {
                        _pendingBlocks.Add(i);
                    }
                }

                if (_pendingBlocks.Count > 0)
                {
                    //announce file sharing participation in chats
                    SendBroadcastFileShareParticipate();

                    //start block download
                    int totalDownloaders = FILE_BLOCK_DOWNLOAD_THREADS;

                    if (_pendingBlocks.Count < totalDownloaders)
                    {
                        totalDownloaders = _pendingBlocks.Count;
                    }

                    _downloaders = new List <FileBlockDownloader>(totalDownloaders);

                    lock (_downloaders)
                    {
                        for (int i = 0; i < totalDownloaders; i++)
                        {
                            _downloaders.Add(new FileBlockDownloader(this));
                        }
                    }

                    //start file transfer speed calculator
                    _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000);

                    if (FileDownloadStarted != null)
                    {
                        RaiseEventFileDownloadStarted();
                    }
                }
                else
                {
                    OnDownloadComplete();
                }
            }
        }
Пример #8
0
        internal static SharedFile LoadFile(string filePath, SharedFileMetaData metaData, byte[] blockAvailable, SharedFileState state, SynchronizationContext syncCxt)
        {
            //check if file already shared
            lock (_sharedFiles)
            {
                SharedFile sharedFile;

                if (_sharedFiles.ContainsKey(metaData.FileID))
                {
                    sharedFile = _sharedFiles[metaData.FileID];
                }
                else
                {
                    if (state == SharedFileState.Advertisement)
                    {
                        sharedFile = new SharedFile(null, metaData, new byte[metaData.BlockHash.Length], 0, syncCxt);
                        _sharedFiles.Add(metaData.FileID, sharedFile);

                        sharedFile._state = SharedFileState.Advertisement;
                    }
                    else
                    {
                        int availableBlocksCount = 0;

                        for (int i = 0; i < blockAvailable.Length; i++)
                        {
                            if (blockAvailable[i] == FILE_BLOCK_AVAILABLE)
                            {
                                availableBlocksCount++;
                            }
                        }

                        FileStream fS;

                        if (blockAvailable.Length == availableBlocksCount)
                        {
                            fS = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                        }
                        else
                        {
                            fS = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
                        }

                        sharedFile = new SharedFile(fS, metaData, blockAvailable, availableBlocksCount, syncCxt);
                        _sharedFiles.Add(metaData.FileID, sharedFile);

                        sharedFile._state = SharedFileState.Paused;

                        if (state != SharedFileState.Paused)
                        {
                            sharedFile.Start();
                        }
                    }
                }

                return(sharedFile);
            }
        }
Пример #9
0
        private void OnBlockDownloaded(FileBlockDownloadManager downloadedBlock)
        {
            lock (_downloadingBlocks)
            {
                if (_downloadingBlocks.Remove(downloadedBlock))
                {
                    if (WriteBlock(downloadedBlock))
                    {
                        //block downloaded
                        //Debug.Write("SharedFile.BlockDownloaded", "block: " + downloadedBlock.BlockNumber);

                        if (BlockDownloaded != null)
                        {
                            RaiseEventBlockDownloaded();
                        }
                    }
                    else
                    {
                        //block download fail/corrupt; add block again in pending list
                        lock (_pendingBlocks)
                        {
                            _pendingBlocks.Add(downloadedBlock.BlockNumber);
                        }
                    }

                    //start new block download
                    FileBlockDownloadManager newDownload = GetRandomDownloadBlock();
                    if (newDownload != null)
                    {
                        _downloadingBlocks.Add(newDownload);
                    }

                    if (_downloadingBlocks.Count == 0)
                    {
                        //download COMPLETED!

                        //set variables
                        _isComplete           = true;
                        _state                = SharedFileState.Sharing;
                        _availableBlocksCount = _blockAvailable.Length;

                        //stop download monitor
                        _downloadMonitor.Dispose();
                        _downloadMonitor = null;

                        //rename and open file again in read shared mode
                        string filePath = _fileStream.Name;

                        _fileStream.Close();
                        File.SetLastWriteTimeUtc(filePath, _metaData.LastModified);

                        string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                        File.Move(filePath, newFilePath);

                        _fileStream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);

                        //remove seeders
                        lock (_seeders)
                        {
                            _seeders.Clear();
                        }

                        //announce advertisement for the complete file to all chats available with same file
                        SendFileAdvertisement();

                        //notify event to UI
                        //Debug.Write("SharedFile.BlockDownloaded", "COMPLETED!");

                        if (FileDownloaded != null)
                        {
                            RaiseEventFileDownloaded();
                        }
                    }
                }
            }
        }
Пример #10
0
        private void StartDownload()
        {
            if (_state != SharedFileState.Downloading)
            {
                _state = SharedFileState.Downloading;

                //get file
                if (_fileStream == null)
                {
                    //find file name
                    string filePath = Path.Combine(_profile.DownloadFolder, _metaData.FileName);

                    int nameCount = 0;

                    while (File.Exists(filePath))
                    {
                        if (nameCount > 10000)
                        {
                            throw new BitChatException("Cannot download file as local file name not available.");
                        }

                        nameCount++;
                        filePath = Path.Combine(_profile.DownloadFolder, Path.GetFileNameWithoutExtension(_metaData.FileName) + " [" + nameCount + "]" + Path.GetExtension(_metaData.FileName));
                    }

                    //create file
                    _fileStream = new FileStream(filePath + ".downloading", FileMode.Create, FileAccess.ReadWrite);

                    //pre-allocate file
                    _fileStream.SetLength(_metaData.FileSize);

                    //init block available
                    _blockAvailable       = new FileBlockState[_blockAvailable.Length];
                    _availableBlocksCount = 0;
                }

                //list all pending blocks
                if (_pendingBlocks == null)
                {
                    _pendingBlocks   = new List <int>(_blockAvailable.Length);
                    _rndPendingBlock = new Random(DateTime.UtcNow.Second);

                    for (int i = 0; i < _blockAvailable.Length; i++)
                    {
                        if (_blockAvailable[i] != FileBlockState.Available)
                        {
                            _pendingBlocks.Add(i);
                        }
                    }
                }

                //announce file sharing participation in chats
                SendFileShareParticipate();

                //start block download
                _downloadingBlocks = new List <FileBlockDownloadManager>(TOTAL_DOWNLOAD_BLOCKS);

                lock (_downloadingBlocks)
                {
                    for (int i = 0; i < TOTAL_DOWNLOAD_BLOCKS; i++)
                    {
                        FileBlockDownloadManager download = GetRandomDownloadBlock();

                        if (download == null)
                        {
                            break;
                        }

                        _downloadingBlocks.Add(download);
                    }
                }

                //start file transfer speed calculator
                _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000);

                //start download monitor
                _downloadMonitor = new Timer(DownloadMonitorAsync, null, DOWNLOAD_MONITOR_INTERVAL, Timeout.Infinite);

                if (FileDownloadStarted != null)
                {
                    RaiseEventFileDownloadStarted();
                }
            }
        }
Пример #11
0
        private void StartSharing()
        {
            if (_state != SharedFileState.Sharing)
            {
                _state = SharedFileState.Sharing;

                //send advertisement
                SendFileAdvertisement();

                //start file transfer speed calculator
                _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000);
            }
        }
Пример #12
0
        private void StartDownload()
        {
            if (_state != SharedFileState.Downloading)
            {
                _state = SharedFileState.Downloading;

                //get file
                if (_fileStream == null)
                {
                    //find file name
                    string filePath = Path.Combine(_profile.DownloadFolder, _metaData.FileName);

                    int nameCount = 0;

                    while (File.Exists(filePath))
                    {
                        if (nameCount > 10000)
                            throw new BitChatException("Cannot download file as local file name not available.");

                        nameCount++;
                        filePath = Path.Combine(_profile.DownloadFolder, Path.GetFileNameWithoutExtension(_metaData.FileName) + " [" + nameCount + "]" + Path.GetExtension(_metaData.FileName));
                    }

                    //create file
                    _fileStream = new FileStream(filePath + ".downloading", FileMode.Create, FileAccess.ReadWrite);

                    //pre-allocate file
                    _fileStream.SetLength(_metaData.FileSize);

                    //init block available
                    _blockAvailable = new FileBlockState[_blockAvailable.Length];
                    _availableBlocksCount = 0;
                }

                //list all pending blocks
                if (_pendingBlocks == null)
                {
                    _pendingBlocks = new List<int>(_blockAvailable.Length);
                    _rndPendingBlock = new Random(DateTime.UtcNow.Second);

                    for (int i = 0; i < _blockAvailable.Length; i++)
                    {
                        if (_blockAvailable[i] != FileBlockState.Available)
                            _pendingBlocks.Add(i);
                    }
                }

                //announce file sharing participation in chats
                SendFileShareParticipate();

                //start block download
                _downloadingBlocks = new List<FileBlockDownloadManager>(TOTAL_DOWNLOAD_BLOCKS);

                lock (_downloadingBlocks)
                {
                    for (int i = 0; i < TOTAL_DOWNLOAD_BLOCKS; i++)
                    {
                        FileBlockDownloadManager download = GetRandomDownloadBlock();

                        if (download == null)
                            break;

                        _downloadingBlocks.Add(download);
                    }
                }

                //start file transfer speed calculator
                _fileTransferSpeedCalculator = new Timer(FileTransferSpeedCalculatorAsync, null, 1000, 1000);

                //start download monitor
                _downloadMonitor = new Timer(DownloadMonitorAsync, null, DOWNLOAD_MONITOR_INTERVAL, Timeout.Infinite);

                if (FileDownloadStarted != null)
                    RaiseEventFileDownloadStarted();
            }
        }
Пример #13
0
        private void OnBlockDownloaded(FileBlockDownloadManager downloadedBlock)
        {
            lock (_downloadingBlocks)
            {
                if (_downloadingBlocks.Remove(downloadedBlock))
                {
                    if (WriteBlock(downloadedBlock))
                    {
                        //block downloaded
                        //Debug.Write("SharedFile.BlockDownloaded", "block: " + downloadedBlock.BlockNumber);

                        if (BlockDownloaded != null)
                            RaiseEventBlockDownloaded();
                    }
                    else
                    {
                        //block download fail/corrupt; add block again in pending list
                        lock (_pendingBlocks)
                        {
                            _pendingBlocks.Add(downloadedBlock.BlockNumber);
                        }
                    }

                    //start new block download
                    FileBlockDownloadManager newDownload = GetRandomDownloadBlock();
                    if (newDownload != null)
                        _downloadingBlocks.Add(newDownload);

                    if (_downloadingBlocks.Count == 0)
                    {
                        //download COMPLETED!

                        //set variables
                        _isComplete = true;
                        _state = SharedFileState.Sharing;
                        _availableBlocksCount = _blockAvailable.Length;

                        //stop download monitor
                        _downloadMonitor.Dispose();
                        _downloadMonitor = null;

                        //rename and open file again in read shared mode
                        string filePath = _fileStream.Name;

                        _fileStream.Close();
                        File.SetLastWriteTimeUtc(filePath, _metaData.LastModified);

                        string newFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath));
                        File.Move(filePath, newFilePath);

                        _fileStream = new FileStream(newFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);

                        //remove seeders
                        lock (_seeders)
                        {
                            _seeders.Clear();
                        }

                        //announce advertisement for the complete file to all chats available with same file
                        SendFileAdvertisement();

                        //notify event to UI
                        //Debug.Write("SharedFile.BlockDownloaded", "COMPLETED!");

                        if (FileDownloaded != null)
                            RaiseEventFileDownloaded();
                    }
                }
            }
        }
Пример #14
0
        public void Pause()
        {
            if (_state != SharedFileState.Paused)
            {
                _state = SharedFileState.Paused;

                Stop();

                //announce no participation in chats
                SendFileShareUnparticipate();
            }
        }