public static void SupperReceive(Socket client, string path, ReceiveWorker worker, Action <string, int, bool, double> statusHandler = null, Action <string, long> speedHandler = null) { try { Stopwatch watcher = new Stopwatch(); watcher.Start(); int recv = worker.Client.Receive(worker.Buffer); long fileLength = BitConverter.ToInt64(worker.Buffer, 0); string fileName = Encoding.Default.GetString(worker.Buffer, PerLongCount, recv - PerLongCount); Console.WriteLine("Receiveing file:" + fileName + ".Plz wait..."); int threadCount = GetThreadCount(fileLength); ReceiveWorker[] workers = new ReceiveWorker[threadCount]; for (int i = 0; i < threadCount; i++) { if (i == 0) { workers[i] = worker; } else { workers[i] = new ReceiveWorker(client); } } int perPairCount = PerLongCount * 2, count = perPairCount * threadCount; byte[] bufferInfo = new byte[count]; string filePath = Path.Combine(path, fileName), pointFilePath = filePath + PointExtension, tempFilePath = filePath + 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++) { Read(out w, bufferInfo, i * perPairCount); Read(out t, bufferInfo, i * perPairCount + PerLongCount); workers[i].Initialize(tempFilePath, i * avgSize, i == threadCount - 1 ? avgSize + oddSize : avgSize, w, t); } worker.Client.Send(bufferInfo); } else { pointStream = new FileStream(pointFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); FileStream stream = new FileStream(tempFilePath, FileMode.Create, 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); } worker.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); Write(w, bufferInfo, i * perPairCount); Write(t, bufferInfo, i * perPairCount + PerLongCount); } pointStream.Position = 0L; pointStream.Write(bufferInfo, 0, count); pointStream.Flush(); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(2)); AutoResetEvent reset = new AutoResetEvent(true); for (int i = 0; i < threadCount; i++) { workers[i].RunWork(i == threadCount - 1 ? reset : null); } reset.WaitOne(); string id = client.LocalEndPoint.ToString() + "|" + fileName; long speed; long diff; long value = 0L; int percent; double ms0 = watcher.ElapsedMilliseconds; do { Thread.Sleep(500); diff = workers.ReportSpeed(ref value, out percent); double ms1 = watcher.ElapsedMilliseconds; speed = (long)((diff * 1000) / (ms1 - ms0)); Console.WriteLine("waiting for other threads. Progress:" + value + "/" + fileLength + ";Speed:" + Common.ByteConvertToGBMBKB(speed) + "/S."); //int percent = (int)Math.Round(value * 100.0 / fileLength); if (speedHandler != null) { speedHandler.Invoke(id, speed); } if (statusHandler != null) { statusHandler.Invoke(id, percent, false, ms1); } ms0 = watcher.ElapsedMilliseconds; }while (!workers.IsAllFinished()); timer.Dispose(); pointStream.Dispose(); File.Delete(pointFilePath); File.Copy(tempFilePath, filePath, true); File.Delete(tempFilePath); watcher.Stop(); Console.WriteLine("Receive finish.Span Time:" + watcher.Elapsed.TotalMilliseconds + " ms."); if (speedHandler != null) { speedHandler.Invoke(id, speed); } if (statusHandler != null) { statusHandler.Invoke(id, 100, true, watcher.Elapsed.TotalMilliseconds); } } catch (Exception e) { Console.WriteLine("接收出错:" + e.Message); } }