Exemplo n.º 1
0
        /// <summary>
        /// Begins the process of receiving a message from the client.
        /// This method must manually be called to Begin receiving data
        /// </summary>
        public void BeginReceive()
        {
            try
            {
                if (Connection != null)
                {
                    // Reset Buffer offset back to the original allocated offset
                    BufferDataToken token = ReadEventArgs.UserToken as BufferDataToken;
                    ReadEventArgs.SetBuffer(token.BufferOffset, token.BufferBlockSize);

                    // Begin Receiving
                    if (!Connection.ReceiveAsync(ReadEventArgs))
                    {
                        ProcessReceive();
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                if (!DisconnectEventCalled)
                {
                    // Disconnect user
                    DisconnectEventCalled = true;
                    OnDisconnected?.Invoke();
                }
            }
            catch (SocketException e)
            {
                HandleSocketError(e.SocketErrorCode);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Once data has been recived from the client, this method is called
        /// to process the data. Once a message has been completed, the OnDataReceived
        /// event will be called
        /// </summary>
        private void ProcessReceive()
        {
            // If we do not get a success code here, we have a bad socket
            if (ReadEventArgs.SocketError != SocketError.Success)
            {
                HandleSocketError(ReadEventArgs.SocketError);
                return;
            }

            // Force disconnect (Specifically for Gpsp, whom will spam empty connections)
            if (ReadEventArgs.BytesTransferred == 0)
            {
                Dispose(false);
                return;
            }
            else
            {
                // Fetch our message as a string from the Buffer
                BufferDataToken token = ReadEventArgs.UserToken as BufferDataToken;
                RecvMessage.Append(
                    Encoding.UTF8.GetString(
                        ReadEventArgs.Buffer,
                        token.BufferOffset,
                        ReadEventArgs.BytesTransferred
                        )
                    );

                // Process Message
                string received = RecvMessage.ToString();

                if (DataAttempt < 5)
                {
                    if (IsMessageFinished.Invoke(received))
                    {
                        if (LogWriter.Log.DebugSockets)
                        {
                            LogWriter.Log.Write(LogLevel.Debug, "{0} [Recv] TCP data: {1}", SocketManager.ServerName, received);
                        }

                        DataAttempt = 0;

                        // tell our parent that we recieved a message
                        RecvMessage.Clear(); // Clear old junk
                        OnDataReceived.Invoke(received);
                    }

                    DataAttempt++;
                }
                else
                {
                    // Looks like the client is sending a lot of data that is not valid
                    LogWriter.Log.Write(LogLevel.Info, "TCP stream {0} is sending a lot of data! Connection closed.", RemoteEndPoint);
                    Dispose(false);
                }
            }

            // Begin receiving again
            BeginReceive();
        }
Exemplo n.º 3
0
        public GamespyUdpPacket(SocketAsyncEventArgs e)
        {
            // Get our recived bytes
            BytesRecieved = new byte[e.BytesTransferred];
            BufferDataToken token = e.UserToken as BufferDataToken;

            Array.Copy(e.Buffer, token.BufferOffset, BytesRecieved, 0, e.BytesTransferred);

            // Set our internal variables
            AsyncEventArgs = e;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Sets the contents of the SocketAsyncEventArgs buffer,
        /// so a reply can be sent to the remote host connection
        /// </summary>
        /// <param name="contents">The new contents to set the buffer to</param>
        /// <returns>The length of bytes written to the buffer</returns>
        public int SetBufferContents(byte[] contents)
        {
            BufferDataToken token = AsyncEventArgs.UserToken as BufferDataToken;

            if (contents.Length > token.BufferBlockSize)
            {
                throw new ArgumentOutOfRangeException("contents", "Contents are larger then the allocated buffer block size.");
            }

            // Copy contents to buffer, then set buffer position
            Array.Copy(contents, 0, AsyncEventArgs.Buffer, token.BufferOffset, contents.Length);
            AsyncEventArgs.SetBuffer(token.BufferOffset, contents.Length);
            return(contents.Length);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Begins accepting a new Connection asynchronously
        /// </summary>
        protected async void StartAcceptAsync()
        {
            // If we are shutting down, dont receive again
            if (!IsRunning)
            {
                return;
            }

            try
            {
                // Enforce max connections. If we are capped on connections, the new connection will stop here,
                // and retrun once a connection is opened up from the Release() method
                await MaxConnectionsEnforcer..WaitAsync();

                // Fetch ourselves an available AcceptEventArg for the next connection
                SocketAsyncEventArgs AcceptEventArg = SocketReadWritePool.Pop();
                AcceptEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, Port);

                // Reset the Async's Buffer position for the next read
                BufferDataToken token = AcceptEventArg.UserToken as BufferDataToken;
                AcceptEventArg.SetBuffer(token.BufferOffset, token.BufferBlockSize);

                // Begin accpetion connections
                bool willRaiseEvent = Listener.ReceiveFromAsync(AcceptEventArg);

                // If we wont raise event, that means a connection has already been accepted syncronously
                // and the Accept_Completed event will NOT be fired. So we manually call ProcessAccept
                if (!willRaiseEvent)
                {
                    IOComplete(this, AcceptEventArg);
                }
            }
            catch (ObjectDisposedException)
            {
                // Happens when the server is shutdown
            }
            catch (Exception e)
            {
                L.LogError(
                    "ERROR: [GamespyUdpSocket.StartAccept] An Exception was thrown while attempting to recieve"
                    + " a conenction. Generating Exception Log"
                    );
                ExceptionHandler.GenerateExceptionLog(e);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Once data has been recived from the client, this method is called
        /// to process the data. Once a message has been completed, the OnDataReceived
        /// event will be called
        /// </summary>
        private void ProcessReceive()
        {
            // If we do not get a success code here, we have a bad socket
            if (ReadEventArgs.SocketError != SocketError.Success)
            {
                HandleSocketError(ReadEventArgs.SocketError);
                return;
            }

            // Force disconnect (Specifically for Gpsp, whom will spam empty connections)
            if (ReadEventArgs.BytesTransferred == 0)
            {
                Close();
                return;
            }
            else
            {
                // Fetch our message as a string from the Buffer
                BufferDataToken token = ReadEventArgs.UserToken as BufferDataToken;
                RecvMessage.Append(
                    Encoding.UTF8.GetString(
                        ReadEventArgs.Buffer,
                        token.BufferOffset,
                        ReadEventArgs.BytesTransferred
                        )
                    );

                // Process Message
                string received = RecvMessage.ToString();
                if (received.EndsWith("final\\") || received.EndsWith("\x00\x00\x00\x00"))
                {
                    // tell our parent that we recieved a message
                    RecvMessage.Clear(); // Clear old junk
                    DataReceived(received);
                }
            }

            // Begin receiving again
            BeginReceive();
        }
Exemplo n.º 7
0
        /// <summary>
        /// Begins the process of receiving a message from the client.
        /// This method must manually be called to Begin receiving data
        /// </summary>
        public void BeginReceive()
        {
            try
            {
                if (Connection != null)
                {
                    // Reset Buffer offset back to the original allocated offset
                    BufferDataToken token = ReadEventArgs.UserToken as BufferDataToken;
                    ReadEventArgs.SetBuffer(token.BufferOffset, token.BufferBlockSize);

                    // Begin Receiving
                    if (!Connection.ReceiveAsync(ReadEventArgs))
                    {
                        ProcessReceive();
                    }
                }
            }
            catch (ObjectDisposedException e)
            {
                if (!DisconnectEventCalled)
                {
                    // Uh-Oh. idk how we got here
                    L.LogError("WARNING: [GamespyStream.BeginReceive] ObjectDisposedException was thrown: " + e.Message);

                    // Disconnect user
                    DisconnectEventCalled = true;
                    if (OnDisconnect != null)
                    {
                        OnDisconnect();
                    }
                }
            }
            catch (SocketException e)
            {
                HandleSocketError(e.SocketErrorCode);
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Sends a message Asynchronously to the client connection
        /// </summary>
        private void ProcessSend()
        {
            // Return if we are closing the socket
            if (SocketClosed)
            {
                return;
            }

            // Bool holder
            bool willRaiseEvent = true;

            // Prevent an connection loss exception
            try
            {
                // Prevent race conditions by locking here.
                // ** Make sure to set WaitingOnAsync Inside the LOCK! **
                lock (_lockObj)
                {
                    // If we are waiting on the IO operation to complete, we exit here
                    if (WaitingOnAsync)
                    {
                        return;
                    }

                    // Get the number of bytes remaining to be sent
                    int NumBytesToSend = SendMessage.Count - SendBytesOffset;

                    // If there are no more bytes to send, then reset
                    if (NumBytesToSend <= 0)
                    {
                        SendMessage.Clear();
                        SendBytesOffset = 0;
                        WaitingOnAsync  = false;
                        return;
                    }

                    // Make sure we arent sending more data then what we have space for
                    BufferDataToken Token = WriteEventArgs.UserToken as BufferDataToken;
                    if (NumBytesToSend > Token.BufferBlockSize)
                    {
                        NumBytesToSend = Token.BufferBlockSize;
                    }

                    // Copy our message to the Write Buffer
                    SendMessage.CopyTo(SendBytesOffset, WriteEventArgs.Buffer, Token.BufferOffset, NumBytesToSend);
                    WriteEventArgs.SetBuffer(Token.BufferOffset, NumBytesToSend);

                    // We have to exit the lock() before we can handle the event manually
                    WaitingOnAsync = true;
                    willRaiseEvent = Connection.SendAsync(WriteEventArgs);
                }
            }
            catch (ObjectDisposedException)
            {
                WaitingOnAsync = false;
                Dispose(false);
            }

            // If we wont raise the IO event, that means a connection sent the messsage syncronously
            if (!willRaiseEvent)
            {
                // Remember, if we are here, data was sent Synchronously... IOComplete event is not called!
                // First, Check for a closed conenction
                if (WriteEventArgs.BytesTransferred == 0 || WriteEventArgs.SocketError != SocketError.Success)
                {
                    Dispose(false);
                    return;
                }
                // Append to the offset
                SendBytesOffset += WriteEventArgs.BytesTransferred;
                WaitingOnAsync   = false;
                ProcessSend();
            }
        }