/// <summary> /// Internal connect operation /// </summary> private void InternalConnect() { Commands.Clear(); SetSocketStatus(SocketStatus.Connecting); IPEndPoint host = new IPEndPoint(IPAddress.Parse(Server), Port); _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { _Socket.Connect(host); if (_Socket.Connected) { _SocketReader.Socket = _Socket; _SocketReader.Timeout = ConnectingTimeout; _SocketReader.SleepTime = 10; if (_SocketReader.Read() == SocketReader.ReadStatus.Success && _SocketReader.Type == SocketReader.ReadType.Response && _SocketReader.CommandId == -1) { var response = NetResponse.Parse(_SocketReader.Data); if (response.Okey) { var hash = response.Parameters["hash"] as ParameterInt32; HashCode = hash.Value; SetSocketStatus(SocketStatus.Connected); _ProcessFlag = true; ConnectTime = DateTime.Now; ProcessOperation(); } else { _Socket.Shutdown(SocketShutdown.Both); _Socket.Close(); SetSocketStatus(SocketStatus.None); } } else { _Socket.Shutdown(SocketShutdown.Both); _Socket.Close(); SetSocketStatus(SocketStatus.None); } } else { SetSocketStatus(SocketStatus.None); } } catch //(Exception exception) { if (_Socket != null && _Socket.Connected) { _Socket.Shutdown(SocketShutdown.Both); _Socket.Close(); } SetSocketStatus(SocketStatus.Error); } }
/// <summary> /// Listen and process messages /// </summary> private void ProcessOperation() { var lastCommandDate = DateTime.Now; var time = 0; _SocketReader.Clear(); _SocketReader.SleepTime = 5; _SocketReader.Socket = _Socket; _SocketReader.Timeout = CommandTimeout; NetResponse response = null; try { while (_ProcessFlag) { response = null; if (_Socket.Available > 0) { OnBeginReceiveData(); _SocketReader.Clear(); _SocketReader.Read(); OnEndReceiveData(); if (_SocketReader.LastStatus == SocketReader.ReadStatus.Success) { if (_SocketReader.Type == SocketReader.ReadType.Command) { NetCommand command = NetCommand.Parse(_SocketReader.Data); command.Id = _SocketReader.CommandId; ServerCommandsManager.PublishCommandExecute(command); command.Status = CommandStatus.Executed; if (command.Response == null) { command.Response = new NetResponse(false, "Server command could not be executed"); } Send(command.Response); } else { var command = _SendCommands[_SocketReader.CommandId] as NetCommand; if (command == null) { OnUnknownServerData(); } else { response = NetResponse.Parse(_SocketReader.Data); command.Response = response; command.Status = CommandStatus.Executed; CommandExecutionManager.PublishCommandExecute(command); _SendCommands.Remove(command.Id); } } } else { Disconnect(); } lastCommandDate = DateTime.Now; } else { NetCommand active = null; for (int k = 0; k < Commands.Count; k++) { NetCommand cd = Commands[k, true]; if (cd.Status == CommandStatus.Waiting) { active = cd; break; } } if (active != null) { Commands.Active = active; OnBeginSendingData(); Send(active); OnEndSendingData(); _SendCommands.Add(active.Id, active); } else { time = Convert.ToInt32(DateTime.Now.Subtract(lastCommandDate).TotalMilliseconds); if (KeepConnection && time >= NoopPeriod) { Commands.Add(new NetCommand(CommandNames.NOOP)); } else { if (time > ConnectionTimeout) { break; } } Thread.Sleep(10); } } } } catch (SocketException ex) { if (ex.NativeErrorCode != 0x2745 && ex.NativeErrorCode != 0x2714) { throw ex; } } catch (Exception ex) { OnSystemError(ex); } finally { Disconnect(); } }
/// <summary> /// Process client operations /// </summary> private void ClientProcess() { DateTime lastCommandDate = DateTime.Now; _SocketReader.Socket = Socket; _SocketReader.SleepTime = 5; // 5 ms _SocketReader.Timeout = Server.CommandTimeout; _BadCommandCount = 0; try { // send welcome message to the client var response = new NetResponse(true, "Server is ready at " + DateTime.Now.ToString("yyyyMMdd HH:mm:ss")); response.CommandId = -1; response.Parameters.Add(new ParameterInt32("hash", Guid.GetHashCode())); Send(response); Server.OnClientConnected(this); double time = 0; response = null; bool badcommand = false; NetCommand command = null; while (_IsOnProcess) { response = null; badcommand = false; command = null; if (Socket.Available > 0) { _SocketReader.Clear(); _SocketReader.Read(); lastCommandDate = DateTime.Now; if (_SocketReader.LastStatus == SocketReader.ReadStatus.Success) { try { if (_SocketReader.Type == SocketReader.ReadType.Command) { command = NetCommand.Parse(_SocketReader.Data); command.Id = _SocketReader.CommandId; CommandOperationEventArgs e = new CommandOperationEventArgs(command); OnNewCommand(e); if (!e.Handled) { badcommand = true; } } else { command = _SendedCommands[_SocketReader.CommandId] as NetCommand; if (command != null) { response = NetResponse.Parse(_SocketReader.Data); response.CommandId = _SocketReader.CommandId; command.Response = response; command.Status = CommandStatus.Executed; _SendedCommands.Remove(command.Id); } } } catch (Exception exception) { Server.OnSystemError(exception); badcommand = true; } if (badcommand) { _BadCommandCount++; if (_SocketReader.Type == SocketReader.ReadType.Command) { if (command != null) { response = new NetResponse(false, "Bad command"); command.Response = response; Send(response); command.Status = CommandStatus.Executed; } } else { command = _SendedCommands[response.CommandId] as NetCommand; if (command != null) { command.Response = new NetResponse(false, "Bad command"); command.Status = CommandStatus.Executed; _SendedCommands.Remove(command.Id); } } if (_BadCommandCount > Server.BadCommandCount) { response = new NetResponse(false, "Because of too much bad commands your connection will be terminated"); Send(response); break; } } } else { switch (_SocketReader.LastStatus) { case SocketReader.ReadStatus.Exception: response = new NetResponse(false, "Socket reading exception"); Send(response); break; case SocketReader.ReadStatus.Timeout: response = new NetResponse(false, "Timeout"); Send(response); break; default: response = new NetResponse(false, "Unknow socket reading exception"); Send(response); break; } } } else { NetCommand active = null; for (int k = 0; k < Commands.Count; k++) { NetCommand cd = Commands[k, true]; if (cd.Status == CommandStatus.Waiting) { active = cd; break; } } if (active != null) { active.Status = CommandStatus.SendingToTarget; Send(active); _SendedCommands.Add(active.Id, active); active.Status = CommandStatus.WaitingForResponse; } else { time = DateTime.Now.Subtract(lastCommandDate).TotalMilliseconds; if (time > Server.ConnectionTimeout) { response = new NetResponse(false, "Connection is timeout"); Send(response); Disconnect(); break; } Thread.Sleep(10); } } } } catch (SocketException ex) { if (ex.NativeErrorCode == 0x2745) { // connection close by remote host is not an exception (client might be closed) } else if (ex.NativeErrorCode != 0x2714) // WSACancelBlockCall (We might close) { Server.OnSystemError(new Exception(string.Format("Socket exception in Client {0}", Guid.ToString("N")), ex)); } } catch (Exception ex) { Server.OnSystemError(new Exception(string.Format("Exception in Client {0}", Guid.ToString("N")), ex)); } finally{ Disconnect(); } }