private void Download(IAsyncResult iar) { try { client.EndConnect(iar); } catch (SocketException) { #region load Server IPEndPoint remoteendpoint = (IPEndPoint)iar.AsyncState; time.Stop();//停止计时 try { if (LoadServer(remoteendpoint)) { client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); time.Start();//开始计时 client.BeginConnect(remoteendpoint, new AsyncCallback(Download), client); } else { SetControlText(labelInfo, labelCanNotConnect.Text);// SetState(State.Idle); } return; } catch (ObjectDisposedException) { SetControlText(labelInfo, labelUpdateCancel.Text); SetState(State.Idle); time.Stop(); return; } #endregion } catch (ObjectDisposedException) { SetControlText(labelInfo, labelUpdateCancel.Text); SetState(State.Idle); time.Stop(); return; } time.Stop();//停止计时 FileInfoCollection fc = new FileInfoCollection(); if (true)//是否只更新有修改过的文件 { try { fc.Load(Config.WorkPath); if (File.Exists("Resume.xml")) //存在续传记录 { if (MessageBox.Show(this, labelResume.Text, "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { XmlDocument xmlresume = new XmlDocument(); try { xmlresume.Load("Resume.xml"); XmlNode noderesume = xmlresume.SelectSingleNode("Resume/FileResume"); int id = Convert.ToInt32(noderesume.Attributes["ID"].Value); DateTime date = Convert.ToDateTime(noderesume.Attributes["Date"].Value); int length = Convert.ToInt32(noderesume.Attributes["Length"].Value); int offset = Convert.ToInt32(noderesume.Attributes["Offset"].Value); fc.SetFiletoResumeInfo(id, date, length, offset); } catch { } } else//清空临时文件夹 { Directory.Delete("temp", true); Directory.CreateDirectory("temp"); } } } catch { fc.Clear(); } File.Delete("Resume.xml"); } time.Start();//开启计时 byte[] xml = fc.SaveToBuffer(); MessageBuffer buf = new MessageBuffer(MessageType.RequeryFile, 0, 0, xml.Length); FileStream fs = null; buf.SetFileBytes(xml); int fileid = 0; //记录当前下载的文件ID int fileoffset = 0;//记录当前下载的文件偏移量 try { client.Send(buf.GetBytes());//发送已经存在文件列表 SetControlText(labelInfo, labelDownloadingList.Text); int filelength = 0;//记录所有文件的大小 int filelengthfinished = 0; //记录已经完成的文件的大小 byte[] btbufundecoded = new byte[0];//存放上次未处理的娄组 while (true) { byte[] bufmax = new byte[Config.MAX_LENGTH];//存放接收到的数组 int length = client.Receive(bufmax);//接收数据 time.Restart();//重启计时 //重写算法 byte[] btbuf = new byte[length + btbufundecoded.Length];//存放接收到及未处理的数组 if (btbufundecoded.Length > 0) { Buffer.BlockCopy(btbufundecoded, 0, btbuf, 0, btbufundecoded.Length);//将未完成的字节加入队列的开始 } Buffer.BlockCopy(bufmax, 0, btbuf, btbufundecoded.Length, length);//加入接收到的字节 int bufindex = 0; bool iscompleted = true; while (bufindex < btbuf.Length) //全部处理完也要跳出循环 { btbufundecoded = new byte[0];//清空 byte[] btmb = new byte[btbuf.Length - bufindex]; Buffer.BlockCopy(btbuf, bufindex, btmb, 0, btmb.Length);//将已经处理完的字节移出 MessageBuffer mb = new MessageBuffer(btmb); iscompleted = mb.Completed;//判断这个Message是否完整 if (!mb.Completed)//是否完整 { btbufundecoded = btmb; break;//跳出循环,未处理的在下次接收后一同处理 } else { bufindex += mb.FileLength + 13;//修改已经处理的位置 switch (mb.Header) { case MessageType.SendFileList: Config.LocalFiles.Load(mb.GetFileBytes()); filelength = Config.LocalFiles.Length; break; case MessageType.SendFile: { if (fileid != mb.FileID) //新文件 { fileid = mb.FileID; fileoffset = mb.FileOffSet; if (fs != null) { fs.Close();//写回到文件 } fs = new FileStream(string.Format("temp\\{0}.tmp", fileid), FileMode.OpenOrCreate); SetControlText(labelInfo, labelDownloading.Text + Config.LocalFiles[fileid].ToString()); } fs.Position = mb.FileOffSet; fs.Write(mb.GetFileBytes(), 0, mb.FileLength);//写入到流 fileoffset += mb.FileLength; filelengthfinished += mb.FileLength; SetProgressBarValue(progressBarDetail, (int)((double)fileoffset / (double)Config.LocalFiles[fileid].Length * 100)); SetProgressBarValue(progressBarTotal, (int)((double)filelengthfinished / (double)filelength * 100)); //刷新进度条 if (fileoffset == Config.LocalFiles[fileid].Length)//完成这个文件 { fs.Close();//从流写回到文件 fs = null; string filename = Config.WorkPath + Config.LocalFiles[fileid].ToString(); if (!Directory.Exists(Path.GetDirectoryName(filename)))//创建目的文件夹 { Directory.CreateDirectory(Path.GetDirectoryName(filename)); } if (File.Exists(filename))//如果文件存在则删除 { File.Delete(filename); } File.Move(string.Format("temp\\{0}.tmp", mb.FileID), filename);//移动文件到目的文件夹 File.SetLastWriteTime(filename, Config.LocalFiles[fileid].Date);//设置最后修改时间 Config.LocalFiles.Remove(fileid); } break; } case MessageType.SendFinished: if (true) { client.Send(MessageBuffer.ReceiveFinished.GetBytes()); } else// 用来申请某个文件中的一部分,可能用不到 { //MessageBuffer mbreqblock = new MessageBuffer(MessageType.RequeryBlock, "id", "offset", "length"); //client.Send(mbreqblock.GetBytes()); } if (filelength == 0) { SetControlText(labelInfo, labelNoUpdateFound.Text); } else { SetControlText(labelInfo, labelUpdateFinished.Text); } SetProgressBarValue(progressBarDetail, 100); SetProgressBarValue(progressBarTotal, 100); client.Shutdown(SocketShutdown.Both); client.Close(100); if (true) { if (File.Exists(Config.WorkPath + "\\" + Config.PreInstall) && !Config.CheckPreInstall()) { try { System.Diagnostics.Process pro = System.Diagnostics.Process.Start(Config.WorkPath + "\\" + Config.PreInstall); pro.WaitForInputIdle(); } catch { } } try { if (CurrentSolution != null) { XmlDocument clientxml = CreateClientXml(CurrentSolution); clientxml.Save(Config.WorkPath + @"\EEPNetClient.xml"); } } catch(Exception e) { SetMessageBox(e.Message); } try { String S = CurrentSolution.Language.ToString() + " " + CurrentSolution.IP + " " + CurrentSolution.ApPort.ToString(); System.Diagnostics.Process pro = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(Config.WorkPath + "\\" + Config.LaunchPath, S)); pro.WaitForInputIdle(); SetState(State.Idle); //Application.Exit(); } catch(Exception e) { SetMessageBox(e.Message); } } return; } } } } } catch (Exception e)//有些文件在copy时会有权限问题,还查不出 { if (client.Connected) { client.Send(MessageBuffer.ReceiveFinished.GetBytes()); } if (buttonStart.Text == labelStart.Text) { SetControlText(labelInfo, labelUpdateCancel.Text); if (fileid != 0 && fileoffset != Config.LocalFiles[fileid].Length)//当前文件未完成 { //存入文件 XmlDocument xmlresume = new XmlDocument(); XmlNode nodedoc = xmlresume.CreateElement("Resume"); xmlresume.AppendChild(nodedoc); XmlNode nodefileresume = xmlresume.CreateElement("FileResume"); XmlAttribute att = xmlresume.CreateAttribute("ID"); att.Value = fileid.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Offset"); att.Value = fileoffset.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Date"); att.Value = Config.LocalFiles[fileid].Date.ToString(); nodefileresume.Attributes.Append(att); att = xmlresume.CreateAttribute("Length"); att.Value = Config.LocalFiles[fileid].Length.ToString(); nodefileresume.Attributes.Append(att); nodedoc.AppendChild(nodefileresume); xmlresume.Save("Resume.xml");//记录续传文件的信息 } } else { SetControlText(labelInfo, string.Empty); SetMessageBox(e.Message); } SetState(State.Idle); } finally { if (fs != null) { fs.Close(); } //if (!this.Disposing) //{ // SetState(State.Idle); //} client.Close(); time.Stop(); } }
private ArrayList listthread = new ArrayList(); //记录所有运行的线程 private void Receive(object param) { Socket client = param as Socket; bool finished = false; try { byte[] btbufundecoded = new byte[0]; while (!finished) { byte[] bufmax = new byte[Config.MAX_LENGTH]; int length = client.Receive(bufmax);//接收消息 //接收不完整的时候出现问题 byte[] btbuf = new byte[length + btbufundecoded.Length]; if (btbufundecoded.Length > 0) { Buffer.BlockCopy(btbufundecoded, 0, btbuf, 0, btbufundecoded.Length);//将未完成的字节加入队列的开始 } Buffer.BlockCopy(bufmax, 0, btbuf, btbufundecoded.Length, length);//加入接收到的字节 MessageBuffer mb = new MessageBuffer(btbuf); if (mb.Completed) { switch (mb.Header) { case MessageType.RequerySolution: { XmlDocument xmldoc = new XmlDocument(); if (System.IO.File.Exists(Config.SolutionFile)) { try { xmldoc.Load(Config.SolutionFile); } catch { } } System.IO.MemoryStream ms = new System.IO.MemoryStream(); xmldoc.Save(ms); byte[] xml = ms.ToArray(); MessageBuffer mbsolutionlist = new MessageBuffer(MessageType.SendSolutionList, 0, 0,xml.Length); mbsolutionlist.SetFileBytes(xml); client.Send(mbsolutionlist.GetBytes()); finished = true; break; } case MessageType.RequeryFile: { UserInfo user = new UserInfo((IPEndPoint)client.RemoteEndPoint); FileInfoCollection fc = new FileInfoCollection(); fc.Load(mb.GetFileBytes()); user.FilesToDownLoad = Config.LocalFiles.GetDownloadList(fc); RefreshList(RefreshType.Add, user.ID, user);//增加用户,刷新列表 byte[] xml = user.FilesToDownLoad.SaveToBuffer(); MessageBuffer mbfilelist = new MessageBuffer(MessageType.SendFileList, 0, 0, xml.Length); mbfilelist.SetFileBytes(xml); client.Send(mbfilelist.GetBytes());//发送更新列表 user.FilesToDownLoad.Send(client);//发送文件内容 client.Send(MessageBuffer.SendFinished.GetBytes());//发送完毕 break; } case MessageType.RequeryBlock: Config.LocalFiles.Send(client, mb.FileID, mb.FileOffSet, mb.FileLength);//发送文件部分内容 break; case MessageType.ReceiveFinished: finished = true; break; } } } } catch (SocketException)//客户端退出或者取消或者超时关闭 { } catch//确保服务器稳定 { //记录错误,有心情再做 } finally { RefreshList(RefreshType.Remove, ((IPEndPoint)client.RemoteEndPoint).ToString().GetHashCode(), null);//移除用户,刷新列表 client.Close(); } }