Пример #1
0
        /// <summary>
        /// 接收文件
        /// </summary>
        /// <param name="saveFilePath">文件完整路径</param>
        public void ReceiverFile(string saveFilePath)
        {
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            listener.Bind(BigFileTransferDescription.ServiceIP);
            listener.Listen(BigFileTransferDescription.MaxThreadCount);
            var receiveWorker = new BigFileReceiveWorker(listener.Accept());

            //计时器
            watcher.Start();

            //接收相关流到缓冲区
            int    recv       = receiveWorker.Client.Receive(receiveWorker.Buffer);
            long   fileLength = BitConverter.ToInt64(receiveWorker.Buffer, 0);
            string fileName   = Encoding.Default.GetString(receiveWorker.Buffer, BigFileTransferDescription.PerLongCount, recv - BigFileTransferDescription.PerLongCount);

            Console.WriteLine("Receiveing file:" + fileName + ".Plz wait...");

            //获取当前文件接收线程数
            int threadCount = SocketFileTransferUtility.GetThreadCount(fileLength);

            BigFileReceiveWorker[] workers = new BigFileReceiveWorker[threadCount];
            try
            {
                for (int i = 0; i < threadCount; i++)
                {
                    workers[i] = i == 0 ? receiveWorker : new BigFileReceiveWorker(listener.Accept());
                }

                #region Breakpoint 断点续传

                int        perPairCount = BigFileTransferDescription.PerLongCount * 2, count = perPairCount * threadCount;
                byte[]     bufferInfo = new byte[count];
                string     filePath = Path.Combine(saveFilePath, fileName), pointFilePath = Path.ChangeExtension(filePath, BigFileTransferDescription.PointExtension), tempFilePath = Path.ChangeExtension(filePath, BigFileTransferDescription.TempExtension);
                FileStream pointStream;
                long       oddSize, avgSize = Math.DivRem(fileLength, (long)threadCount, out oddSize);
                if (File.Exists(pointFilePath) && File.Exists(tempFilePath))
                {
                    pointStream = new FileStream(pointFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                    pointStream.Read(bufferInfo, 0, count);
                    long w, t;
                    for (int i = 0; i < threadCount; i++)
                    {
                        SocketFileTransferUtility.ReadFile(out w, bufferInfo, i * perPairCount);
                        SocketFileTransferUtility.ReadFile(out t, bufferInfo, i * perPairCount + BigFileTransferDescription.PerLongCount);
                        workers[i].Initialize(tempFilePath, i * avgSize, i == threadCount - 1 ? avgSize + oddSize : avgSize, w, t);
#if BreakpointLog
                        AppendTransmitLog(LogType.Breakpoint, i + " read:" + w + "/" + t + ".");
#endif
                    }
                    receiveWorker.Client.Send(bufferInfo);
                }
                else
                {
                    pointStream = new FileStream(pointFilePath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None);
                    FileStream stream = new FileStream(tempFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.Write);
                    stream.SetLength(fileLength);
                    stream.Flush();
                    stream.Dispose();
                    for (int i = 0; i < threadCount; i++)
                    {
                        workers[i].Initialize(tempFilePath, i * avgSize, i == threadCount - 1 ? avgSize + oddSize : avgSize);
                    }
                    receiveWorker.Client.Send(bufferInfo, 0, 4, SocketFlags.None);
                }

                //计时器--异步执行
                Timer timer = new Timer(state =>
                {
                    long w, t;
                    for (int i = 0; i < threadCount; i++)
                    {
                        workers[i].ReportProgress(out w, out t);
                        SocketFileTransferUtility.WriteFile(w, bufferInfo, i * perPairCount);
                        SocketFileTransferUtility.WriteFile(t, bufferInfo, i * perPairCount + BigFileTransferDescription.PerLongCount);
#if BreakpointLog
                        AppendTransmitLog(LogType.Breakpoint, i + " write:" + w + "/" + t + ".");
#endif
                    }
                    pointStream.Position = 0L;
                    pointStream.Write(bufferInfo, 0, count);
                    pointStream.Flush();
                }, null, TimeSpan.Zero, TimeSpan.FromSeconds(2));

                #endregion

                //线程同步锁
                AutoResetEvent reset = new AutoResetEvent(true);
                for (int i = 0; i < threadCount; i++)
                {
                    workers[i].RunWork(i == threadCount - 1 ? reset : null);
                }
                reset.WaitOne();

                #region Breakpoint 断点续传

                int  speed;
                long value = 0L;
                do
                {
                    speed = workers.ReportSpeed(ref value);
                    Console.WriteLine("waiting for other threads. Progress:" + value + "/" + fileLength + ";Speed:" + speed + "kb/s.");
                    Thread.Sleep(500);
                }while (!workers.IsAllFinished());
                speed = workers.ReportSpeed(ref value);
                Console.WriteLine("waiting for other threads. Progress:" + value + "/" + fileLength + ";Speed:" + speed + "kb/s.");
                timer.Dispose();
                pointStream.Dispose();
                File.Delete(pointFilePath);
                File.Move(tempFilePath, filePath);
                #endregion
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件传输过程中出现错误:" + ex.InnerException == null ? ex.Message : ex.InnerException.Message);
            }

            watcher.Stop();
            Console.WriteLine("Receive finish.Span Time:" + watcher.Elapsed.TotalMilliseconds + " ms.");
        }
Пример #2
0
        public void SendFile(string filePath)
        {
            //启动监视器
            watcher.Start();

            //获取文件信息
            FileInfo file = new FileInfo(filePath);

#if DEBUG
            if (!file.Exists) //Debug 模式下抛出异常
            {
                throw new FileNotFoundException();
            }
#endif
            //多线程处理器
            BigFileSendWorker worker = new BigFileSendWorker(BigFileTransferDescription.ServiceIP);
            long fileLength          = file.Length;
            Buffer.BlockCopy(BitConverter.GetBytes(fileLength), 0, worker.Buffer, 0, BigFileTransferDescription.PerLongCount);
            string fileName = file.Name;
            worker.Client.Send(worker.Buffer, 0, BigFileTransferDescription.PerLongCount + Encoding.Default.GetBytes(fileName, 0, fileName.Length, worker.Buffer, BigFileTransferDescription.PerLongCount), SocketFlags.None);
            Console.WriteLine("Sending file:" + fileName + ".Plz wait...");

            int threadCount = SocketFileTransferUtility.GetThreadCount(fileLength);

            BigFileSendWorker[] workers = new BigFileSendWorker[threadCount];

            try
            {
                for (int i = 0; i < threadCount; i++)
                {
                    workers[i] = i == 0 ? worker : new BigFileSendWorker(BigFileTransferDescription.ServiceIP);
                }

                #region Breakpoint 断点续传

                int    perPairCount = BigFileTransferDescription.PerLongCount * 2, count = perPairCount * threadCount;
                byte[] bufferInfo = new byte[count];
                long   oddSize, avgSize = Math.DivRem(fileLength, (long)threadCount, out oddSize);
                if (worker.Client.Receive(bufferInfo) == 4)
                {
                    for (int i = 0; i < threadCount; i++)
                    {
                        workers[i].Initialize(filePath, i * avgSize, i == threadCount - 1 ? avgSize + oddSize : avgSize);
                    }
                }
                else
                {
                    long w, t;
                    for (int i = 0; i < threadCount; i++)
                    {
                        SocketFileTransferUtility.ReadFile(out w, bufferInfo, i * perPairCount);
                        SocketFileTransferUtility.ReadFile(out t, bufferInfo, i * perPairCount + BigFileTransferDescription.PerLongCount);
                        workers[i].Initialize(filePath, i * avgSize, i == threadCount - 1 ? avgSize + oddSize : avgSize, w, t);
#if BreakpointLog
                        AppendTransmitLog(LogType.Breakpoint, i + " read:" + w + "/" + t + ".");
#endif
                    }
                }

                Thread.Sleep(100);

                #endregion

                //线程同步锁
                AutoResetEvent reset = new AutoResetEvent(true);
                for (int i = 0; i < threadCount; i++)
                {
                    workers[i].RunWork(i == threadCount - 1 ? reset : null);
                }
                reset.WaitOne();
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件传输过程中出现错误:" + ex.InnerException == null ? ex.Message : ex.InnerException.Message);
            }

            #region Breakpoint 断点续传

            int  speed;
            long value = 0L;
            do
            {
                speed = workers.ReportSpeed(ref value);
                Console.WriteLine("waiting for other threads. Progress:" + value + "/" + fileLength + ";Speed:" + speed + "kb/s.");
                Thread.Sleep(500);
            }while (!workers.IsAllFinished());
            speed = workers.ReportSpeed(ref value);
            Console.WriteLine("waiting for other threads. Progress:" + value + "/" + fileLength + ";Speed:" + speed + "kb/s.");

            #endregion

            watcher.Stop();
            Console.WriteLine("Send finish.Span Time:" + watcher.Elapsed.TotalMilliseconds + " ms.");
        }