Ejemplo n.º 1
0
        private void AddUser(string ipPort, JoinPayload payload)
        {
            Logger.Info($"Client from '{ipPort}' wants to join chat server.");
            if (string.IsNullOrWhiteSpace(payload.Name) || string.IsNullOrWhiteSpace(payload.Color))
            {
                Logger.Debug($"Client '{ipPort}' has no name or no color.");
                _server.DisconnectClient(ipPort, MessageStatus.Failure);
                return;
            }

            var user = new User
            {
                Id     = Guid.NewGuid(),
                Name   = payload.Name,
                Color  = payload.Color,
                IpPort = ipPort
            };
            var clientPayload = new JoinedPayload(user.Id, user.Name, user.Color);
            var clientPacket  = new ClientPacket(ClientAction.Joined, clientPayload);

            SendToAllUsers(clientPacket);

            Users.Add(user);
            InvokeUserJoinEvent(user);
        }
 /// <summary>
 /// Al conectarse un cliente TCP al servidor
 /// </summary>
 /// <param name="ipPort">IP:Puerto</param>
 private bool TcpServer_OnNodeConnected(string ipPort)
 {
     if (m_connectedRootNode != null)
     {
         if (m_killOnConnect)
         {
             m_tcpServer.DisconnectClient(m_connectedRootNode);
             m_connectedRootNode = null;
         }
         else
         {
             if (!m_tcpServer.IsClientConnected(m_connectedRootNode))
             {
                 m_connectedRootNode = null;
             }
         }
     }
     if (m_connectedRootNode == null)
     {
         m_connectedRootNode = ipPort;
         Debug.WriteLine(this, "Se ha conectado un nodo raíz al servidor TCP para MDF: " + ipPort, VerbosityLevel.Info);
     }
     else
     {
         m_tcpServer.DisconnectClient(ipPort);
         Debug.WriteLine(this, "Se ha intentado conectar un nuevo nodo raíz al servidor TCP mientras que ya habia uno registrado, se ha desconectado la nueva conexión: " + ipPort, VerbosityLevel.Warning);
     }
     return(true);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Disconnect a remote client.
 /// </summary>
 /// <param name="ipPort">IP address and port of the remoteclient, of the form IP:port.</param>
 public void DisconnectClient(string ipPort)
 {
     Console.WriteLine("DisconnectClient " + ipPort);
     if (String.IsNullOrEmpty(ipPort))
     {
         throw new ArgumentNullException(nameof(ipPort));
     }
     _TcpServer.DisconnectClient(ipPort);
 }
Ejemplo n.º 4
0
 internal void DisconnectClient(string ipPort)
 {
     if (String.IsNullOrEmpty(ipPort))
     {
         throw new ArgumentNullException(nameof(ipPort));
     }
     Logger?.Invoke("[MeshServer] Disconnecting client " + ipPort);
     _TcpServer.DisconnectClient(ipPort);
 }
Ejemplo n.º 5
0
    private static void ClientConnected(object sender, ConnectionEventArgs e)
    {
        Debug.Log($"Client from {e.IpPort} connected!");

        for (int i = 1; i <= MaxPlayers; i++)
        {
            if (!clients[i].player)
            {
                Client client = clients[i];
                clients[i].Connect(e.IpPort);
                return;
            }
        }

        //disconnect player if no room
        server.DisconnectClient(e.IpPort);
    }
Ejemplo n.º 6
0
        private bool MessageReceived(string ipPort, byte[] data)
        {
            if (data == null || data.Length <= 0)
            {
                return(false);
            }

            try
            {
                using (var stream = new MemoryStream(data))
                {
                    var bProtocolVersion = new byte[4];
                    stream.Read(bProtocolVersion, 0, 4);
                    var protocolVersion = BitConverter.ToInt32(bProtocolVersion, 0);
                    if (protocolVersion != Protocol.Version)
                    {
                        throw new Exception($"Invalid protocol version {ipPort}");
                    }

                    var bPacketId = new byte[4];
                    stream.Read(bPacketId, 0, 4);
                    var packetId = (Protocols)BitConverter.ToInt32(bPacketId, 0);

                    Console.WriteLine("Received PID {0} from {1}", Enum.GetName(typeof(Protocols), packetId), ipPort);

                    // ReSharper disable once SwitchStatementMissingSomeCases
                    switch (packetId)
                    {
                    case Protocols.LOGIN_REQ:
                        var loginReq = Serializer.Deserialize <LoginReq>(stream);
                        var user     = _handler.OnLoginReq(loginReq, ipPort, _authUsers);

                        if (user != null)
                        {
                            if (!_authUsers.ContainsKey(ipPort))
                            {
                                _authUsers.Add(ipPort, user);
                            }
                        }
                        break;

                    case Protocols.ZONECOUNT_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Guest))
                        {
                            goto default;
                        }

                        _handler.OnZoneCountReq(ipPort);
                        break;

                    case Protocols.ZONELIST_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Guest))
                        {
                            goto default;
                        }
                        _handler.OnZoneListReq(ipPort);
                        break;

                    case Protocols.INSERTZONE_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var insertZoneReq = Serializer.Deserialize <InsertZoneReq>(stream);
                        _handler.OnInsertZoneReqAsync(insertZoneReq, ipPort);
                        break;

                    case Protocols.REMOVEZONE_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var removeZoneReq = Serializer.Deserialize <RemoveZoneReq>(stream);
                        _handler.OnRemoveZoneReq(removeZoneReq, ipPort);
                        break;

                    case Protocols.UPDATEZONE_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var updateZoneReq = Serializer.Deserialize <UpdateZoneReq>(stream);
                        _handler.OnUpdateZoneReq(updateZoneReq, ipPort);
                        break;

                    case Protocols.REMOVEPOINT_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var removePointReq = Serializer.Deserialize <RemovePointReq>(stream);
                        _handler.OnRemovePointReq(removePointReq, ipPort);
                        break;

                    case Protocols.INSERTPOINT_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var insertPointReq = Serializer.Deserialize <InsertPointReq>(stream);
                        _handler.OnInsertPointReqAsync(insertPointReq, ipPort);
                        break;

                    case Protocols.UPDATEPOINT_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var updatePointReq = Serializer.Deserialize <UpdatePointReq>(stream);
                        _handler.OnUpdatePointReq(updatePointReq, ipPort);
                        break;

                    case Protocols.CITYLIST_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Editor))
                        {
                            goto default;
                        }

                        _handler.OnCityListReqAsync(ipPort);
                        break;

                    case Protocols.USERLIST_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Admin))
                        {
                            goto default;
                        }

                        _handler.OnUserListReqAsync(ipPort);
                        break;

                    case Protocols.INSERTUSER_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var insertUserReq = Serializer.Deserialize <InsertUserReq>(stream);
                        _handler.OnInsertUserReq(insertUserReq);
                        break;

                    case Protocols.REMOVEUSER_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var removeUserReq = Serializer.Deserialize <RemoveUserReq>(stream);
                        _handler.OnRemoveUserReq(removeUserReq);
                        break;

                    case Protocols.UPDATEUSER_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var updateUserReq = Serializer.Deserialize <UpdateUserReq>(stream);
                        _handler.OnUpdateUserReq(updateUserReq);
                        break;

                    case Protocols.ISDUPLICATEUSER_REQ:
                        if (!CheckPrivileges(ipPort, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var isDuplicateUserReq = Serializer.Deserialize <IsDuplicateUserReq>(stream);
                        _handler.IsDuplicateUserReq(isDuplicateUserReq, ipPort);
                        break;

                    default:
                        _watsonTcpServer.DisconnectClient(ipPort);
                        Console.WriteLine("Invalid message from {0}", ipPort);
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                _watsonTcpServer.DisconnectClient(ipPort);
            }

            return(true);
        }
Ejemplo n.º 7
0
        private static void Main(string[] args)
        {
            serverIp   = InputString("Server IP:", "127.0.0.1", false);
            serverPort = InputInteger("Server port:", 9000, true, false);
            useSsl     = InputBoolean("Use SSL:", false);

            if (!useSsl)
            {
                server = new WatsonTcpServer(serverIp, serverPort);
            }
            else
            {
                certFile             = InputString("Certificate file:", "test.pfx", false);
                certPass             = InputString("Certificate password:"******"password", false);
                acceptInvalidCerts   = InputBoolean("Accept invalid certs:", true);
                mutualAuthentication = InputBoolean("Mutually authenticate:", false);

                server = new WatsonTcpServer(serverIp, serverPort, certFile, certPass);
                server.AcceptInvalidCertificates = acceptInvalidCerts;
                server.MutuallyAuthenticate      = mutualAuthentication;
            }

            server.ClientConnected    = ClientConnected;
            server.ClientDisconnected = ClientDisconnected;
            server.MessageReceived    = MessageReceived;
            server.Debug = debug;
            server.Start();

            bool runForever = true;

            while (runForever)
            {
                Console.Write("Command [? for help]: ");
                string userInput = Console.ReadLine();

                List <string> clients;
                string        ipPort;
                bool          success = false;

                if (String.IsNullOrEmpty(userInput))
                {
                    continue;
                }

                switch (userInput)
                {
                case "?":
                    Console.WriteLine("Available commands:");
                    Console.WriteLine("  ?          help (this menu)");
                    Console.WriteLine("  q          quit");
                    Console.WriteLine("  cls        clear screen");
                    Console.WriteLine("  list       list clients");
                    Console.WriteLine("  dispose    dispose of the connection");
                    Console.WriteLine("  send       send message to client");
                    Console.WriteLine("  sendasync  send message to a client asynchronously");
                    Console.WriteLine("  remove     disconnect client");
                    Console.WriteLine("  psk        set preshared key");
                    Console.WriteLine("  debug      enable/disable debug (currently " + server.Debug + ")");
                    break;

                case "q":
                    runForever = false;
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "list":
                    clients = server.ListClients();
                    if (clients != null && clients.Count > 0)
                    {
                        Console.WriteLine("Clients");
                        foreach (string curr in clients)
                        {
                            Console.WriteLine("  " + curr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "dispose":
                    server.Dispose();
                    break;

                case "send":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    if (String.IsNullOrEmpty(ipPort))
                    {
                        break;
                    }
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    success = server.Send(ipPort, Encoding.UTF8.GetBytes(userInput));
                    Console.WriteLine(success);
                    break;

                case "sendasync":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    if (String.IsNullOrEmpty(ipPort))
                    {
                        break;
                    }
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    success = server.SendAsync(ipPort, Encoding.UTF8.GetBytes(userInput)).Result;
                    Console.WriteLine(success);
                    break;

                case "remove":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    server.DisconnectClient(ipPort);
                    break;

                case "psk":
                    server.PresharedKey = InputString("Preshared key:", "1234567812345678", false);
                    break;

                case "debug":
                    server.Debug = !server.Debug;
                    Console.WriteLine("Debug set to: " + server.Debug);
                    break;

                default:
                    break;
                }
            }
        }
Ejemplo n.º 8
0
        private static void Main(string[] args)
        {
            serverIp   = InputString("Server IP:", "127.0.0.1", false);
            serverPort = InputInteger("Server port:", 9000, true, false);
            useSsl     = InputBoolean("Use SSL:", false);

            try
            {
                if (!useSsl)
                {
                    server = new WatsonTcpServer(serverIp, serverPort);
                }
                else
                {
                    certFile             = InputString("Certificate file:", "test.pfx", false);
                    certPass             = InputString("Certificate password:"******"password", false);
                    acceptInvalidCerts   = InputBoolean("Accept invalid certs:", true);
                    mutualAuthentication = InputBoolean("Mutually authenticate:", false);

                    server = new WatsonTcpServer(serverIp, serverPort, certFile, certPass);
                    server.AcceptInvalidCertificates = acceptInvalidCerts;
                    server.MutuallyAuthenticate      = mutualAuthentication;
                }

                server.ClientConnected    += ClientConnected;
                server.ClientDisconnected += ClientDisconnected;
                server.MessageReceived    += MessageReceived;
                server.SyncRequestReceived = SyncRequestReceived;
                // server.PresharedKey = "0000000000000000";
                // server.IdleClientTimeoutSeconds = 10;
                server.Logger        = Logger;
                server.DebugMessages = debugMessages;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return;
            }

            // server.Start();
            Task serverStart = server.StartAsync();

            bool          runForever = true;
            List <string> clients;
            string        ipPort;
            Dictionary <object, object> metadata;
            bool success = false;

            while (runForever)
            {
                string userInput = InputString("Command [? for help]:", null, false);

                switch (userInput)
                {
                case "?":
                    Console.WriteLine("Available commands:");
                    Console.WriteLine("  ?                   help (this menu)");
                    Console.WriteLine("  q                   quit");
                    Console.WriteLine("  cls                 clear screen");
                    Console.WriteLine("  list                list clients");
                    Console.WriteLine("  dispose             dispose of the connection");
                    Console.WriteLine("  send                send message to client");
                    Console.WriteLine("  send md             send message with metadata to client");
                    Console.WriteLine("  sendasync           send message to a client asynchronously");
                    Console.WriteLine("  sendasync md        send message with metadata to a client asynchronously");
                    Console.WriteLine("  sendandwait         send message and wait for a response");
                    Console.WriteLine("  sendempty           send empty message with metadata");
                    Console.WriteLine("  sendandwait empty   send empty message with metadata and wait for a response");
                    Console.WriteLine("  remove              disconnect client");
                    Console.WriteLine("  psk                 set preshared key");
                    Console.WriteLine("  stats               display server statistics");
                    Console.WriteLine("  stats reset         reset statistics other than start time and uptime");
                    Console.WriteLine("  comp                set the compression type, currently: " + server.Compression.ToString());
                    Console.WriteLine("  debug               enable/disable debug (currently " + server.DebugMessages + ")");
                    break;

                case "q":
                    runForever = false;
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "list":
                    clients = server.ListClients().ToList();
                    if (clients != null && clients.Count > 0)
                    {
                        Console.WriteLine("Clients");
                        foreach (string curr in clients)
                        {
                            Console.WriteLine("  " + curr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "dispose":
                    server.Dispose();
                    break;

                case "send":
                    ipPort    = InputString("IP:port:", lastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    if (!server.Send(ipPort, userInput))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "send md":
                    ipPort    = InputString("IP:port:", lastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    metadata  = InputDictionary();
                    if (!server.Send(ipPort, metadata, userInput))
                    {
                        Console.WriteLine("Failed");
                    }
                    Console.WriteLine(success);
                    break;

                case "send md large":
                    ipPort   = InputString("IP:port:", lastIpPort, false);
                    metadata = new Dictionary <object, object>();
                    for (int i = 0; i < 100000; i++)
                    {
                        metadata.Add(i, i);
                    }
                    if (!server.Send(ipPort, metadata, "Hello!"))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendasync":
                    ipPort    = InputString("IP:port:", lastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    success   = server.SendAsync(ipPort, Encoding.UTF8.GetBytes(userInput)).Result;
                    if (!success)
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendasync md":
                    ipPort    = InputString("IP:port:", lastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    metadata  = InputDictionary();
                    success   = server.SendAsync(ipPort, metadata, Encoding.UTF8.GetBytes(userInput)).Result;
                    if (!success)
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendandwait":
                    SendAndWait();
                    break;

                case "sendempty":
                    ipPort   = InputString("IP:port:", lastIpPort, false);
                    metadata = InputDictionary();
                    if (!server.Send(ipPort, metadata))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendandwait empty":
                    SendAndWaitEmpty();
                    break;

                case "remove":
                    ipPort = InputString("IP:port:", lastIpPort, false);
                    server.DisconnectClient(ipPort);
                    break;

                case "psk":
                    server.PresharedKey = InputString("Preshared key:", "1234567812345678", false);
                    break;

                case "stats":
                    Console.WriteLine(server.Stats.ToString());
                    break;

                case "stats reset":
                    server.Stats.Reset();
                    break;

                case "comp":
                    server.Compression = (CompressionType)(Enum.Parse(typeof(CompressionType), InputString("Compression [None|Default|Gzip]:", "None", false)));
                    break;

                case "debug":
                    server.DebugMessages = !server.DebugMessages;
                    Console.WriteLine("Debug set to: " + server.DebugMessages);
                    break;

                default:
                    break;
                }
            }
        }
Ejemplo n.º 9
0
        private static void Main(string[] args)
        {
            serverIp   = InputString("Server IP:", "127.0.0.1", false);
            serverPort = InputInteger("Server port:", 9000, true, false);
            useSsl     = InputBoolean("Use SSL:", false);

            if (!useSsl)
            {
                server = new WatsonTcpServer(serverIp, serverPort);
            }
            else
            {
                certFile             = InputString("Certificate file:", "test.pfx", false);
                certPass             = InputString("Certificate password:"******"password", false);
                acceptInvalidCerts   = InputBoolean("Accept Invalid Certs:", true);
                mutualAuthentication = InputBoolean("Mutually authenticate:", true);

                server = new WatsonTcpServer(serverIp, serverPort, certFile, certPass);
                server.AcceptInvalidCertificates = acceptInvalidCerts;
                server.MutuallyAuthenticate      = mutualAuthentication;
            }

            server.ClientConnected    += ClientConnected;
            server.ClientDisconnected += ClientDisconnected;
            server.StreamReceived     += StreamReceived;
            server.SyncRequestReceived = SyncRequestReceived;
            server.Logger = Logger;
            // server.Debug = true;
            server.Start();

            bool runForever = true;

            while (runForever)
            {
                Console.Write("Command [? for help]: ");
                string userInput = Console.ReadLine();

                byte[]       data = null;
                MemoryStream ms   = null;
                Dictionary <object, object> metadata;
                bool success = false;

                List <string> clients;
                string        ipPort;

                if (String.IsNullOrEmpty(userInput))
                {
                    continue;
                }

                switch (userInput)
                {
                case "?":
                    Console.WriteLine("Available commands:");
                    Console.WriteLine("  ?              help (this menu)");
                    Console.WriteLine("  q              quit");
                    Console.WriteLine("  cls            clear screen");
                    Console.WriteLine("  list           list clients");
                    Console.WriteLine("  send           send message to client");
                    Console.WriteLine("  send md        send message with metadata to client");
                    Console.WriteLine("  sendasync      send message to a client asynchronously");
                    Console.WriteLine("  sendasync md   send message with metadata to a client asynchronously");
                    Console.WriteLine("  sendandwait    send message and wait for a response");
                    Console.WriteLine("  remove         disconnect client");
                    Console.WriteLine("  psk            set preshared key");
                    Console.WriteLine("  debug          enable/disable debug (currently " + server.DebugMessages + ")");
                    break;

                case "q":
                    runForever = false;
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "list":
                    clients = server.ListClients().ToList();
                    if (clients != null && clients.Count > 0)
                    {
                        Console.WriteLine("Clients");
                        foreach (string curr in clients)
                        {
                            Console.WriteLine("  " + curr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "send":
                    ipPort = InputString("IP:port:", lastIpPort, false);
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    data    = Encoding.UTF8.GetBytes(userInput);
                    ms      = new MemoryStream(data);
                    success = server.Send(ipPort, data.Length, ms);
                    Console.WriteLine(success);
                    break;

                case "send md":
                    ipPort   = InputString("IP:port:", lastIpPort, false);
                    metadata = InputDictionary();
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    data    = Encoding.UTF8.GetBytes(userInput);
                    ms      = new MemoryStream(data);
                    success = server.Send(ipPort, metadata, data.Length, ms);
                    Console.WriteLine(success);
                    break;

                case "sendasync":
                    ipPort = InputString("IP:port:", lastIpPort, false);
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    data    = Encoding.UTF8.GetBytes(userInput);
                    ms      = new MemoryStream(data);
                    success = server.SendAsync(ipPort, data.Length, ms).Result;
                    Console.WriteLine(success);
                    break;

                case "sendasync md":
                    ipPort   = InputString("IP:port:", lastIpPort, false);
                    metadata = InputDictionary();
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    data    = Encoding.UTF8.GetBytes(userInput);
                    ms      = new MemoryStream(data);
                    success = server.SendAsync(ipPort, metadata, data.Length, ms).Result;
                    Console.WriteLine(success);
                    break;

                case "sendandwait":
                    SendAndWait();
                    break;

                case "remove":
                    ipPort = InputString("IP:port:", lastIpPort, false);
                    server.DisconnectClient(ipPort);
                    break;

                case "psk":
                    server.PresharedKey = InputString("Preshared key:", "1234567812345678", false);
                    break;

                case "debug":
                    server.DebugMessages = !server.DebugMessages;
                    Console.WriteLine("Debug set to: " + server.DebugMessages);
                    break;

                default:
                    break;
                }
            }
        }
Ejemplo n.º 10
0
        private static void Main(string[] args)
        {
            serverIp   = InputString("Server IP:", "127.0.0.1", false);
            serverPort = InputInteger("Server port:", 9000, true, false);
            useSsl     = InputBoolean("Use SSL:", false);

            try
            {
                if (!useSsl)
                {
                    server = new WatsonTcpServer(serverIp, serverPort);
                }
                else
                {
                    certFile             = InputString("Certificate file:", "test.pfx", false);
                    certPass             = InputString("Certificate password:"******"password", false);
                    acceptInvalidCerts   = InputBoolean("Accept invalid certs:", true);
                    mutualAuthentication = InputBoolean("Mutually authenticate:", false);

                    server = new WatsonTcpServer(serverIp, serverPort, certFile, certPass);
                    server.AcceptInvalidCertificates = acceptInvalidCerts;
                    server.MutuallyAuthenticate      = mutualAuthentication;
                }

                server.ClientConnected    += ClientConnected;
                server.ClientDisconnected += ClientDisconnected;
                server.MessageReceived    += MessageReceived;
                // server.IdleClientTimeoutSeconds = 10;
                server.Logger        = Logger;
                server.DebugMessages = debug;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return;
            }

            // server.Start();
            Task serverStart = server.StartAsync();

            bool runForever = true;

            while (runForever)
            {
                Console.Write("Command [? for help]: ");
                string userInput = Console.ReadLine();

                List <string> clients;
                string        ipPort;
                Dictionary <object, object> metadata;
                bool success = false;

                if (String.IsNullOrEmpty(userInput))
                {
                    continue;
                }

                switch (userInput)
                {
                case "?":
                    Console.WriteLine("Available commands:");
                    Console.WriteLine("  ?              help (this menu)");
                    Console.WriteLine("  q              quit");
                    Console.WriteLine("  cls            clear screen");
                    Console.WriteLine("  list           list clients");
                    Console.WriteLine("  dispose        dispose of the connection");
                    Console.WriteLine("  send           send message to client");
                    Console.WriteLine("  send md        send message with metadata to client");
                    Console.WriteLine("  sendasync      send message to a client asynchronously");
                    Console.WriteLine("  sendasync md   send message with metadata to a client asynchronously");
                    Console.WriteLine("  remove         disconnect client");
                    Console.WriteLine("  psk            set preshared key");
                    Console.WriteLine("  stats          display server statistics");
                    Console.WriteLine("  stats reset    reset statistics other than start time and uptime");
                    Console.WriteLine("  conn           show connection count");
                    Console.WriteLine("  max            set max connections (currently " + server.MaxConnections + ")");
                    Console.WriteLine("  debug          enable/disable debug (currently " + server.DebugMessages + ")");
                    break;

                case "q":
                    runForever = false;
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "list":
                    clients = server.ListClients().ToList();
                    if (clients != null && clients.Count > 0)
                    {
                        Console.WriteLine("Clients");
                        foreach (string curr in clients)
                        {
                            Console.WriteLine("  " + curr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "dispose":
                    server.Dispose();
                    break;

                case "send":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    if (String.IsNullOrEmpty(ipPort))
                    {
                        break;
                    }
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    success = server.Send(ipPort, Encoding.UTF8.GetBytes(userInput));
                    Console.WriteLine(success);
                    break;

                case "send md":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    if (String.IsNullOrEmpty(ipPort))
                    {
                        break;
                    }
                    metadata = InputDictionary();
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    success = server.Send(ipPort, metadata, Encoding.UTF8.GetBytes(userInput));
                    Console.WriteLine(success);
                    break;

                case "sendasync":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    if (String.IsNullOrEmpty(ipPort))
                    {
                        break;
                    }
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    success = server.SendAsync(ipPort, Encoding.UTF8.GetBytes(userInput)).Result;
                    Console.WriteLine(success);
                    break;

                case "sendasync md":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    if (String.IsNullOrEmpty(ipPort))
                    {
                        break;
                    }
                    metadata = InputDictionary();
                    Console.Write("Data: ");
                    userInput = Console.ReadLine();
                    if (String.IsNullOrEmpty(userInput))
                    {
                        break;
                    }
                    success = server.SendAsync(ipPort, metadata, Encoding.UTF8.GetBytes(userInput)).Result;
                    Console.WriteLine(success);
                    break;

                case "remove":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    server.DisconnectClient(ipPort);
                    break;

                case "psk":
                    server.PresharedKey = InputString("Preshared key:", "1234567812345678", false);
                    break;

                case "stats":
                    Console.WriteLine(server.Stats.ToString());
                    break;

                case "stats reset":
                    server.Stats.Reset();
                    break;

                case "conn":
                    Console.WriteLine("Connections: " + server.Connections);
                    break;

                case "max":
                    server.MaxConnections = InputInteger("Max connections:", 4096, true, false);
                    break;

                case "debug":
                    server.DebugMessages = !server.DebugMessages;
                    Console.WriteLine("Debug set to: " + server.DebugMessages);
                    break;

                default:
                    break;
                }
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Processing and deserialization of incoming messages
        /// </summary>
        /// <param name="ipPort">IP:Port of the sender client</param>
        /// <param name="data">Byte array that contains data</param>
        /// <returns></returns>
        private bool MessageReceived(string ipPort, byte[] data)
        {
            if (data == null || data.Length <= 0)
            {
                return(false);
            }

            try
            {
                var ipOnly = ipPort.Split(':')[0];
                var user   = Guard.GetAuthUser(ipPort);

                // If the client is banned, drop the cconnection
                if (Guard.IsBanned(ipOnly) && !Guard.CheckExpired(ipOnly))
                {
                    throw new Exception($"Refused to process requests from {ipOnly}. Ip banned!");
                }

                using (var stream = new MemoryStream(data))
                {
                    // Check protocol version
                    // TODO: MessageReceived should not even get called if the protocol dont't match
                    var bProtocolVersion = new byte[4];
                    stream.Read(bProtocolVersion, 0, 4);
                    var protocolVersion = BitConverter.ToInt32(bProtocolVersion, 0);
                    if (protocolVersion != Protocol.Version)
                    {
                        throw new Exception($"Invalid protocol version {ipPort}");
                    }

                    // Fetch packet id
                    var bPacketId = new byte[4];
                    stream.Read(bPacketId, 0, 4);
                    var packetId = (Protocols)BitConverter.ToInt32(bPacketId, 0);

                    ConsoleKit.Message(ConsoleKit.MessageType.INFO, "PID {0} received from {1}\n", Enum.GetName(typeof(Protocols), packetId), ipPort);

                    // ReSharper disable once SwitchStatementMissingSomeCases
                    // Process each message type
                    switch (packetId)
                    {
                    case Protocols.LOGIN_REQ:
                        var  loginReq = Serializer.Deserialize <LoginReq>(stream);
                        User loginUser;

                        if (user != null)
                        {
                            Send(ipPort, new LoginDuplicateAck());
                        }
                        else
                        {
                            loginUser = _handler.OnLoginReq(loginReq, ipPort);

                            if (loginUser != null)
                            {
                                Guard.AddAuthUser(loginUser);
                                BroadcastOnlineUsersAck();
                            }
                            else
                            {
                                Guard.TryCheck(ipOnly);
                            }
                        }

                        break;

                    case Protocols.ZONECOUNT_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Guest))
                        {
                            goto default;
                        }

                        _handler.OnZoneCountReq(ipPort);
                        break;

                    case Protocols.ZONELIST_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Guest))
                        {
                            goto default;
                        }
                        _handler.OnZoneListReq(ipPort);
                        break;

                    case Protocols.INSERTZONE_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var insertZoneReq = Serializer.Deserialize <InsertZoneReq>(stream);
                        _handler.OnInsertZoneReqAsync(insertZoneReq, user);
                        break;

                    case Protocols.REMOVEZONE_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var removeZoneReq = Serializer.Deserialize <RemoveZoneReq>(stream);
                        _handler.OnRemoveZoneReq(removeZoneReq, user);
                        break;

                    case Protocols.UPDATEZONE_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var updateZoneReq = Serializer.Deserialize <UpdateZoneReq>(stream);
                        _handler.OnUpdateZoneReq(updateZoneReq, user);
                        break;

                    case Protocols.REMOVEPOINT_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var removePointReq = Serializer.Deserialize <RemovePointReq>(stream);
                        _handler.OnRemovePointReq(removePointReq, user);
                        break;

                    case Protocols.INSERTPOINT_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var insertPointReq = Serializer.Deserialize <InsertPointReq>(stream);
                        _handler.OnInsertPointReqAsync(insertPointReq, user);
                        break;

                    case Protocols.UPDATEPOINT_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        var updatePointReq = Serializer.Deserialize <UpdatePointReq>(stream);
                        _handler.OnUpdatePointReq(updatePointReq, user);
                        break;

                    case Protocols.CITYLIST_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Editor))
                        {
                            goto default;
                        }

                        _handler.OnCityListReqAsync(user);
                        break;

                    case Protocols.USERLIST_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        _handler.OnUserListReqAsync(user);
                        break;

                    case Protocols.INSERTUSER_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var insertUserReq = Serializer.Deserialize <InsertUserReq>(stream);
                        _handler.OnInsertUserReq(insertUserReq);
                        break;

                    case Protocols.REMOVEUSER_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var removeUserReq = Serializer.Deserialize <RemoveUserReq>(stream);
                        _handler.OnRemoveUserReq(removeUserReq);
                        break;

                    case Protocols.UPDATEUSER_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var updateUserReq = Serializer.Deserialize <UpdateUserReq>(stream);
                        _handler.OnUpdateUserReq(updateUserReq);
                        break;

                    case Protocols.ISDUPLICATEUSER_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var isDuplicateUserReq = Serializer.Deserialize <IsDuplicateUserReq>(stream);
                        _handler.OnIsDuplicateUserReq(isDuplicateUserReq, user);
                        break;

                    case Protocols.ONLINEUSERS_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }
                        _handler.OnOnlineUsersReq(user);
                        break;

                    case Protocols.DISCONNECTUSER_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var disconnectUserReq = Serializer.Deserialize <DisconnectUserReq>(stream);
                        _handler.OnDisconnectUserReq(disconnectUserReq);
                        break;

                    case Protocols.BANIPADDRESS_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var banIpAddressReq = Serializer.Deserialize <BanIpAddressReq>(stream);
                        _handler.OnBanIPAddressReq(banIpAddressReq, user);
                        break;

                    case Protocols.LISTBANNEDIPS_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        _handler.OnListBannedIPsReq(user);
                        break;

                    case Protocols.UNBANIPADDRESS_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var unbanIpAddressReq = Serializer.Deserialize <UnbanIPAddressReq>(stream);
                        _handler.OnUnbanIPAddressReq(unbanIpAddressReq, user);
                        break;

                    case Protocols.COMMAND_REQ:
                        if (!Guard.CheckPrivileges(user, GroupRole.Admin))
                        {
                            goto default;
                        }

                        var commandReq = Serializer.Deserialize <CommandReq>(stream);
                        _handler.OnCommandReq(commandReq, user);
                        break;

                    default:
                        // Unknown or invalid message.
                        // Increase tries and disconnecct the client
                        Guard.TryCheck(ipOnly);
                        _watsonTcpServer.DisconnectClient(ipPort);
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                // Print out the exception and disconnect the client that might have caused it
                ConsoleKit.Message(ConsoleKit.MessageType.ERROR, e.Message + "\n" + e.StackTrace + "\n");
                _watsonTcpServer.DisconnectClient(ipPort);
            }

            return(true);
        }
Ejemplo n.º 12
0
        private static void Main(string[] args)
        {
            _ServerIp   = InputString("Server IP:", "localhost", false);
            _ServerPort = InputInteger("Server port:", 9000, true, false);
            _Ssl        = InputBoolean("Use SSL:", false);

            try
            {
                if (!_Ssl)
                {
                    _Server = new WatsonTcpServer(_ServerIp, _ServerPort);
                }
                else
                {
                    _CertFile           = InputString("Certificate file:", "test.pfx", false);
                    _CertPass           = InputString("Certificate password:"******"password", false);
                    _AcceptInvalidCerts = InputBoolean("Accept invalid certs:", true);
                    _MutualAuth         = InputBoolean("Mutually authenticate:", false);

                    _Server = new WatsonTcpServer(_ServerIp, _ServerPort, _CertFile, _CertPass);
                    _Server.Settings.AcceptInvalidCertificates = _AcceptInvalidCerts;
                    _Server.Settings.MutuallyAuthenticate      = _MutualAuth;
                }

                _Server.Events.ClientConnected    += ClientConnected;
                _Server.Events.ClientDisconnected += ClientDisconnected;
                _Server.Events.MessageReceived    += MessageReceived;
                _Server.Events.ServerStarted      += ServerStarted;
                _Server.Events.ServerStopped      += ServerStopped;

                _Server.Callbacks.SyncRequestReceived = SyncRequestReceived;

                // _Server.Settings.IdleClientTimeoutSeconds = 10;
                // _Server.Settings.PresharedKey = "0000000000000000";
                _Server.Settings.Logger        = Logger;
                _Server.Settings.DebugMessages = _DebugMessages;

                _Server.Keepalive.EnableTcpKeepAlives    = true;
                _Server.Keepalive.TcpKeepAliveInterval   = 1;
                _Server.Keepalive.TcpKeepAliveTime       = 1;
                _Server.Keepalive.TcpKeepAliveRetryCount = 3;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return;
            }

            _Server.Start();

            bool          runForever = true;
            List <string> clients;
            string        ipPort;
            Dictionary <object, object> metadata;
            bool success = false;

            while (runForever)
            {
                string userInput = InputString("Command [? for help]:", null, false);

                switch (userInput)
                {
                case "?":
                    bool listening = (_Server != null ? _Server.IsListening : false);
                    Console.WriteLine("Available commands:");
                    Console.WriteLine("  ?                   help (this menu)");
                    Console.WriteLine("  q                   quit");
                    Console.WriteLine("  cls                 clear screen");
                    Console.WriteLine("  start               start listening for connections (listening: " + listening.ToString() + ")");
                    Console.WriteLine("  stop                stop listening for connections  (listening: " + listening.ToString() + ")");
                    Console.WriteLine("  list                list clients");
                    Console.WriteLine("  dispose             dispose of the server");
                    Console.WriteLine("  send                send message to client");
                    Console.WriteLine("  send md             send message with metadata to client");
                    Console.WriteLine("  sendasync           send message to a client asynchronously");
                    Console.WriteLine("  sendasync md        send message with metadata to a client asynchronously");
                    Console.WriteLine("  sendandwait         send message and wait for a response");
                    Console.WriteLine("  sendempty           send empty message with metadata");
                    Console.WriteLine("  sendandwait empty   send empty message with metadata and wait for a response");
                    Console.WriteLine("  remove              disconnect client");
                    Console.WriteLine("  remove all          disconnect all clients");
                    Console.WriteLine("  psk                 set preshared key");
                    Console.WriteLine("  stats               display server statistics");
                    Console.WriteLine("  stats reset         reset statistics other than start time and uptime");
                    Console.WriteLine("  debug               enable/disable debug");
                    break;

                case "q":
                    runForever = false;
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "start":
                    _Server.Start();
                    break;

                case "stop":
                    _Server.Stop();
                    break;

                case "list":
                    clients = _Server.ListClients().ToList();
                    if (clients != null && clients.Count > 0)
                    {
                        Console.WriteLine("Clients");
                        foreach (string curr in clients)
                        {
                            Console.WriteLine("  " + curr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "dispose":
                    _Server.Dispose();
                    break;

                case "send":
                    ipPort    = InputString("IP:port:", _LastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    if (!_Server.Send(ipPort, userInput))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "send10":
                    ipPort    = InputString("IP:port:", _LastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    for (int i = 0; i < 10; i++)
                    {
                        Console.WriteLine("Sending " + i);
                        if (!_Server.Send(ipPort, userInput + "[" + i.ToString() + "]"))
                        {
                            Console.WriteLine("Failed");
                        }
                    }
                    break;

                case "send md":
                    ipPort    = InputString("IP:port:", _LastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    metadata  = InputDictionary();
                    if (!_Server.Send(ipPort, userInput, metadata))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "send md large":
                    ipPort   = InputString("IP:port:", _LastIpPort, false);
                    metadata = new Dictionary <object, object>();
                    for (int i = 0; i < 100000; i++)
                    {
                        metadata.Add(i, i);
                    }
                    if (!_Server.Send(ipPort, "Hello!", metadata))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendasync":
                    ipPort    = InputString("IP:port:", _LastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    success   = _Server.SendAsync(ipPort, Encoding.UTF8.GetBytes(userInput)).Result;
                    if (!success)
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendasync md":
                    ipPort    = InputString("IP:port:", _LastIpPort, false);
                    userInput = InputString("Data:", null, false);
                    metadata  = InputDictionary();
                    success   = _Server.SendAsync(ipPort, Encoding.UTF8.GetBytes(userInput), metadata).Result;
                    if (!success)
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendandwait":
                    SendAndWait();
                    break;

                case "sendempty":
                    ipPort   = InputString("IP:port:", _LastIpPort, false);
                    metadata = InputDictionary();
                    if (!_Server.Send(ipPort, "", metadata))
                    {
                        Console.WriteLine("Failed");
                    }
                    break;

                case "sendandwait empty":
                    SendAndWaitEmpty();
                    break;

                case "remove":
                    ipPort = InputString("IP:port:", _LastIpPort, false);
                    _Server.DisconnectClient(ipPort);
                    break;

                case "remove all":
                    _Server.DisconnectClients();
                    break;

                case "psk":
                    _Server.Settings.PresharedKey = InputString("Preshared key:", "1234567812345678", false);
                    break;

                case "stats":
                    Console.WriteLine(_Server.Statistics.ToString());
                    break;

                case "stats reset":
                    _Server.Statistics.Reset();
                    break;

                case "debug":
                    _Server.Settings.DebugMessages = !_Server.Settings.DebugMessages;
                    Console.WriteLine("Debug set to: " + _Server.Settings.DebugMessages);
                    break;

                default:
                    break;
                }
            }
        }
Ejemplo n.º 13
0
        static void Main(string[] args)
        {
            Console.Write("Server IP    : ");
            serverIp = Console.ReadLine();

            Console.Write("Server Port  : ");
            serverPort = Convert.ToInt32(Console.ReadLine());

            using (WatsonTcpServer server = new WatsonTcpServer(serverIp, serverPort, ClientConnected, ClientDisconnected, MessageReceived, true))
            {
                bool runForever = true;
                while (runForever)
                {
                    Console.Write("Command [? for help]: ");
                    string userInput = Console.ReadLine();

                    List <string> clients;
                    string        ipPort;

                    if (String.IsNullOrEmpty(userInput))
                    {
                        continue;
                    }

                    switch (userInput)
                    {
                    case "?":
                        Console.WriteLine("Available commands:");
                        Console.WriteLine("  ?        help (this menu)");
                        Console.WriteLine("  q        quit");
                        Console.WriteLine("  cls      clear screen");
                        Console.WriteLine("  list     list clients");
                        Console.WriteLine("  send     send message to client");
                        Console.WriteLine("  remove   disconnect client");
                        break;

                    case "q":
                        runForever = false;
                        break;

                    case "cls":
                        Console.Clear();
                        break;

                    case "list":
                        clients = server.ListClients();
                        if (clients != null && clients.Count > 0)
                        {
                            Console.WriteLine("Clients");
                            foreach (string curr in clients)
                            {
                                Console.WriteLine("  " + curr);
                            }
                        }
                        else
                        {
                            Console.WriteLine("None");
                        }
                        break;

                    case "send":
                        Console.Write("IP:Port: ");
                        ipPort = Console.ReadLine();
                        Console.Write("Data: ");
                        userInput = Console.ReadLine();
                        if (String.IsNullOrEmpty(userInput))
                        {
                            break;
                        }

                        server.Send(ipPort, Encoding.UTF8.GetBytes(userInput));
                        break;

                    case "remove":
                        Console.Write("IP:Port: ");
                        ipPort = Console.ReadLine();
                        server.DisconnectClient(ipPort);
                        break;

                    default:
                        break;
                    }
                }
            }
        }
Ejemplo n.º 14
0
        static void Main(string[] args)
        {
            if (!Directory.Exists(_appDataFolder))
            {
                Directory.CreateDirectory(_appDataFolder);
            }

            _serverIp   = Common.InputString("Server IP:", "127.0.0.1", false);
            _serverPort = Common.InputInteger("Server port:", 9000, true, false);
            _server     = new WatsonTcpServer(_serverIp, _serverPort);

            _server.ClientConnected    = ClientConnected;
            _server.ClientDisconnected = ClientDisconnected;
            _server.MessageReceived    = MessageReceived;

            _server.Start();

            LogMessage("Server start");

            bool runForever = true;

            while (runForever)
            {
                Console.Write("Command [? for help]: ");
                string userInput = Console.ReadLine();

                List <string> clients;
                string        ipPort;

                if (String.IsNullOrEmpty(userInput))
                {
                    continue;
                }

                switch (userInput)
                {
                case "?":
                    Console.WriteLine("Available commands:");
                    Console.WriteLine("  ?        help (this menu)");
                    Console.WriteLine("  q        quit");
                    Console.WriteLine("  cls      clear screen");
                    Console.WriteLine("  list     list clients");
                    Console.WriteLine("  send     send message to client");
                    Console.WriteLine("  remove   disconnect client");
                    break;

                case "q":
                    runForever = false;
                    break;

                case "cls":
                    Console.Clear();
                    break;

                case "list":
                    clients = _server.ListClients();
                    if (clients != null && clients.Count > 0)
                    {
                        Console.WriteLine("Clients");
                        foreach (string curr in clients)
                        {
                            Console.WriteLine("  " + curr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("None");
                    }
                    break;

                case "remove":
                    Console.Write("IP:Port: ");
                    ipPort = Console.ReadLine();
                    _server.DisconnectClient(ipPort);
                    break;

                default:
                    break;
                }
            }
        }