Beispiel #1
0
 private async Task ClientDisconnected_Internal(WsConnectedClient player)
 {
     lock (clients)
     {
         clients.Remove(player);
     }
     if (ClientDisconnected != null)
     {
         await ClientDisconnected.Invoke(player);
     }
 }
Beispiel #2
0
 private async Task Send(WsConnectedClient ConnectedClient, ArraySegment <byte> data)
 {
     try
     {
         await ConnectedClient.workSocket.SendAsync(data, SocketFlags.None);
     }
     catch (Exception e)
     {
         Logger.Debug(e.ToString());
         await ClientDisconnected_Internal(ConnectedClient);
     }
 }
Beispiel #3
0
 private async Task Send(WsConnectedClient ConnectedClient, string json)
 {
     try
     {
         await ConnectedClient.workSocket.SendAsync(GetFrameFromString(json), SocketFlags.None);
     }
     catch (Exception e)
     {
         Logger.Debug(e.ToString());
         await ClientDisconnected_Internal(ConnectedClient);
     }
 }
Beispiel #4
0
        public async Task Start()
        {
            IPAddress  ipv4Address       = IPAddress.Any;
            IPAddress  ipv6Address       = IPAddress.IPv6Any;
            IPEndPoint localIPV4EndPoint = new IPEndPoint(ipv4Address, port);
            IPEndPoint localIPV6EndPoint = new IPEndPoint(ipv6Address, port);

            ipv4Server = new Socket(ipv4Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            ipv6Server = new Socket(ipv6Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            ipv4Server.Bind(localIPV4EndPoint);
            ipv6Server.Bind(localIPV6EndPoint);

            ipv4Server.Listen(100);
            ipv6Server.Listen(100);

            Func <Socket, Task> processClient = async(clientSocket) =>
            {
                var ConnectedClient = new WsConnectedClient
                {
                    workSocket = clientSocket,
                    id         = Guid.NewGuid()
                };

                byte[] buffer         = new byte[1024];
                string headerResponse = string.Empty;
                if ((ipv4Server != null && ipv4Server.IsBound) || (ipv6Server != null && ipv6Server.IsBound))
                {
                    var i = ConnectedClient.workSocket.Receive(buffer);
                    headerResponse = (Encoding.UTF8.GetString(buffer)).Substring(0, i);
                }

                if (clientSocket != null)
                {
                    /* Handshaking and managing ClientSocket */
                    if (headerResponse != "")
                    {
                        var key = headerResponse.Replace("ey:", "`")
                                  .Split('`')[1]
                                  .Replace("\r", "").Split('\n')[0]
                                  .Trim();

                        byte[] ComputeHash(string str)
                        {
                            return(sha1.ComputeHash(Encoding.ASCII.GetBytes(str)));
                        }

                        string AcceptKey(ref string key)
                        {
                            string longKey = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

                            byte[] hashBytes = ComputeHash(longKey);
                            return(Convert.ToBase64String(hashBytes));
                        }

                        var acceptKey = AcceptKey(ref key);

                        var newLine = "\r\n";

                        var response = "HTTP/1.1 101 Switching Protocols" + newLine
                                       + "Upgrade: websocket" + newLine
                                       + "Connection: Upgrade" + newLine
                                       + "Sec-WebSocket-Accept: " + acceptKey +
                                       newLine +
                                       newLine;
                        clientSocket.Send(Encoding.UTF8.GetBytes(response));
                    }
                }

                lock (clients)
                {
                    clients.Add(ConnectedClient);
                }

                if (ClientConnected != null)
                {
                    await ClientConnected.Invoke(ConnectedClient);
                }

                ReceiveLoop(ConnectedClient);
            };

            Func <Task> ipv4Accept = async() =>
            {
                while (Enabled)
                {
                    // Start an asynchronous socket to listen for connections.
                    Logger.Debug($"Waiting for an IPV4 connection on {ipv4Address}:{port} ...");
                    var clientSocket = await ipv4Server.AcceptAsync();

                    Logger.Debug($"Accepted connection on {ipv4Address}:{port} ...");

                    await processClient(clientSocket);
                }
            };

            Func <Task> ipv6Accept = async() =>
            {
                while (Enabled)
                {
                    // Start an asynchronous socket to listen for connections.
                    Logger.Debug($"Waiting for an IPV6 connection on {ipv6Address}:{port} ...");
                    var clientSocket = await ipv6Server.AcceptAsync();

                    Logger.Debug($"Accpeted connection on {ipv6Address}:{port} ...");

                    await processClient(clientSocket);
                }
            };

            await ipv4Accept();

            //Task.Run(ipv4Accept);
            //ipv6Accept();
        }
Beispiel #5
0
        private async void ReceiveLoop(WsConnectedClient player)
        {
            try
            {
                // Begin receiving the data from the remote device.
                while (player?.workSocket?.Connected ?? false)
                {
                    var bytesRead = await player.workSocket.ReceiveAsync(player.buffer, SocketFlags.None);

                    if (bytesRead > 0)
                    {
                        var currentBytes = new byte[bytesRead];
                        Buffer.BlockCopy(player.buffer.ToArray(), 0, currentBytes, 0, bytesRead);

                        Packet readPacket = null;
                        bool   fin        = (currentBytes[0] & 0b10000000) != 0,
                               mask       = (currentBytes[1] & 0b10000000) != 0;

                        int opcode = currentBytes[0] & 0b00001111,
                            msglen = currentBytes[1] - 128,
                            offset = 2;

                        if (opcode == 0x8)
                        {
                            await Send(player, GetFrameFromString("", EOpcodeType.ClosedConnection));

                            throw new Exception("Stream ended");
                        }

                        if (msglen == 126)
                        {
                            msglen = BitConverter.ToUInt16(new byte[] { currentBytes[3], currentBytes[2] }, 0);
                            offset = 4;
                        }

                        if (msglen == 0)
                        {
                            Logger.Debug("msglen == 0");
                        }
                        else if (mask)
                        {
                            byte[] decoded = new byte[msglen];
                            byte[] masks   = new byte[4] {
                                currentBytes[offset], currentBytes[offset + 1], currentBytes[offset + 2], currentBytes[offset + 3]
                            };
                            offset += 4;

                            for (int i = 0; i < msglen; ++i)
                            {
                                decoded[i] = (byte)(currentBytes[offset + i] ^ masks[i % 4]);
                            }

                            player.accumulatedBytes.AddRange(decoded);
                            var accumulatedBytes = player.accumulatedBytes.ToArray();
                            if (accumulatedBytes.Length == msglen)
                            {
                                string text = Encoding.UTF8.GetString(decoded);
                                Logger.Warning(text);
                                try
                                {
                                    readPacket = Packet.FromJSON(text);
                                    PacketReceived?.Invoke(player, readPacket);
                                }
                                catch (Exception e)
                                {
                                    Logger.Error(e.Message);
                                    Logger.Error(e.StackTrace);
                                }
                                player.accumulatedBytes.Clear();
                                accumulatedBytes = player.accumulatedBytes.ToArray();
                            }
                        }
                    }
                    else if (bytesRead == 0)
                    {
                        await Send(player, GetFrameFromString("", EOpcodeType.ClosedConnection));

                        throw new Exception("Stream ended");
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                await ClientDisconnected_Internal(player);
            }
            catch (Exception e)
            {
                Logger.Debug(e.ToString());
                await ClientDisconnected_Internal(player);
            }
        }