Пример #1
0
        /// <summary>
        /// 开始接受连入
        /// </summary>
        private void BeginAccept()
        {
            while (!this._shutingdown)
            {
                SocketSession _socketSession = this.Sessions.Pop();
                if (_socketSession == null)
                {
                    Thread.Sleep(100); continue;
                }

                #region Session池可用
                _socketSession.Handshaked = false;
                _socketSession.Status     = SocketSessionStatus.Accepting;

                try
                {
                    try
                    {
                        if (!this.socket.AcceptAsync(_socketSession.SocketAsyncEventArgs))
                        {
                            this.EndAccept(_socketSession.SocketAsyncEventArgs);
                        }
                    }
                    catch (InvalidOperationException)
                    {
                        int _index = _socketSession.Index;
                        _socketSession.Dispose();

                        _socketSession = new SocketSession(this, _index);
                        _socketSession.SocketAsyncEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(Async_Completed);
                        this.Sessions[_index] = _socketSession;

                        if (!this.socket.AcceptAsync(_socketSession.SocketAsyncEventArgs))
                        {
                            this.EndAccept(_socketSession.SocketAsyncEventArgs);
                        }
                    }
                }
                catch (ObjectDisposedException _ex)
                {
                    if (_ex.ObjectName != "Socket")
                    {
                        this.OnException(_ex);
                    }
                }
                catch (Exception _ex)
                {
                    this.OnException(_ex);
                }
                #endregion

                return;
            }
        }
Пример #2
0
        public object DePackage(byte[] _byteArray, out uint _packageSize, bool _completely = false, SocketSession _session = null)
        {
            if (_session == null)
            {
                _packageSize = uint.Parse(_byteArray.Length.ToString()); return(null);
            }

            string _data = "";

            if (_session["__I__N__I__T__"] == null)
            {
                #region 首次握手
                _data = Encoding.UTF8.GetString(_byteArray);
                int _index = _data.IndexOf("\r\n\r\n");
                if (_index == -1)
                {
                    _packageSize = 0; return(null);
                }
                if (!_completely && _index > -1)
                {
                    _packageSize = 0; return(new WstpPackage(WstpPackageType.Init));
                }

                _packageSize = uint.Parse((_index + 4).ToString());
                string[] _lines = _data.Split("\r\n");
                Dictionary <string, string> _header = new Dictionary <string, string>();
                foreach (string _line in _lines)
                {
                    string _key   = "";
                    string _value = "";
                    if (_line.StartsWith("GET"))
                    {
                        _key   = "Path";
                        _value = _line.Substring(4, _line.IndexOf(" ", 4) - 4);
                    }
                    else
                    {
                        int _splitIndex = _line.IndexOf(":");
                        if (_splitIndex == -1)
                        {
                            continue;
                        }
                        _key   = _line.Substring(0, _splitIndex).Trim();
                        _value = _line.Substring(_splitIndex + 1).Trim();
                    }
                    if (_header.ContainsKey(_key))
                    {
                        _header[_key] = _header[_key] + "\n" + _value;
                    }
                    else
                    {
                        _header.Add(_key, _value);
                    }
                }
                if (!_header.ContainsKey("Upgrade") || _header["Upgrade"] != "websocket")
                {
                    _packageSize = 0; _session.Disconnect(); return(null);
                }

                if (_header.ContainsKey("Sec-WebSocket-Key"))
                {
                    string _wsKey = _header["Sec-WebSocket-Key"];
                    if (_wsKey == "")
                    {
                        _packageSize = 0; _session.Dispose(); return(null);
                    }
                    string _wsSecret = SHA.EncodeSHA1ToBase64(_wsKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");

                    string _returnData = $"HTTP/1.1 101 Switching Protocols\r\n";
                    _returnData += $"Connection:Upgrade\r\n";
                    _returnData += $"Server:{this.name}\r\n";
                    _returnData += $"Upgrade:WebSocket\r\n";
                    _returnData += $"Date:{DateTime.UtcNow.ToString("r")}\r\n";
                    _returnData += $"Sec-WebSocket-Accept:{_wsSecret}\r\n\r\n";

                    _session.SendBytes(Encoding.UTF8.GetBytes(_returnData));
                    foreach (KeyValuePair <string, string> _item in _header)
                    {
                        _session[$"{_item.Key}"] = _item.Value;
                    }
                    _session["Sec-WebSocket-Secret"] = _wsSecret;
                    _session["__I__N__I__T__"]       = true;
                    return(new WstpPackage(WstpPackageType.Init));
                }
                else if (_header.ContainsKey("Sec-WebSocket-Key1"))
                {
                    string _origin = _header["Origin"];
                    if (_origin.Length == 0)
                    {
                        _origin = "null";
                    }

                    string _returnData = $"HTTP/1.1 101 Web Socket Protocol Handshake\r\n";
                    _returnData += $"Upgrade:WebSocket\r\n";
                    _returnData += $"Connection:Upgrade\r\n";
                    _returnData += $"Server:{this.name}\r\n";
                    _returnData += $"Date:{DateTime.UtcNow.ToString("r")}\r\n";
                    _returnData += $"Sec-WebSocket-Origin:{_origin}\r\n\r\n";
                    _returnData += $"Sec-WebSocket-Location:ws://{_header["Host"]}{_header["Path"]}\r\n\r\n";

                    uint _key1 = GetWebSocketKeyValue(_header["Sec-WebSocket-Key1"]);
                    uint _key2 = GetWebSocketKeyValue(_header["Sec-WebSocket-Key2"]);

                    string _keyExt = _lines[_lines.Length - 1];
                    if (_keyExt.Length < 8)
                    {
                        _packageSize = 0; _session.Disconnect(); return(null);
                    }

                    byte[] _buffer      = new byte[16];
                    byte[] _key1Bytes   = BitConverter.GetBytes(_key1);
                    byte[] _key2Bytes   = BitConverter.GetBytes(_key2);
                    byte[] _keyExtBytes = Encoding.UTF8.GetBytes(_keyExt);
                    Array.Copy(_key1Bytes, 0, _buffer, 0, _key1Bytes.Length);
                    Array.Copy(_key2Bytes, 0, _buffer, _key2Bytes.Length, _key2Bytes.Length);
                    Array.Copy(_keyExtBytes, 0, _buffer, _key1Bytes.Length + _key2Bytes.Length, _keyExtBytes.Length);
                    _returnData += Encrypt.MD5.Encode(_buffer);

                    _session.SendBytes(Encoding.UTF8.GetBytes(_returnData));
                    foreach (KeyValuePair <string, string> _item in _header)
                    {
                        _session[$"{_item.Key}"] = _item.Value;
                    }
                    _session["__I__N__I__T__"] = true;
                    return(new WstpPackage(WstpPackageType.Init));
                }
                #endregion
            }

            int _start = 0;
            _packageSize = 0;
            WstpPackage _package = null;
            if (_byteArray.Length == 0)
            {
                return(_package);
            }

            while (true)
            {
                int _fin = (_byteArray[_start] & 0x80) == 0x80 ? 1 : 0;
                if (_fin == 0)
                {
                    break;
                }

                int _op  = _byteArray[_start] & 0x0F;
                int _len = _byteArray[_start + 1] & 0x7F;

                int _lenByByte  = 1;
                int _maskByByte = 4;
                if (_len == 126)
                {
                    _lenByByte = 3;
                }
                else if (_len == 127)
                {
                    _lenByByte = 9;
                }
                if ((_byteArray.Length - _start) < (1 + _lenByByte + _maskByByte))
                {
                    break;
                }
                if (_len == 126)
                {
                    byte[] _buffer = new byte[2];
                    Array.Copy(_byteArray, _start + 2, _buffer, 0, _buffer.Length);
                    _len = System.Net.IPAddress.NetworkToHostOrder(BitConverter.ToInt16(_buffer, 0));
                }
                else if (_len == 127)
                {
                    byte[] _buffer = new byte[8];
                    Array.Copy(_byteArray, _start + 2, _buffer, 0, _buffer.Length);
                    _len = (int)System.Net.IPAddress.NetworkToHostOrder((long)BitConverter.ToInt64(_buffer, 0));
                }
                if ((_byteArray.Length - _start) < (1 + _lenByByte + _maskByByte + _len))
                {
                    break;
                }

                if (_op == 8)
                {
                    _session.SendPackage(new WstpPackage(WstpPackageType.Close));
                    _session.Disconnect();
                    _package = new WstpPackage(WstpPackageType.Close);
                }
                else if (_op == 9)
                {
                    _session.SendPackage(new WstpPackage(WstpPackageType.Pong));
                    _package = new WstpPackage(WstpPackageType.Ping);
                }

                byte[] _mask = new byte[_maskByByte];
                Array.Copy(_byteArray, _start + 1 + _lenByByte, _mask, 0, _maskByByte);
                byte[] _payload = new byte[_len];
                Array.Copy(_byteArray, _start + 1 + _lenByByte + _maskByByte, _payload, 0, _len);

                if (_package == null && _op == 1)
                {
                    _package = new WstpPackage(WstpPackageType.Text);
                }
                if (_package == null && _op == 2)
                {
                    _package = new WstpPackage(WstpPackageType.Binary);
                }
                if (_package == null)
                {
                    return(null);
                }

                int _binaryLen = _package.Binary.Length;
                Array.Resize(ref _package.Binary, _package.Binary.Length + _payload.Length);
                for (int i = 0; i < _payload.Length; i++)
                {
                    _package.Binary[_binaryLen + i] = (byte)(_payload[i] ^ _mask[i % 4]);
                }
                _start = _start + 1 + _lenByByte + _maskByByte + _len;
                if (_fin == 1)
                {
                    break;
                }
            }

            _packageSize = uint.Parse(_start.ToString());
            return(_package);
        }