public bool ReceiveFirstPackage(JObject _json, SocketSession _session) { if (_session["TxKey"] + "" != "" && _session["Checksum"] + "" == "DONE") { return(false); } if (_session["RxKey"] + "" == "") { DateTime _time = DateTimePlus.JSTime2DateTime(long.Parse(_json["time"].Value <string>())); if (Math.Abs((_time - DateTime.UtcNow).TotalSeconds) > 300) { _session.Disconnect(); return(true); } _session["TxKey"] = _json["key"].Value <string>(); Random _random = new Random(RandomPlus.RandomSeed); string _rxKey = _random.Next(10000000, 100000000).ToString(); _session["RxKey"] = _rxKey; string _checksum = _random.Next(10000000, 100000000).ToString(); _session["Checksum"] = _checksum; JObject _result = new JObject(); _result["check"] = this.rsa.Sign(_json["num"].Value <string>()); _result["num"] = _checksum; _result["key"] = _rxKey; _session.SendPackage(_result); } else if (_session["Checksum"] + "" != "DONE") { if (!this.rsa.Verify(_session["Checksum"] + "", _json["check"].Value <string>())) { this.socketTxKey = ""; return(true); } _session["Checksum"] = "DONE"; _session.Handshaked = true; } return(true); }
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); }
internal void EndReceive(SocketAsyncEventArgs _socketAsyncEventArgs) { try { bool _disconnect = false; if (_socketAsyncEventArgs == null || _socketAsyncEventArgs.SocketError != SocketError.Success || _socketAsyncEventArgs.BytesTransferred <= 0 || _shutingdown) { _disconnect = true; } SocketSession _socketSession = (SocketSession)_socketAsyncEventArgs.UserToken; if (!_disconnect) { try { #region 读取数据 _socketSession.ReceivedStream.Write(_socketAsyncEventArgs.Buffer, _socketAsyncEventArgs.Offset, _socketAsyncEventArgs.BytesTransferred); byte[] _receivedBytes = _socketSession.ReceivedStream.ToArray(); if (_receivedBytes == null) { _disconnect = true; } try { this.OnReceive(_socketSession, _receivedBytes); } catch (Exception _ex) { this.OnException(_ex); _disconnect = true; } _socketSession.LastOperationTime = DateTime.UtcNow; #endregion #region 匹配协议 if (_socketSession.Protocol == null) { for (int i = 0; i < this.Protocols.Length; i++) { if (this.Protocols[i].Check(_receivedBytes, false, _socketSession)) { _socketSession.Protocol = this.Protocols[i]; break; } } } #endregion #region 处理数据包 if (_socketSession.Protocol != null) { while (_receivedBytes != null && _socketSession.Protocol.Check(_receivedBytes, false, _socketSession)) { uint _packageSize = 0; object _package = _socketSession.Protocol.DePackage(_receivedBytes, out _packageSize, false, _socketSession); if (_package == null) { throw new Exception("Package is NULL."); } #region OnReceivingPackage 事件处理 try { this.OnReceivingPackage(_socketSession, _package); } catch (Exception _ex) { this.OnException(_ex); } #endregion if (!_socketSession.Protocol.Check(_receivedBytes, true, _socketSession)) { break; } _packageSize = 0; _package = _socketSession.Protocol.DePackage(_receivedBytes, out _packageSize, true, _socketSession); if (_package == null) { throw new Exception("Package is NULL."); } #region 刷新已接受数据流 byte[] _temp = new byte[_socketSession.ReceivedStream.Length - _packageSize]; if (_temp.Length > 0) { _socketSession.ReceivedStream.Position = _packageSize; _socketSession.ReceivedStream.Read(_temp, 0, _temp.Length); _socketSession.ReceivedStream.Position = 0; _socketSession.ReceivedStream.Write(_temp, 0, _temp.Length); _socketSession.ReceivedStream.SetLength(_temp.Length); _socketSession.ReceivedStream.Capacity = _temp.Length; _receivedBytes = _socketSession.ReceivedStream.ToArray(); } else { _socketSession.ReceivedStream.SetLength(0); _socketSession.ReceivedStream.Capacity = 0; _receivedBytes = new byte[0]; } #endregion #region OnReceivedPackage 事件处理 try { if (_socketSession.Protocol.IsKeepAlivePackage(_package, _socketSession)) { _socketSession.SendPackage(_socketSession.Protocol.KeepAlivePackage); } else { this.OnReceivedPackage(_socketSession, _package); } } catch (Exception _ex) { this.OnException(_ex); } #endregion } } #endregion this.BeginReceive(_socketAsyncEventArgs); return; } catch (Exception _ex) { Console.WriteLine(_ex); _disconnect = true; } } if (_disconnect) { this.BeginDisconnect(_socketAsyncEventArgs.AcceptSocket); this.OnSessionEnd(_socketSession); this.bufferManager.FreeBuffer(_socketAsyncEventArgs); _socketSession.Clear(); } } catch (Exception _ex) { this.OnException(_ex); } }