/// <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."); }
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."); }