public byte[] EnPackage(object _object, SocketSession _session = null) { WstpPackage _package = (WstpPackage)_object; int _payloadByte = 0; if (_package.Binary.Length >= 65536) { _payloadByte = 8; } else if (_package.Binary.Length >= 126) { _payloadByte = 2; } byte[] _data = new byte[2 + _payloadByte + _package.Binary.Length]; _data[0] = 0; _data[1] = 0; _data[0] |= 0x80; switch (_package.Type) { case WstpPackageType.Ping: _data[0] |= 0x09; break; case WstpPackageType.Pong: _data[0] |= 0x0A; break; case WstpPackageType.Text: _data[0] |= 0x01; break; case WstpPackageType.Binary: _data[0] |= 0x02; break; case WstpPackageType.Close: _data[0] |= 0x08; break; } if (_payloadByte == 0) { _data[1] = (byte)_package.Binary.Length; Array.Copy(_package.Binary, 0, _data, 2, _package.Binary.Length); } else if (_payloadByte == 2) { _data[1] = 126; ushort _size = ushort.Parse(_package.Binary.Length.ToString()); short _sizeNet = System.Net.IPAddress.HostToNetworkOrder((short)_size); byte[] _length = BitConverter.GetBytes(_sizeNet); Array.Copy(_length, 0, _data, 2, _length.Length); Array.Copy(_package.Binary, 0, _data, 4, _package.Binary.Length); } else { _data[1] = 127; int _size = _package.Binary.Length; long _sizeNet = System.Net.IPAddress.HostToNetworkOrder((long)_size); byte[] _length = BitConverter.GetBytes(_sizeNet); Array.Copy(_length, 0, _data, 2, _length.Length); Array.Copy(_package.Binary, 0, _data, 10, _package.Binary.Length); } return(_data); }
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); }