/// <summary> /// 收到报文头的处理过程. /// </summary> /// <param name="state">state对象.</param> /// <param name="length">已从缓冲区读取的字节数.</param> /// <returns>成功返回NULL, 失败返回错误信息.</returns> private string ReceivedHeader(UserState state, int length) { string headerError; if ((headerError = SetMsgHeader(length, state)) != null) return headerError; // 设置成功, 通知客户端可以继续. string sendMsg = null; try { var sendAct = ResponseMessageAction.Go; // 如果action为transferfileunknow, 提示用户 if (state.ReqHeader.Action == RequestHeaderAction.SendFileUnknow) { state.ReqHeader.Action = RequestHeaderAction.SendFileCreate; if (File.Exists(Instance.StartArgs.UploadFile)) { var fi = new FileInfo(Instance.StartArgs.UploadFile); sendAct = ResponseMessageAction.Ask; sendMsg = string.Format("服务器已存在此文件, 大小: {0}, 写入日期: {1}", fi.Length, fi.LastWriteTime); state.Refresh(); } } // 没有消息正文的几种情况 if (state.ReqHeader.Action == RequestHeaderAction.Backup || state.ReqHeader.Action == RequestHeaderAction.StopIIS || state.ReqHeader.Action == RequestHeaderAction.StartIIS || state.ReqHeader.Action == RequestHeaderAction.Update) { var error = state.ReqHeader.Action == RequestHeaderAction.Backup ? BackupWeb() : state.ReqHeader.Action == RequestHeaderAction.Update ? UpdateWeb() : state.ReqHeader.Action == RequestHeaderAction.StopIIS ? StopIIS() : StartIIS(); if (error != null) return error; state.Refresh(); } new ResponseMessage { Action = sendAct, Message = sendMsg }.SendToClient(state.WorkSocket); } catch (Exception exp) { ServerLog.Write(string.Format("主服务在发送信息至客户端时发生错误: {0}, 信息内容: {1}", exp.Message, sendMsg), EventLogEntryType.Warning); return string.Empty; } return null; }
/// <summary> /// 收到正文的处理过程. /// </summary> /// <param name="state">state对象.</param> /// <param name="length">已从缓冲区读取的字节数.</param> /// <returns>成功返回True, 失败须结束state.socket</returns> private string ReceivedBody(UserState state, int length) { // 要响应到客户端的消息 string msgAck = null; // 用户未鉴权, 退出 if (!state.IsAuthentication && state.ReqHeader.Action != RequestHeaderAction.Authentication) return "用户未鉴权."; // 第一次接收? var isFirstReceiveBody = state.ReceivedLength == 0; // 接收总字节数增加. state.ReceivedLength += length; // 根据报文头定义的正文长度读取数据 switch (state.ReqHeader.Action) { case RequestHeaderAction.SendFileCreate: // 如果是第一次读缓冲区, 则根据报头创建新文件., 否则追加文件 try { Util.WriteFile(Instance.StartArgs.UploadFile, isFirstReceiveBody ? FileMode.Create : FileMode.Append, state.Buffer, length); } catch (Exception exp) { ServerLog.Write(string.Format("压缩文件 {0} 写入失败: {1}", Instance.StartArgs.UploadFile, exp.Message), EventLogEntryType.Warning); return "文件写入失败."; } break; // 追加模式 case RequestHeaderAction.SendFileAppend: try { Util.WriteFile(Instance.StartArgs.UploadFile, FileMode.Append, state.Buffer, length); } catch (Exception exp) { ServerLog.Write(string.Format("压缩文件 {0} 写入失败: {1}", Instance.StartArgs.UploadFile, exp.Message), EventLogEntryType.Warning); return "文件写入失败."; } break; case RequestHeaderAction.Authentication: state.StrContainer.Append(Encoding.UTF8.GetString(state.Buffer, 0, length)); if (state.ReceivedLength == state.ReqHeader.BodyLength) { if (state.StrContainer.ToString() != Instance.StartArgs.AuthKey) // 验证失败了. return "用户鉴权失败."; // 鉴权成功 state.IsAuthentication = true; msgAck = state.Id; } break; case RequestHeaderAction.VerifyFileMd5: state.StrContainer.Append(Encoding.UTF8.GetString(state.Buffer, 0, length)); if (state.ReceivedLength == state.ReqHeader.BodyLength) { if (state.StrContainer.ToString() != Util.GetFileMd5(Instance.StartArgs.UploadFile)) // MD5验证失败了. return "文件MD5验证失败."; } break; default: return string.Empty; } // 如果接收的字节总长已经达到MsgHeader中指定. 则视为接收完毕. if (state.ReceivedLength == state.ReqHeader.BodyLength) { // 一个回合结束了, 清除State的已存信息, 恢复state状态为waitaction state.Refresh(); // 响应客户端 try { new ResponseMessage { Action = ResponseMessageAction.Go, Message = msgAck }.SendToClient(state.WorkSocket); } catch (Exception exp) { ServerLog.Write(string.Format("主服务在发送信息至客户端时发生错误: {0}, 信息内容: {1}", exp.Message, msgAck), EventLogEntryType.Warning); return string.Empty; } } return null; }