BF2Statistics.Gamespy.Net.GamespyTcpStream.ProcessSend C# (CSharp) Method

ProcessSend() private method

Sends a message Asynchronously to the client connection
private ProcessSend ( ) : void
return void
        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;
                Close();
            }

            // 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)
                {
                    Close();
                    return;
                }
                // Append to the offset
                SendBytesOffset += WriteEventArgs.BytesTransferred;
                WaitingOnAsync = false;
                ProcessSend();
            }
        }