/// <summary> /// 构造一个新的消息对象,并绑定到指定的端口和IP上。 /// </summary> /// <param name="ip">绑定的IP</param> /// <param name="port">绑定的端口</param> internal UDPThread(IPMClient ipmClient) { IsInitialized = false; try { client = new UdpClient(new IPEndPoint(ipmClient.Config.BindedIP, ipmClient.Config.Port)); } catch (Exception) { OnNetworkError(new EventArgs()); return; } SendList = new List<PackedNetworkMessage>(); client.EnableBroadcast = true; _ipmClient = ipmClient; CheckQueueTimeInterval = 2000; MaxResendTimes = 5; new System.Threading.Thread(new System.Threading.ThreadStart(CheckUnConfirmedQueue)) { IsBackground = true }.Start(); IsInitialized = true; //开始监听 client.BeginReceive(EndReceiveDataAsync, null); }
/// <summary> /// 将调试器辅助类附加到客户端上 /// <para>这个是强行附加上的,不会考虑到是DEBUG模式还是Release模式</para> /// </summary> /// <param name="client">要附加的客户端</param> public void AttachHelper(IPMClient client) { client.MessageClient.IpValidateRequired += new Network.IpValidateRequiredEventHandler(MessageClient_IpValidateRequired); client.MessageClient.PackageReceived += new EventHandler<Network.PackageReceivedEventArgs>(MessageClient_PackageReceived); client.MessageClient.PackageResend += new EventHandler<Network.PackageSendEventArgs>(MessageClient_PackageResend); client.MessageClient.PackageSendFailure += new EventHandler<Network.PackageSendEventArgs>(MessageClient_PackageSendFailure); client.MessageClient.PackageDroped += new EventHandler<Network.NetworkPackageEventArgs>(MessageClient_PackageDroped); }
/// <summary> /// 初始化加载 /// </summary> /// <param name="client">绑定的客户端</param> /// <param name="isInitializingCall">是否是初始化加载</param> /// <returns></returns> internal bool Load(IPMClient client, bool isInitializingCall) { if (EnsureLoadAssembly() && CreateProviderInstance() && InitialzingServiceProvider(client)) { LoadService(isInitializingCall); return true; } return false; }
/// <summary> /// 触发消息将要处理的事件 /// </summary> /// <param name="e">事件参数</param> protected virtual void OnMessageProcessing(MessageEventArgs e) { if (MessageProcessing == null) { return; } if (IPMClient.NeedPostMessage) { if (messageProcessingCall == null) { messageProcessingCall = (s) => MessageProcessing(this, s as MessageEventArgs); } IPMClient.SendSynchronizeMessage(messageProcessingCall, e); } else { MessageProcessing(this, e); } }
/// <summary> /// 触发消息对方消息已经打开事件 /// </summary> /// <param name="e">事件参数</param> protected virtual void OnTextMessageOpened(MessageEventArgs e) { if (TextMessageOpened == null) { return; } if (!IPMClient.NeedPostMessage) { TextMessageOpened(this, e); } else { if (textMessageOpenedCall == null) { textMessageOpenedCall = (s) => TextMessageOpened(this, s as MessageEventArgs); } IPMClient.SendSynchronizeMessage(textMessageOpenedCall, e); } }
internal TCPThread(IPMClient client) { IsInitialized = false; _client = client; this.Config = client.Config; Config.EnableFileTransfer = false; try { listener = new TcpListener(this.IP, this.Port) { }; StartListener(); IsInitialized = true; Config.EnableFileTransfer = true; } catch (Exception) { OnNetworkError(new EventArgs()); } }
/// <summary> /// 引发接收到消息包事件 /// </summary> /// <param name="e"></param> protected virtual void OnMessageReceived(MessageEventArgs e) { if (MessageReceived == null) { return; } if (!IPMClient.NeedPostMessage) { MessageReceived(this, e); } else { if (messageReceivedCallBack == null) { messageReceivedCallBack = s => MessageReceived(this, s as MessageEventArgs); } IPMClient.SendSynchronizeMessage(messageReceivedCallBack, e); } }
protected virtual void OnNetworkError(EventArgs e) { if (NetworkError == null) { return; } if (!IPMClient.NeedPostMessage) { NetworkError(this, e); } else { if (scpcNetworkError == null) { scpcNetworkError = (s) => { NetworkError(this, s as EventArgs); } } ; IPMClient.SendASynchronizeMessage(scpcNetworkError, e); } }
/// <summary> /// 引发 <seealso cref="FSLib.IPMessager.Core.FileTaskManager.FileReceiveTaskReDroped"/> 事件 /// </summary> /// <param name="e"></param> protected virtual void OnFileReceiveTaskReDroped(FileTaskEventArgs e) { if (FileReceiveTaskReDroped == null) { return; } if (!IPMClient.NeedPostMessage) { FileReceiveTaskReDroped(this, e); } else { if (callFileReceiveTaskReDroped == null) { callFileReceiveTaskReDroped = s => FileReceiveTaskReDroped(this, s as FileTaskEventArgs); } IPMClient.SendSynchronizeMessage(callFileReceiveTaskReDroped, e); } }
protected virtual void OnFileSystemOperationError(FileSystemOperationErrorEventArgs e) { if (FileSystemOperationError == null) { return; } IpmEvents.OnTcpThreadFileSystemOperationError(_client, e); if (!IPMClient.NeedPostMessage) { FileSystemOperationError(this, e); } else { if (scpcFileSystemOperationError == null) { scpcFileSystemOperationError = (s) => FileSystemOperationError(this, s as FileSystemOperationErrorEventArgs); } IPMClient.SendASynchronizeMessage(scpcFileSystemOperationError, e); } }
/// <summary> /// 自由线程,检测未发送的数据并发出 /// </summary> void CheckUnConfirmedQueue() { //异步调用委托 if (cucqCallpack == null) { cucqCallpack = (s) => OnPackageSendFailure(s as PackageSendEventArgs); } if (resendCallback == null) { resendCallback = (s) => OnPackageResend(s as PackageSendEventArgs); } do { if (SendList.Count > 0) { PackedNetworkMessage[] array = null; lock (SendList) { array = SendList.ToArray(); } //挨个重新发送并计数 Array.ForEach(array, s => { s.SendTimes++; if (s.SendTimes >= MaxResendTimes) { //发送失败啊 PackageSendEventArgs e = new PackageSendEventArgs() { Package = s }; if (IPMClient.NeedPostMessage) { IPMClient.SendSynchronizeMessage(cucqCallpack, e); } else { OnPackageSendFailure(e); } SendList.Remove(s); } else { //重新发送 client.Send(s.Data, s.Data.Length, s.RemoteIP); PackageSendEventArgs e = new PackageSendEventArgs() { Package = s }; if (IPMClient.NeedPostMessage) { IPMClient.SendASynchronizeMessage(resendCallback, e); } else { OnPackageResend(e); } } }); } System.Threading.Thread.Sleep(CheckQueueTimeInterval); } while (IsInitialized); }
internal void AttachHelperAuto(IPMClient client) { if (isAttached) return; AttachHelper(client); }
protected virtual void OnFileSystemOperationError(FileSystemOperationErrorEventArgs e) { if (FileSystemOperationError == null) { return; } if (!IPMClient.NeedPostMessage) { FileSystemOperationError(this, e); } else { if (scpcFileSystemOperationError == null) { scpcFileSystemOperationError = (s) => { FileSystemOperationError(this, s as FileSystemOperationErrorEventArgs); } } ; IPMClient.SendASynchronizeMessage(scpcFileSystemOperationError, e); } } #region 发送文件事件 #endregion #endregion #region 发送文件-监听线程 /// <summary> /// 开始发送文件的监听线程 /// </summary> void StartListener() { System.Threading.ThreadStart ts = ListenForSendRequest; new System.Threading.Thread(ts) { IsBackground = true }.Start(); } /// <summary> /// 关闭监听线程 /// </summary> void CloseListener() { listener.Stop(); IsInitialized = false; } /// <summary> /// 监听函数 /// </summary> void ListenForSendRequest() { listener.Start(); while (IsInitialized) { try { TcpClient client = listener.AcceptTcpClient(); //开始发送线程 if (client != null) { System.Diagnostics.Debug.WriteLine("文件发送线程:已经接收到连接请求,远程IP:" + client.Client.RemoteEndPoint.ToString()); new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(PerformFileSend)) { IsBackground = true }.Start(client); } } catch (Exception) { if (!IsInitialized) { break; } } } } #endregion #region 发送文件-发送线程 /// <summary> /// 处理文件发送请求 /// </summary> /// <param name="client"></param> void PerformFileSend(object p) { System.Diagnostics.Debug.WriteLine("文件发送线程 [0x" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString("X4") + "] 已经启动"); using (TcpClient client = p as TcpClient) { byte[] buffer = new byte[400]; //接收或发送缓冲区 int bytesReceived = ReceiveByBuffer(client, buffer, buffer.Length); //第一步:接收文件传输命令 if (bytesReceived < 1) { return; //没收到数据 } Message request = ParseSendCommand(buffer, 0, bytesReceived); //试着解析命令 System.Diagnostics.Debug.WriteLineIf(request == null, "未能解析收到的请求,退出发送线程"); if (request == null) { return; } System.Diagnostics.Debug.WriteLine("已解析文件请求:" + request.NormalMsg.ToString()); //非法请求 //查找任务 string[] taskInfo = request.NormalMsg.Split(':'); ulong pid = 0ul; int tid = 0; FileTaskItem task = null; if (taskInfo.Length < 2 || !ulong.TryParse(taskInfo[0], System.Globalization.NumberStyles.AllowHexSpecifier, null, out pid) || !int.TryParse(taskInfo[1], System.Globalization.NumberStyles.AllowHexSpecifier, null, out tid) || (task = TaskManager.QuerySendTask(pid, tid, (client.Client.RemoteEndPoint as IPEndPoint).Address)) == null ) { return; } System.Diagnostics.Debug.WriteLine(string.Format("文件请求已经接纳,文件编号:0x{0:x8},文件索引:0x{1:x4}", pid, tid)); TaskManager.MarkSendTaskItemState(task, FileTaskItemState.Initializing); //准备发送 if (task.IsFolder) { PerformSendDirectory(client, task.TaskInfo, task); } else { //文件支持有限的断点续传 if (taskInfo.Length == 3) { ulong temp; if (ulong.TryParse(taskInfo[2], out temp)) { task.CurrentFileTransfered = temp; task.FileTransferedAtPast = temp; } System.Diagnostics.Debug.WriteLineIf(task.CurrentFileTransfered > 0, string.Format("断点模式,从 0x{0} 处开始续传", task.CurrentFileTransfered)); } PerformSendFile(client, task.TaskInfo, task); } client.Close(); } } //发送文件夹 void PerformSendDirectory(TcpClient client, FileTaskInfo task, FileTaskItem item) { NetworkStream stream = null; try { stream = client.GetStream(); } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); return; } string currentDirectory = item.FullPath; //当前处理路径 Stack <string> directoryStack = new Stack <string>(); //文件夹栈 directoryStack.Push(""); bool needUpdateTotal = item.TotalSize == 0; //是否需要在发送的时候更新统计 TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Processing); item.StartTime = DateTime.Now; using (stream) { while (!string.IsNullOrEmpty(currentDirectory) || directoryStack.Count > 0) { if (!PerformSendDirectory_SendCreateDirCommand(currentDirectory, stream, task, item)) { return; } if (string.IsNullOrEmpty(currentDirectory)) { if (directoryStack.Count > 0) { currentDirectory = directoryStack.Pop(); //当前是空目录,则向上递归 } continue; } //扫描目录和文件 string[] files = null, directories = null; try { files = System.IO.Directory.GetFiles(currentDirectory); directories = System.IO.Directory.GetDirectories(currentDirectory); item.FolderCount += directories.Length; item.FileCount += files.Length; } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); OnFileSystemOperationError(new FileSystemOperationErrorEventArgs(FileSystemOperationType.QueryDirectory, item.FullPath, task.RemoteHost)); return; } //优先发送文件 foreach (var f in files) { if (!PerformSendDirectory_SendFilesInDirectory(f, stream, task, item, needUpdateTotal)) { return; } } //扫描子目录 if (directories.Length > 0) { directoryStack.Push(""); Array.ForEach(directories, s => { directoryStack.Push(s); }); currentDirectory = directoryStack.Pop(); //取出一个文件夹来发送 } else { //如果没有子目录,则置空当前目录,以命令流程向上返回 currentDirectory = null; } } if (item.State != FileTaskItemState.Failure) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Finished); } } } //发送文件夹中的文件 bool PerformSendDirectory_SendFilesInDirectory(string path, NetworkStream stream, FileTaskInfo task, FileTaskItem item, bool updateTotal) { System.IO.FileInfo fileinfo = new System.IO.FileInfo(path); if (!fileinfo.Exists) { OnFileSystemOperationError(new FileSystemOperationErrorEventArgs(FileSystemOperationType.OpenFileToSend, path, task.RemoteHost)); } if (updateTotal) { item.TotalSize += (ulong)fileinfo.Length; } item.CurrentName = fileinfo.Name; item.CurrentFileTransfered = 0; item.CurrentFileSize = (ulong)fileinfo.Length; string strCMD = string.Format(":{0}:{1:x}:{2:x}:", fileinfo.Name, fileinfo.Length, (int)Consts.Cmd_FileType_Option.Regular); byte[] bytes = null; if (task.RemoteHost.IsEnhancedContractEnabled) { bytes = System.Text.Encoding.Unicode.GetBytes(strCMD); } else { bytes = System.Text.Encoding.Default.GetBytes(strCMD); } try { stream.Write(System.Text.Encoding.Default.GetBytes((bytes.Length + 4).ToString("x4")), 0, 4); stream.Write(bytes, 0, bytes.Length); } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); return(false); } //写入文件数据 FileStream reader = null; try { reader = fileinfo.OpenRead(); } catch (Exception) { OnFileSystemOperationError(new FileSystemOperationErrorEventArgs(FileSystemOperationType.OpenFileToSend, path, task.RemoteHost)); TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); return(false); } using (reader) { byte[] buffer = new byte[SendBuffer]; while (item.CurrentFileTransfered < (ulong)reader.Length) { int bytesRead = reader.Read(buffer, 0, buffer.Length); item.CurrentFileTransfered += (ulong)bytesRead; item.FinishedSize += (ulong)bytesRead; try { stream.Write(buffer, 0, bytesRead); } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); return(false); } } reader.Close(); } item.FinishedFileCount++; return(true); } //发送要求创建文件命令 bool PerformSendDirectory_SendCreateDirCommand(string path, NetworkStream stream, FileTaskInfo task, FileTaskItem item) { string strCMD = string.Format(":{0}:{1}:{2:x}:", string.IsNullOrEmpty(path) ? "." : System.IO.Path.GetFileName(path), 0, (int)(string.IsNullOrEmpty(path) ? Consts.Cmd_FileType_Option.RetParent : Consts.Cmd_FileType_Option.Dir)); byte[] bytes = null; if (task.RemoteHost.IsEnhancedContractEnabled) { bytes = System.Text.Encoding.Unicode.GetBytes(strCMD); } else { bytes = System.Text.Encoding.Default.GetBytes(strCMD); } if (!string.IsNullOrEmpty(path)) { item.FinishedFolderCount++; } try { stream.Write(System.Text.Encoding.Default.GetBytes((bytes.Length + 4).ToString("x4")), 0, 4); stream.Write(bytes, 0, bytes.Length); return(true); } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); return(false); } } /// <summary> /// 发送单个文件 /// </summary> /// <param name="client"></param> /// <param name="task"></param> /// <param name="item"></param> void PerformSendFile(TcpClient client, FileTaskInfo task, FileTaskItem item) { System.IO.FileStream fs = null; System.Net.Sockets.NetworkStream writer = null; try { writer = client.GetStream(); } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); return; } try { fs = new System.IO.FileStream(item.FullPath, System.IO.FileMode.Open, System.IO.FileAccess.Read); } catch (Exception) { if (writer != null) { writer.Close(); } TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); OnFileSystemOperationError(new FileSystemOperationErrorEventArgs(FileSystemOperationType.OpenFileToSend, item.FullPath, task.RemoteHost)); return; } using (fs) { //检测断点数据是否正确 if (item.CurrentFileTransfered < 0 || item.CurrentFileTransfered > (ulong)fs.Length) { item.CurrentFileTransfered = 0; } fs.Seek((long)item.CurrentFileTransfered, System.IO.SeekOrigin.Begin); //设置当前任务信息 item.CurrentFileSize = (ulong)fs.Length; TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Processing); item.StartTime = DateTime.Now; using (writer) { byte[] buffer = new byte[SendBuffer]; //缓冲区 while (item.CurrentFileTransfered < item.CurrentFileSize) { int bytesRead = fs.Read(buffer, 0, buffer.Length); try { writer.Write(buffer, 0, bytesRead); } catch (Exception) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Failure); break; } //更新进度 item.CurrentFileTransfered += (ulong)bytesRead; item.FinishedSize += (ulong)bytesRead; } item.FinishedFileCount++; writer.Close(); } fs.Close(); //标记任务完成 if (item.State != FileTaskItemState.Failure) { TaskManager.MarkSendTaskItemState(item, FileTaskItemState.Finished); } } } /// <summary> /// 解析请求的命令 /// </summary> /// <param name="buffer"></param> /// <param name="startIndex"></param> /// <param name="length"></param> /// <returns></returns> Message ParseSendCommand(byte[] buffer, int startIndex, int length) { byte[] cmdInfo = new byte[length]; Array.Copy(buffer, 0, cmdInfo, 0, length); if (!MessagePacker.Test(cmdInfo)) { return(null); } Message msg = MessagePacker.TryToTranslateMessage(cmdInfo, null); if (msg == null || (msg.Command != Consts.Commands.GetDirFiles && msg.Command != Consts.Commands.GetFileData)) { return(null); } return(msg); } /// <summary> /// 接收数据 /// </summary> /// <param name="buffer">缓冲区</param> /// <returns></returns> int ReceiveByBuffer(TcpClient client, byte[] buffer) { try { return(client.Client.Receive(buffer)); } catch (Exception) { //网络异常 return(-1); } } /// <summary> /// 接收数据 /// </summary> /// <param name="buffer">缓冲区</param> /// <returns></returns> int ReceiveByBuffer(TcpClient client, byte[] buffer, int length) { try { return(client.Client.Receive(buffer, length, SocketFlags.None)); } catch (Exception) { //网络异常 return(-1); } } /// <summary> /// 接收数据 /// </summary> /// <param name="buffer">缓冲区</param> /// <returns></returns> int ReceiveByBuffer(NetworkStream stream, byte[] buffer) { try { return(stream.Read(buffer, 0, buffer.Length)); } catch (Exception) { //网络异常 return(-1); } } /// <summary> /// 接收数据 /// </summary> /// <param name="buffer">缓冲区</param> /// <returns></returns> int ReceiveByBuffer(NetworkStream stream, byte[] buffer, int length) { try { return(stream.Read(buffer, 0, length)); } catch (Exception) { //网络异常 return(-1); } } #endregion #region 接收文件 /// <summary> /// 请求接收文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void _taskManager_FileReceiveRequired(object sender, FileReceiveRequiredEventArgs e) { if (!IsInitialized) { return; } new Thread(() => { PerformFileReceive(e.Task, e.Item); }) { IsBackground = true }.Start(); }
/// <summary> /// 初始化设置 /// </summary> /// <param name="client">初始化客户端</param> public override void Initialize(IPMClient client) { base.Initialize(client); _enabled = true; }
/// <summary> /// 构造函数 /// </summary> internal CommandExecutor(IPMClient client) { _client = client; this.Config = client.Config; }
/// <summary> /// 执行初始化(已重载) /// </summary> /// <param name="client">客户端对象</param> public override void Initialize(IPMClient client) { base.Initialize(client); }
/// <summary> /// 初始化加载 /// </summary> /// <param name="client">绑定的客户端</param> /// <returns></returns> public bool Load(IPMClient client) { return Load(client, false); }
/// <summary> /// 初始化指定插件 /// </summary> /// <returns></returns> public bool InitialzingServiceProvider(IPMClient client) { if (State != ServiceState.UnInitialized) return ServiceProvider != null; else { ServiceProvider.Initialize(client); return true; } }
/// <summary> /// 初始化请求(已重载) /// </summary> /// <param name="client">飞鸽传书客户端</param> public override void Initialize(IPMClient client) { }
/// <summary> /// 初始化设置 /// </summary> /// <param name="client">初始化客户端</param> public virtual void Initialize(IPMClient client) { Client = client; }
/// <summary> /// 初始化加载 /// </summary> /// <param name="client">绑定的客户端</param> /// <returns></returns> public bool Load(IPMClient client) { return(Load(client, false)); }