예제 #1
0
        public InitialRequest(
            Version sdkVersion,
            Version clientVersion,
            byte[] customData)
        {
            var buffer = ByteBufferFactory.NewBuffer();

            buffer.WriteByte(DataSerializer.Version);
            buffer.WriteByte((byte)MessageType.InitialRequest);

            buffer.WriteShort((short)sdkVersion.Major);
            buffer.WriteShort((short)sdkVersion.Minor);
            buffer.WriteShort((short)sdkVersion.Build);

            buffer.WriteShort((short)clientVersion.Major);
            buffer.WriteShort((short)clientVersion.Minor);
            buffer.WriteShort((short)clientVersion.Build);

            int customDataLength = customData == null ? 0 : customData.Length;

            buffer.WriteShort((short)customDataLength);

            if (customDataLength > 200)
            {
                _bytes = null;
                return;
            }

            if (customData != null)
            {
                buffer.WriteBytes(customData, 0, customDataLength);
            }

            _bytes = buffer.ToArray();
        }
예제 #2
0
        private void ReceiveAsync(IAsyncResult res)
        {
            if (State == SocketState.Disconnected)
            {
                return;
            }

            byte[] buf = null;

            IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 8000);

            if (_client == null)
            {
                return;
            }

            buf = _client.EndReceive(res, ref remoteIpEndPoint);

            if (buf == null || buf.Length < UdpPeer.MtuHeaderLength || buf.Length > _mtuSize)
            {
                throw new Exception(string.Format("The length of received data[{0}] is out of range between {1} and {2}", buf.Length, UdpPeer.MtuHeaderLength, _mtuSize));
            }

            var buffer = ByteBufferFactory.NewBuffer(buf);

            _broker.OnReceive(buffer);

            if (_client == null)
            {
                return;
            }

            _client.BeginReceive(ReceiveAsync, null);
        }
예제 #3
0
        public void Disconnect(DisconnectReason reason, bool sendingRequired)
        {
            if (_udpSocket.State == SocketState.Disconnecting || _udpSocket.State == SocketState.Disconnected)
            {
                return;
            }

            Log(LogLevel.Debug, "Disconnect Reson[{0}]", reason.ToString());

            if (sendingRequired)
            {
                _udpSocket.Disconnecting();

                var buffer = ByteBufferFactory.NewBuffer();
                buffer.WriteInt((int)reason);

                EnqueueOutgoingCommand(new OutgoingCommand(CommandType.Disconnect, (byte)(ChannelCount - 1), buffer.ToArray()));
                FlushSendQueues();
            }

            _udpSocket.Dispose();

            if (_listener != null)
            {
                switch (reason)
                {
                case DisconnectReason.Timeout:
                case DisconnectReason.ServerUserLimit:
                case DisconnectReason.ServerLogic:
                case DisconnectReason.QueueFull:
                case DisconnectReason.InvalidConnection:
                case DisconnectReason.InvalidDataFormat:
                case DisconnectReason.ClientDisconnect:
                case DisconnectReason.ApplicationStop:
                    _listener.OnStatusChanged(StatusCode.Disconnected, string.Format("Disconnected by {0}", reason));
                    break;

                case DisconnectReason.ConnectionFailed:
                    _listener.OnStatusChanged(StatusCode.FailedToConnect, string.Format("Failed to connect to {0}:{1}", RemoteEndPoint.Address, RemoteEndPoint.Port));
                    break;

                default:
                    _listener.OnStatusChanged(StatusCode.Disconnected, "Disconnected by unknown error");
                    break;
                }

                _listener.OnClose();
            }

            if (_sendAckBackgroundThread != null)
            {
                _sendAckBackgroundThread.Abort();
                _sendAckBackgroundThread = null;
            }

            LogMessageRecevied = null;

            _isAckThreadRunning = false;
        }
        internal OutgoingCommand(CommandType commandType, byte channel, bool encryted, byte[] payload)
        {
            ReliableSequenceNumber   = UdpChannel.InitialSequenceNumber;
            UnreliableSequenceNumber = UdpChannel.InitialSequenceNumber;

            CommandType = commandType;

            Channel = channel;

            Payload = payload != null && payload.Length > 0 ? ByteBufferFactory.NewBuffer(payload) : ByteBufferFactory.NewBuffer();

            switch (CommandType)
            {
            case CommandType.Acknowledge:
                _headerLength = (int)Lengths.AcknowledgeHeader;
                Flags         = CommandFlags.Unreliable;
                break;

            case CommandType.Disconnect:
                _headerLength = (int)Lengths.DisconnectHeader;
                Flags         = CommandFlags.Reliable;
                break;

            case CommandType.Ping:
                _headerLength = (int)Lengths.PingHeader;
                Flags         = CommandFlags.Reliable;
                break;

            case CommandType.Reliable:
                _headerLength = (int)Lengths.ReliableHeader;
                Flags         = encryted ? CommandFlags.Reliable | CommandFlags.Encrypted : CommandFlags.Reliable;
                break;

            case CommandType.Unreliable:
                _headerLength = (int)Lengths.UnreliableHeader;
                Flags         = encryted ? CommandFlags.Unreliable | CommandFlags.Encrypted : CommandFlags.Unreliable;
                break;

            case CommandType.Fragmented:
                _headerLength = (int)Lengths.FragmentHeader;
                Flags         = encryted ? CommandFlags.Reliable | CommandFlags.Encrypted : CommandFlags.Unreliable;
                break;

            case CommandType.SNTP:
                _headerLength = (int)Lengths.SntpHeader;
                Flags         = CommandFlags.Reliable;
                break;

            default:
                throw new ArgumentException(string.Format("Unknown CommandType: {0}", commandType));
            }

            Size = Payload.Count > 0 ? (short)(_headerLength + Payload.Count) : _headerLength;
        }
        public static OutgoingCommand CreateAck(this IncomingCommand command)
        {
            if (false == command.IsReliable)
            {
                return(null);
            }

            var payload = ByteBufferFactory.NewBuffer();

            payload.WriteLong(command.ReliableSequenceNumber);
            payload.WriteLong(command.ServerSentTime);

            return(new OutgoingCommand(CommandType.Acknowledge, command.Channel, payload.ToArray()));
        }
        public EventMessage(short code, DataObject parameters, INetworkPeer peer, bool encrypt)
        {
            var buffer = ByteBufferFactory.NewBuffer();

            // Write a message header (2 bytes).
            buffer.WriteByte(DataSerializer.Version);
            buffer.WriteByte((byte)MessageType.EventMessage);

            buffer.WriteShort(code);
            buffer.WriteDataObject(parameters);

            if (encrypt)
            {
                byte[] bytes = buffer.ToArray();
                _bytes = peer.Cipher.Encrypt(bytes);
            }
            else
            {
                _bytes = buffer.ToArray();
            }
        }
예제 #7
0
        protected void ReceiveFromLoop()
        {
            while (State != SocketState.Disconnected)
            {
                try
                {
                    IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);

                    byte[] buf = _client.Receive(ref remoteEndPoint);

                    if (buf == null || buf.Length < UdpPeer.MtuHeaderLength || buf.Length > _mtuSize)
                    {
                        throw new Exception(string.Format("The length of received data[{0}] is out of range between {1} and {2}", buf.Length, UdpPeer.MtuHeaderLength, _mtuSize));
                    }

                    var buffer = ByteBufferFactory.NewBuffer(buf);

                    _broker.OnReceive(buffer);
                }
                catch (SocketException ex)
                {
                    if (State != SocketState.Disconnecting && State != SocketState.Disconnected)
                    {
                        _broker.Log(LogLevel.Error, ex.ToString());
                    }

                    break;
                }
                catch (Exception ex)
                {
                    if (State != SocketState.Disconnecting && State != SocketState.Disconnected)
                    {
                        _broker.Log(LogLevel.Error, ex.ToString());
                    }

                    break;
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Fetch a payload. If a incoming command is invalid, return null.
        /// </summary>
        /// <returns>A payload in a incoming command.</returns>
        private IByteBuffer FetchPayload(IncomingCommand command)
        {
            if (false == command.IsPayloadAvailable())
            {
                return(null);
            }

            // The length of InitialResponse is 2. Thus payload length should be bigger then 2.
            if (command.GetPayload().Length < 2)
            {
                Log(LogLevel.Error, "Incoming UDP data is too short; Length [{0}] ", command.GetPayload().Length);
                return(null);
            }

            if (command.IsEncrypted)
            {
                try
                {
                    command.SetPayload(_cipher.Decrypt(command.GetPayload()));
                }
                catch (Exception)
                {
                    Log(LogLevel.Error, "Invalid encrypted data");
                    return(null);
                }
            }

            var payload = ByteBufferFactory.NewBuffer(command.GetPayload());

            byte serializerVersion = payload.ReadByte();

            if (serializerVersion != DataSerializer.Version)
            {
                Log(LogLevel.Error, "Unknown serializer Version");
                return(null);
            }

            return(payload);
        }
        private byte[] Serialize()
        {
            if (_buffer != null)
            {
                return(_buffer.ToArray());
            }

            _buffer = ByteBufferFactory.NewBuffer();

            _buffer.WriteByte((byte)CommandType);
            _buffer.WriteByte((byte)Channel);
            _buffer.WriteByte((byte)Flags);

            _buffer.WriteShort(Size);
            _buffer.WriteLong(ReliableSequenceNumber);

            switch (CommandType)
            {
            case CommandType.Unreliable:
                _buffer.WriteLong(UnreliableSequenceNumber);
                break;

            case CommandType.Fragmented:
                _buffer.WriteLong(StartSequenceNumber);
                _buffer.WriteShort(FragmentCount);
                _buffer.WriteShort(FragmentNumber);
                _buffer.WriteLong(TotalLength);
                _buffer.WriteLong(FragmentOffset);
                break;
            }

            if (Payload.Count > 0)
            {
                _buffer.WriteBytes(Payload);
            }

            return(_buffer.ToArray());
        }
        public byte[] CreateConnectCommand(
            short channelCount,
            short mtu,
            int protoVerison,
            int disconnectionTimeout,
            bool isCrcEnabled,
            BigInteger publicKey, long sendingTime)
        {
            var buffer = ByteBufferFactory.NewBuffer();

            buffer.WriteByte((byte)CommandType.Connect);
            buffer.WriteInt(protoVerison);                            //4
            buffer.WriteLong(sendingTime);                            //8
            buffer.WriteShort(channelCount);                          //2
            buffer.WriteShort(mtu);                                   //2
            buffer.WriteInt(disconnectionTimeout);                    //4
            buffer.WriteShort((short)(isCrcEnabled == true ? 1 : 0)); //2
            var publicKeyBytes = publicKey.ToByteArray();

            buffer.WriteByte((byte)publicKeyBytes.Length);
            buffer.WriteBytes(publicKeyBytes); //4
            buffer.WriteLong(0);               //8 crc space

            var bytes = buffer.ToArray();

            if (isCrcEnabled)
            {
                long crc    = bytes.CalculateCrc(bytes.Length);
                int  offset = bytes.Length - (int)Lengths.Crc;
                ByteWrite.SetLong(bytes, ref offset, crc);
            }

            SentCount++;

            return(bytes);
        }