using System; using System.Collections.Generic; using System.Linq; using System.Text; using NetLibrary.Network; using System.Collections; using System.Net.Sockets; using System.Threading; using System.Net; using NetLibrary.Log; using System.IO; namespace NetLibrary.Network { #region 服务器Socket public class SocketService { /// /// 要监控的端口号 /// public int Port { get; set; } /// /// 空闲超时自动断开或引发心跳包事件 /// public int OutTime { get; set; } /// /// 重发等待默认30秒后重发 /// public int RefshSecond { get; set; } /// /// 最大消息等待回包数量(滑动窗口) /// public int MaxWaitMsgNumber { get; set; } public AddressFamily Family { get; set; } public int MaxSendNumber { get; set; } public int BufferSize { get; set; } public bool OutMaxSendNumberCloseConnect { get; set; } /// /// 是否长连接(默认长连接) /// public bool IsLongConnect { get; set; } /// /// 是否启用发送线程 /// public bool IsSendThread { get; set; } /// /// 数据读取到时发生 /// public event Action ReceiveData; /// /// 连接完成时发生 /// public event Action ConnectSocketComplete; /// /// 关闭时发生 /// public event Action CloseSocketComplete; /// /// 心跳请求事件 /// public event Action OutTimeHappen; /// /// 发送失败事件 /// public event Action SendError; public event Action ReadDataMessage; TcpSocketListener socketListener = null; public ServerConnectionPool ListUserSocket = new ServerConnectionPool(); private AutoResetEvent AutoReset = new AutoResetEvent(false); public SocketArgsPool socketArgsPool = null; //BufferPool bufferManager = null; public bool IsRun = false; public SocketService() { Family = AddressFamily.InterNetwork; IsSendThread = false; IsLongConnect = false; OutTime = 180; Port = 10000; RefshSecond = 30; MaxWaitMsgNumber = 10; BufferSize = 1024; OutMaxSendNumberCloseConnect = false; } #region 初始化缓存 public void Init() { //初始化数据接收缓存 //bufferManager = new BufferPool(MaxConnect * BuffSize, BuffSize); //bufferManager.InitBuffer(); // 声明异步Socket //SocketAsyncEventArgs readWriteEventArg; //for (int i = 0; i < MaxConnect; i++) //{ // //初始化异步Socket // readWriteEventArg = new SocketAsyncEventArgs(); // // 设备接收数据缓存 // bufferManager.SetBuffer(readWriteEventArg); // // 把异步Socket放入集合顶部 // socketArgsPool.CheckIn(readWriteEventArg); //} } #endregion #region 开始监控 public void Start() { socketArgsPool = new SocketArgsPool(); socketListener = new TcpSocketListener(Family, IPAddress.Any, Port, 10); socketListener.SocketConnected += socketListener_SocketConnected; socketListener.Start(); RunWhileListUserSocket(); } #endregion #region 结束监控 public void Stop() { IsRun = false; AutoReset.Set(); socketListener.Stop(); while (true) { var model = ListUserSocket.CheckOut(); if (model == null) break; model.Disconnect(); } ListUserSocket.Clear(); System.GC.Collect(); } #endregion #region 结束监控并且发送断开连接消息 public void Stop(byte[] bytes) { IsRun = false; AutoReset.Set(); socketListener.Stop(); while (true) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (bytes != null && bytes.Length > 0) model.SendData(bytes, 0, bytes.Length); model.Disconnect(); } ListUserSocket.Clear(); System.GC.Collect(); } #endregion #region 启动发送线程 void RunWhileListUserSocket() { if (this.IsSendThread == true) { Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket)); t1.Start(); } else { Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket2)); t1.Start(); } } #endregion #region 关闭设备连接 public bool CloseDevice(string IpAddress) { bool bk = false; int index = ListUserSocket.Available; for (int i = 0; i < index; i++) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (model.IpAddress == IpAddress) { model.Disconnect(); bk = true; break; } ListUserSocket.CheckIn(model); } return bk; } #endregion #region 关闭设备连接 public bool CloseDevice2(string DeviceNo) { bool bk = false; int index = ListUserSocket.Available; for (int i = 0; i < index; i++) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (model.DeviceNo == DeviceNo) { model.Disconnect(); bk = true; break; } ListUserSocket.CheckIn(model); } return bk; } #endregion #region 关闭设备连接 public bool CloseDevice3(string DeviceNo, int Port) { bool bk = false; int index = ListUserSocket.Available; for (int i = 0; i < index; i++) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (model.DeviceNo == DeviceNo && model.Port == Port) { model.Disconnect(); bk = true; break; } ListUserSocket.CheckIn(model); } return bk; } #endregion #region 接受连接请求 void socketListener_SocketConnected(object sender, SocketEventArgs e) { try { e.Socket.SendBufferSize = 32 * 1024; e.Socket.ReceiveBufferSize = 32 * 1024; e.Socket.LingerState = new LingerOption(true, 0); e.Socket.SendTimeout = 60000; //SocketAsyncEventArgs args = socketArgsPool.CheckOut(); SocketAsyncEventArgs args = null; if (args == null) { args = new SocketAsyncEventArgs(); byte[] buffer = new byte[BufferSize]; args.SetBuffer(buffer, 0, buffer.Length); } ServerConnection connection = null; try { connection = new ServerConnection(e.Socket, args); connection.DataReceived += DataReceived; connection.CloseSocketed += Disconnected; } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); e.Socket.Close(); //if (connection!=null) connection.Disconnect(); return; } ListUserSocket.CheckIn(connection); if (this.ConnectSocketComplete != null) this.ConnectSocketComplete(connection); } catch (Exception exx) { ErrorFollow.TraceWrite(exx.TargetSite.Name, exx.StackTrace, exx.Message); } } #endregion #region 读取消息 void DataReceived(ServerConnection sender, DataEventArgs e) { if (e.Data.Length == 0) return; sender.PrevTime = DateTime.Now; if (this.ReceiveData != null) this.ReceiveData(sender, e); } #endregion #region 对方关闭连接 void Disconnected(ServerConnection model, SocketAsyncEventArgs e) { if (model == null || model.Enabled == false) { if (model != null) { model.DataReceived -= DataReceived; model.CloseSocketed -= Disconnected; } if (this.CloseSocketComplete != null) this.CloseSocketComplete(model); e.Dispose(); e = null; model = null; } else { model.Disconnect(); } } #endregion #region 发送完成时 void connection_SendCompleted(ServerConnection model) { if (this.IsRun == true) ListUserSocket.CheckIn(model); } #endregion #region 轮循连接列表 void WhileListUserSocket() { //bool IsRemoveMessage = false; IsRun = true; while (IsRun) { try { ServerConnection model = ListUserSocket.CheckOut(); if (model == null) { AutoReset.WaitOne(5000, false); continue; } if (model.Enabled == false) continue; if (model.PrevTime.AddSeconds(this.OutTime) < DateTime.Now) { if (this.IsLongConnect == false) { ErrorFollow.TraceWrite("服务器检测到" + model.DeviceNo + "无应答", "", "断开对方连接"); model.Disconnect(); continue; } else { //如果是长连接引发,心跳事件 if (this.OutTimeHappen != null) { this.OutTimeHappen(model); model.PrevTime = DateTime.Now; ListUserSocket.CheckIn(model); continue; } } } //如果服务器是断开连接的,那么不读取主动发送的数据 if (string.IsNullOrEmpty(model.DeviceNo) == false && model.ListMessage.Count == 0) { if (this.ReadDataMessage != null) this.ReadDataMessage(model); } if (model.ListMessage.Count > 0) { while (model.WaitMsgNumber < this.MaxWaitMsgNumber) { SocketMessage Msg = model.GetNextSocketMessage(this.RefshSecond); if (Msg == null) break; if (this.MaxSendNumber > 0 && Msg.SendNumber > this.MaxSendNumber) { if (OutMaxSendNumberCloseConnect == false) { model.EndWaitMsg(Msg.SequenceID); continue; } else { model.Disconnect(); break; } } if (this.Send(model, Msg) == false) { if (this.SendError != null) this.SendError(Msg); break; } } } if (model.Enabled == false) continue; if (model.ListMessage.IsEmployMessages == true) model.ListMessage.RemoveEmploy(); ListUserSocket.CheckIn(model); AutoReset.WaitOne(10, false); } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } } #endregion #region 轮循连接列表 void WhileListUserSocket2() { IsRun = true; while (IsRun) { try { ServerConnection model = ListUserSocket.CheckOut(); if (model == null) { AutoReset.WaitOne(30000, false); continue; } if (model.Enabled == false) continue; if (model.PrevTime.AddSeconds(this.OutTime) < DateTime.Now) { if (this.IsLongConnect == false) { ErrorFollow.TraceWrite("服务器检测到" + model.DeviceNo + "无应答", "", "断开对方连接"); model.Disconnect(); continue; } else { //如果是长连接引发,心跳事件 if (this.OutTimeHappen != null) { this.OutTimeHappen(model); model.PrevTime = DateTime.Now; ListUserSocket.CheckIn(model); continue; } } } if (model.Enabled == false) continue; ListUserSocket.CheckIn(model); AutoReset.WaitOne(100, false); } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } } #endregion #region 发送数据 public bool Send(ServerConnection model, SocketMessage msg) { model.PrevTime = DateTime.Now; try { msg.SendNumber++; msg.SendTime = DateTime.Now; bool bk = model.SendData(msg.Bytes, 0, msg.SendLength); if (bk == false) { ErrorFollow.TraceWrite("Send", "", "发送失败断开连接"); model.Disconnect(); return false; } if (msg.IsRevert == false) { EndWaitMsg(model, msg.SequenceID); } else { if (msg.SendNumber > 1) model.IncrementWaitMsgNumber(); } } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); model.Disconnect(); return false; } return true; } #endregion #region 返回UserSocket public ServerConnection GetUserSocket(string IpAddress) { int index = ListUserSocket.Available; for (int i = 0; i < index; i++) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (model.Enabled == false) continue; if (model.IpAddress == IpAddress) return model; ListUserSocket.CheckIn(model); } return null; } #endregion #region 返回UserSocket public ServerConnection GetUserSocket2(string DeviceNo) { int index = ListUserSocket.Available; for (int i = 0; i < index; i++) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (model.Enabled == false) continue; if (model.DeviceNo == DeviceNo) return model; ListUserSocket.CheckIn(model); } return null; } #endregion #region 返回UserSocket public ServerConnection GetUserSocket3(string DeviceNo, int Port) { int index = ListUserSocket.Available; for (int i = 0; i < index; i++) { var model = ListUserSocket.CheckOut(); if (model == null) break; if (model.Enabled == false) continue; if (model.DeviceNo == DeviceNo && model.Port != Port) return model; ListUserSocket.CheckIn(model); } return null; } #endregion #region 消除已回复消息 public int EndWaitMsg(ServerConnection model, string SequenceID) { SocketMessage msg = model.EndWaitMsg(SequenceID); if (msg == null) return 0; return msg.MessageID; } #endregion } #endregion #region 客户端Socket public class ClientSocket { public string IpAddress { get; set; } public int Port { get; set; } public ServerConnection UseSocket { get; set; } public int RefshSecond { get; set; } /// /// 最大消息等待回复数量 /// public int MaxWaitMsgNumber { get; set; } /// /// 超出多少秒没有数据通讯后连接自动断开 /// public int OutTime { get; set; } public int BuffSize { get; set; } public int MaxSendNumber { get; set; } public bool IsLongConnect { get; set; } public bool IsLogin { get; set; } public event Action ReceiveData; public event Action ConnectSocketComplete; public event Action CloseSocketComplete; public event Action ConnectSocketError; public event Action OutTimeHappen; public event Action SendError; private AutoResetEvent AutoReset = new AutoResetEvent(false); private bool IsRun = false; private DateTime PrevTime = DateTime.Now; private int CloseReConnectTime = 0; public ClientSocket() { IsLongConnect = true; IsLogin = false; RefshSecond = 30; MaxWaitMsgNumber = 16; MaxSendNumber = 0; OutTime = 180; BuffSize = 32 * 1024; UseSocket = new ServerConnection(); UseSocket.DataReceived += DataReceived; UseSocket.CloseSocketed += Disconnected; } #region 开始监控 public void Start() { IsRun = true; Thread t1 = new Thread(new ThreadStart(this.WhileListUserSocket)); t1.Name = "ClientSocket"; t1.Start(); } #endregion #region 停止 public void Stop() { IsRun = false; AutoReset.Set(); CloseSocket(UseSocket); } #endregion #region 连接 bool SocketAccept() { IPAddress broadcast = IPAddress.Parse(IpAddress); IPEndPoint ep = new IPEndPoint(broadcast, Port); Socket e = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); e.LingerState = new LingerOption(true, 0); e.SendTimeout = 60000; try { e.Connect(ep); System.Threading.Thread.Sleep(1000); UseSocket.PrevTime = DateTime.Now; } catch (Exception ex) { CloseReConnectTime = 60; ErrorFollow.TraceWrite("连接失败", this.IpAddress+":"+Port, ex.Message); if (this.ConnectSocketError != null) this.ConnectSocketError(this.IpAddress); return false; } SocketAsyncEventArgs args = new SocketAsyncEventArgs(); byte[] bytes = new byte[this.BuffSize]; args.SetBuffer(bytes, 0, this.BuffSize); UseSocket.Start(e, args); if (this.ConnectSocketComplete != null) this.ConnectSocketComplete(this.UseSocket); return true; } #endregion #region 读取消息 void DataReceived(ServerConnection sender, DataEventArgs e) { if (e.Data.Length == 0) return; UseSocket.PrevTime = DateTime.Now; if (this.ReceiveData != null) this.ReceiveData(sender, e); } #endregion #region 对方关闭连接 void Disconnected(ServerConnection sender, SocketAsyncEventArgs e) { CloseReConnectTime = 60; if (this.CloseSocketComplete != null) this.CloseSocketComplete(sender); e.Dispose(); e = null; //ErrorFollow.TraceWrite("TcpSocker.Disconnected", "", "对方关闭连接"); //CloseSocket(sender); } #endregion #region 轮循消息列表 void WhileListUserSocket() { bool bk = false; //SocketAccept(); while (IsRun) { try { if (UseSocket.Enabled == false) { if (this.IsLongConnect == true || UseSocket.ListMessage.Count > 0) { if (CloseReConnectTime > 0) { CloseReConnectTime = 0; AutoReset.WaitOne(60000); } bk = SocketAccept(); if (bk == true) continue; if (IsRun == true) AutoReset.WaitOne(60000); } else { if (IsRun == true) AutoReset.WaitOne(2000, false); } continue; } if (UseSocket.PrevTime.AddSeconds(this.OutTime) < DateTime.Now) { if (this.IsLongConnect == false) { CloseSocket(UseSocket); bk = true; continue; } else { //如果是长连接引发,心跳事件 if (this.OutTimeHappen != null) { this.OutTimeHappen(UseSocket); UseSocket.PrevTime = DateTime.Now; continue; } } } if (UseSocket.ListMessage.Count > 0) { //ErrorFollow.TraceWrite("发送数据", "", "数量:" + UseSocket.ListMessage.Count + ",等待数:" + UseSocket.WaitMsgNumber); while (true) { SocketMessage Msg = UseSocket.GetNextSocketMessage(this.RefshSecond); if (Msg == null) break; if (UseSocket.WaitMsgNumber >= this.MaxWaitMsgNumber) break; if (this.MaxSendNumber > 0 && Msg.SendNumber > this.MaxSendNumber) { UseSocket.EndWaitMsg(Msg.SequenceID); continue; } if (this.Send(UseSocket, Msg) == false) { if (this.SendError != null) this.SendError(Msg); break; } UseSocket.IncrementWaitMsgNumber(); AutoReset.WaitOne(10, false); } } if (IsRun == true) AutoReset.WaitOne(1000, false); } catch (Exception ex) { CloseSocket(UseSocket); ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } } #endregion #region 发送数据 public bool Send(ServerConnection model, SocketMessage msg) { model.PrevTime = DateTime.Now; try { msg.SendNumber++; msg.SendTime = DateTime.Now; if (msg.SendNumber > 1) { string m = "第" + msg.SendNumber + "次"; m += ",上次发送时间:" + msg.SendTime; m += ",id:" + msg.MessageID; m += ",流水号:" + msg.SequenceID; m += ",FunNo:" + msg.FunNo; m += ",DeviceNo:" + msg.DeviceNo; ErrorFollow.TraceWrite("重发数据", "", m); } bool bk = model.SendData(msg.Bytes, 0, msg.Bytes.Length); if (bk == false) { ErrorFollow.TraceWrite("发送数据失败", "", "断开连接"); CloseSocket(model); } return bk; } catch { ErrorFollow.TraceWrite("发送数据失败", "", "断开连接"); CloseSocket(model); return false; } } #endregion #region 关闭连接 public void CloseSocket() { CloseSocket(this.UseSocket); } #endregion #region 关闭连接 public void CloseSocket(ServerConnection model) { if (model.Enabled == false) return; try { model.Disconnect(); } catch { } } #endregion #region 消除已回复消息 public int EndWaitMsg(string SequenceID) { try { SocketMessage msg = UseSocket.EndWaitMsg(SequenceID); if (UseSocket.WaitMsgNumber == this.MaxSendNumber-1) UseSocket.WaitMsgNumber = 0; if (msg == null) return 0; return msg.MessageID; } catch (Exception ex) { ErrorFollow.TraceWrite("ClientSocket.EndWaitMsg", "", ex.Message); } return 0; } #endregion } #endregion #region 文件下载服务器 public class FileService { private int Port = 11111; public AutoResetEvent AutoReset = new AutoResetEvent(false); public char SpaceChar = '^'; public static string WebPath = ""; SocketService ser = new SocketService(); public event Action> ReceiveData; public event Action ConnectSocketComplete; public event Action CloseSocketComplete; public System.Security.Cryptography.MD5CryptoServiceProvider oMD5Hasher = new System.Security.Cryptography.MD5CryptoServiceProvider(); public FileService() { //ser. ser.IsLongConnect = false; ser.OutMaxSendNumberCloseConnect = true; ser.MaxWaitMsgNumber = 16; ser.MaxSendNumber = 2; ser.OutTime = 60*3; ser.RefshSecond = 10; ser.ReceiveData += ser_ReceiveData; ser.ConnectSocketComplete += ser_ConnectSocketComplete; ser.CloseSocketComplete += ser_CloseSocketComplete; } #region 连接 void ser_ConnectSocketComplete(ServerConnection model) { if (this.ConnectSocketComplete != null) this.ConnectSocketComplete(model); } #endregion #region 关闭连接 void ser_CloseSocketComplete(ServerConnection model) { if (model.fs != null) { model.fs.Close(); model.fs = null; } if (this.CloseSocketComplete != null) this.CloseSocketComplete(model); } #endregion #region 启动监控 public void Start(int Port) { this.Port = Port; if (this.Port == 0) return; ser.BufferSize = 2 * 1024; ser.Port = Port; ser.Start(); } #endregion #region 停止监控 public void Stop() { if (this.Port == 0) return; ser.Stop(null); } #endregion #region 服务器读取到数据时发生 private void ser_ReceiveData(ServerConnection model, DataEventArgs arg2) { try { string Data = System.Text.Encoding.GetEncoding("GB2312").GetString(model.Data).Trim('\0'); ErrorFollow.TraceWrite("读取到数据", model.IpAddress, Data); Dictionary ReceiveModel = this.ParseData(Data); string FunNo = ReceiveModel["TRANS_NO"]; switch (FunNo) { case "9999": //文件下载请求 DownFile(model, ReceiveModel); break; default: if (this.ReceiveData != null) this.ReceiveData(model, ReceiveModel); break; } } catch (Exception ex) { ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } #endregion #region 解析返回数据 Dictionary ParseData(string Data) { if (string.IsNullOrEmpty(Data) == true) return null; //if (ErrorFollow.IsDebug == true) ErrorFollow.TraceWrite("解析返回数据", "", Data); Dictionary list = new Dictionary(); string[] ss = Data.Split(this.SpaceChar); foreach (string item in ss) { if (string.IsNullOrEmpty(item) == true) continue; string[] sss = item.Split('='); if (sss.Length == 1) { list.Add(sss[0].ToUpper(), ""); } if (sss.Length == 2) { list.Add(sss[0].ToUpper(), sss[1]); } } return list; } #endregion #region 下载文件 public void DownFile(ServerConnection model, Dictionary ReceiveModel) { NetworkStream ns = null; Socket socker = null; try { string FilePath = CustomIO.GetKeyValues(ReceiveModel, "FilePath"); if (FilePath.Contains(":") == false) FilePath = FileService.WebPath + FilePath; bool IsExistsFile = File.Exists(FilePath); socker = model.GetSocket(); ns = new NetworkStream(socker); if (IsExistsFile == false) { ErrorFollow.TraceWrite("下载文件失败,文件不存在", model.IpAddress, FilePath); byte[] fileBuffer = new byte[24]; for (int i = 8; i < 24; i++) { fileBuffer[i] = 255; } ns.Write(fileBuffer, 0, 24); } else { //传送头信息:文件长度,MD5校验码 model.fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] HeaderLen = BitConverter.GetBytes(model.fs.Length); byte[] HeaderHash = oMD5Hasher.ComputeHash(model.fs); ns.Write(HeaderLen, 0, HeaderLen.Length); ns.Write(HeaderHash, 0, HeaderHash.Length); byte[] fileBuffer = new byte[1024 * 4]; // 每次传1KB int bytesRead; int totalBytes = 0; // 将文件流转写入网络流 int index = 0; model.fs.Position = 0; do { bytesRead = model.fs.Read(fileBuffer, 0, fileBuffer.Length); if (bytesRead == 0) break; ns.Write(fileBuffer, 0, bytesRead); totalBytes += bytesRead; // 发送了的字节数 index++; if (index == 10) { AutoReset.WaitOne(10, false); index = 0; model.PrevTime = DateTime.Now; } } while (bytesRead > 0); model.fs.Close(); model.fs = null; } } catch (Exception ex) { if (model.fs != null) { model.fs.Close(); model.fs = null; } ErrorFollow.TraceWrite(ex.TargetSite.Name, ex.StackTrace, ex.Message); } } #endregion } #endregion #region 文件下载客户端 public class FileClient { public static string IpAddress = ""; public static int Port = 11111; public static string SpaceChar = "^"; public int CilentID = 0; public int DownFileID = 0; public List FileManage = null; public int ModelType = 0; public bool IsSaveList = true; public bool IsErrorStopDown = false; public float Version = 0; public object CustomModel = null; private AutoResetEvent AutoReset = new AutoResetEvent(false); public bool IsRun = true; public string tempFilePath = ""; public string RunTime = ""; public event Action DownFileComplete; //下载文件完成 public event Action DownFileErrorComplete; //下载文件错误时发生 public event Action DownNoFileComplete; //服务器不存在这个文件 #region 启动监控 public void Start() { IsRun = true; Thread t = new Thread(this.OnStart); t.Start(); } #endregion #region 启动监控 public void Start(int ModelType, List ListModel) { this.ModelType = ModelType; this.FileManage = ListModel; IsRun = true; string dir = SystemInfo.AppPath() + "TempFileDown"; if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); tempFilePath = dir + "/" + DateTime.Now.ToString("MMddHHmmssfff") + ".txt"; Thread t = new Thread(this.OnStart); t.Start(); } #endregion #region 启动监控 public void Start(int ModelType, string filePath, List ListModel) { this.ModelType = ModelType; this.FileManage = ListModel; IsRun = true; string dir = SystemInfo.AppPath() + "TempFileDown"; if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); tempFilePath = filePath; Thread t = new Thread(this.OnStart); t.Start(); } #endregion #region 停止监控 public void Stop() { FileManage.Clear(); IsRun = false; AutoReset.Set(); } #endregion #region 保存下载文件列表 public void SaveFileList() { try { if (this.IsSaveList == false) return; if (string.IsNullOrEmpty(tempFilePath) == true) { string dir = SystemInfo.AppPath() + "TempFileDown"; if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); tempFilePath = dir + "/" + DateTime.Now.ToString("MMddHHmmssfff") + ".txt"; } StringBuilder sb = new StringBuilder(); sb.Append("DownFileID=" + this.DownFileID + FileClient.SpaceChar); sb.Append("ModelType=" + this.ModelType + FileClient.SpaceChar); sb.Append("RowCount=" + FileManage.Count + FileClient.SpaceChar); sb.Append("IsErrorStopDown=" + IsErrorStopDown.ToString() + FileClient.SpaceChar); int index = 1; foreach (NetDownFile item in FileManage) { sb.Append("DownFileName[" + index + "]=" + item.DownFileName + FileClient.SpaceChar); sb.Append("DownID[" + index + "]=" + item.DownID + FileClient.SpaceChar); sb.Append("SaveFileName[" + index + "]=" + item.SaveFileName + FileClient.SpaceChar); sb.Append("IsDownComplete[" + index + "]=" + item.IsDownComplete.ToString() + FileClient.SpaceChar); sb.Append("FileType[" + index + "]=" + item.FileType + FileClient.SpaceChar); index++; } using (StreamWriter sw = new StreamWriter(tempFilePath, false, System.Text.Encoding.GetEncoding("GB2312"))) { sw.WriteLine(sb.ToString()); sw.Close(); } } catch (Exception ex) { ErrorFollow.TraceWrite("保存下载文件列表", ex.StackTrace, ex.Message); } } #endregion #region 文件下载 void OnStart() { DateTime StartTime = DateTime.Now; SaveFileList(); FileStream fs = null; NetworkStream ns = null; TcpClient tcp = null; try { System.Security.Cryptography.MD5CryptoServiceProvider oMD5Hasher = new System.Security.Cryptography.MD5CryptoServiceProvider(); bool bk = false; #region 循环 foreach (NetDownFile item in FileManage) { if (item.IsDownComplete == true) continue; try { if (File.Exists(item.SaveFileName) == true) File.Delete(item.SaveFileName); } catch { ErrorFollow.TraceWrite("下载文件", "", item.SaveFileName + "文件删除失败"); bk = true; break; } string dir = Path.GetDirectoryName(item.SaveFileName); if (Directory.Exists(dir) == false) Directory.CreateDirectory(dir); string path = item.SaveFileName + ".temp"; if (File.Exists(path) == true) { DateTime dt = DateTime.Now; FileInfo finfo = new FileInfo(path); if (dt.AddMinutes(-1) < finfo.LastWriteTime) { finfo = null; ErrorFollow.TraceWrite("下载文件", "", path + "文件已经在下载"); bk = true; break; } File.Delete(path); } IPAddress broadcast = IPAddress.Parse(IpAddress); IPEndPoint ep = new IPEndPoint(broadcast, Port); tcp = new TcpClient(); tcp.Connect(ep); ns = tcp.GetStream(); //这里发送文件下载请求 StringBuilder sb = new StringBuilder(); if (item.FileType == 0) { sb.Append("TRANS_NO=9998" + FileClient.SpaceChar); } else { sb.Append("TRANS_NO=9999" + FileClient.SpaceChar); } sb.Append("FilePath=" + item.DownFileName + FileClient.SpaceChar); byte[] bytes = System.Text.Encoding.GetEncoding("GB2312").GetBytes(sb.ToString()); ns.Write(bytes, 0, bytes.Length); //AutoReset.WaitOne(1000, false); byte[] fileHeader = new byte[24]; byte[] fileBuffer = new byte[1024 * 4]; // 每次收1KB if (File.Exists(path)) File.Delete(path); fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); // 从缓存buffer中读入到文件流中 int bytesRead; int totalBytes = 0; int index = 0; byte[] HeaderHash = null; string CheckOutCode = ""; do { bytesRead = ns.Read(fileBuffer, 0, fileBuffer.Length); if (totalBytes < 24) { int count = 24 - totalBytes; if (bytesRead < count) count = bytesRead; Buffer.BlockCopy(fileBuffer, 0, fileHeader, totalBytes, count); if (totalBytes + count >= 24) { item.Length = BitConverter.ToInt64(fileHeader, 0); if (item.Length == 0) break; item.CheckOutCode = BitConverter.ToString(fileHeader, 8, 16); if (bytesRead > 24) fs.Write(fileBuffer, count, bytesRead - count); } } else { fs.Write(fileBuffer, 0, bytesRead); } totalBytes += bytesRead; if (item.Length > 0 && totalBytes >= item.Length + 24) break; if (index == 10) { AutoReset.WaitOne(10, false); if (IsRun == false) return; index = 0; } } while (bytesRead > 0); if (fs.Length > 0) { fs.Position = 0; HeaderHash = oMD5Hasher.ComputeHash(fs); CheckOutCode = BitConverter.ToString(HeaderHash, 0, 16); } long FileLength = fs.Length; fs.Close(); fs = null; ns.Close(); ns = null; tcp.Close(); tcp = null; bool bkk = true; if (item.Length == 0 && fileHeader.Length == 24) { bkk = false; for (int i = 8; i < 24; i++) { if (fileHeader[i] != 255) { bkk = true; break; } } } if (bkk==false) { ErrorFollow.TraceWrite("下载文件", "", "服务器不存在这个文件:" + item.DownFileName); item.IsDownComplete = true; if (this.DownNoFileComplete != null) this.DownNoFileComplete(item); File.Delete(path); bk = false; break; } else if (item.Length == 0 || HeaderHash == null) { ErrorFollow.TraceWrite("下载文件出错", "文件长度不能等于0", item.DownFileName); File.Delete(path); bk = true; break; } else if (FileLength != item.Length) { ErrorFollow.TraceWrite("下载文件出错", "文件长度错误", item.DownFileName); File.Delete(path); bk = true; break; } else if (CheckOutCode != item.CheckOutCode) { ErrorFollow.TraceWrite("下载文件出错", "MD5校验失败", item.DownFileName); File.Delete(path); bk = true; break; } else { ErrorFollow.TraceWrite("下载文件成功", "", item.DownFileName); item.IsDownComplete = true; File.Move(path, item.SaveFileName); } } #endregion if (bk == false) { DateTime StopTime = DateTime.Now; TimeSpan ts = StopTime - StartTime; RunTime = ts.ToString(); IsRun = false; if (this.IsSaveList == true) File.Delete(tempFilePath); if (this.DownFileComplete != null) this.DownFileComplete(this); } else { if (this.IsErrorStopDown == true) { ErrorFollow.TraceWrite("下载文件错误", "", "停止下载"); if (this.DownFileErrorComplete != null) this.DownFileErrorComplete(this); } else { ErrorFollow.TraceWrite("下载文件出错", "", "60秒后重新下载"); AutoReset.WaitOne(60000, false); if (IsRun == false) return; OnStart(); return; } } } catch (Exception ex) { try { if (fs != null) { fs.Close(); fs = null; } if (ns != null) { ns.Close(); ns = null; } if (tcp != null) { tcp.Close(); tcp = null; } } catch { } if (this.IsErrorStopDown == true) { ErrorFollow.TraceWrite("下载文件出错", ex.StackTrace, ex.Message); if (this.DownFileErrorComplete != null) this.DownFileErrorComplete(this); } else { ErrorFollow.TraceWrite("下载文件出错,60秒后重新下载", ex.StackTrace, ex.Message); AutoReset.WaitOne(60000, false); if (IsRun == false) return; OnStart(); } } } #endregion } #endregion #region 文件下载信息 public class NetDownFile { public int DownID = 0; public string SaveFileName = ""; public string DownFileName = ""; public long Length = 0; public string CheckOutCode = ""; public bool IsDownComplete = false; public int FileType = 1; //0医生照片下载1文件下载 public void CreateFile() { if (File.Exists(SaveFileName) == true) File.Delete(SaveFileName); } public NetDownFile Copy() { NetDownFile model = new NetDownFile(); model.DownID = this.DownID; model.SaveFileName = this.SaveFileName; model.DownFileName = this.DownFileName; model.Length = this.Length; model.CheckOutCode = this.CheckOutCode; model.IsDownComplete = this.IsDownComplete; model.FileType = this.FileType; return model; } } #endregion }