예제 #1
0
        public AsyncState(AsyncBase server, Socket socket, AsyncOperation operation, IAsyncInterface interface_, object user)
        {
            m_server    = server;
            m_socket    = socket;
            m_operation = operation;

            m_current_write_buffer = null;

            m_read_buffer = new byte[8192];

            m_read_event_args            = new SocketAsyncEventArgs();
            m_read_event_args.Completed += OnIO;
            m_read_event_args.UserToken  = this;
            m_read_event_args.SetBuffer(m_read_buffer, 0, m_read_buffer.Length);

            m_write_event_args            = new SocketAsyncEventArgs();
            m_write_event_args.Completed += OnIO;
            m_write_event_args.UserToken  = this;

            m_write_buffers = new Queue <AsyncBuffer>();

            Context           = new AsyncContext();
            Context.State     = this;
            Context.User      = user;
            Context.Interface = interface_;
        }
예제 #2
0
        internal void Write(AsyncBuffer buffer)
        {
            lock (m_write_buffers)
            {
                m_write_buffers.Enqueue(buffer); // Save the buffer

                CheckWrite();                    // Perform the logic to check for the next write. NOTE: This stays inside the lock to keep FIFO order.
            }
        }
예제 #3
0
        private void CheckWrite()
        {
            lock (m_write_buffers)
            {
                if (m_current_write_buffer == null)                                                                                               // If no write is in progress
                {
                    if (m_write_buffers.Count > 0)                                                                                                // There is pending data
                    {
                        m_current_write_buffer = m_write_buffers.Dequeue();                                                                       // Get the next buffer

                        m_write_event_args.SetBuffer(m_current_write_buffer.Buffer, m_current_write_buffer.Offset, m_current_write_buffer.Count); // Setup the async write

                        DispatchWrite();                                                                                                          // Begin the write
                    }
                }
            }
        }
예제 #4
0
        private bool ProcessWrite(SocketAsyncEventArgs e)
        {
            try
            {
                if (e.BytesTransferred <= 0 || e.SocketError != SocketError.Success) // Check for errors
                {
                    try
                    {
                        Context.Interface.OnDisconnect(Context);
                    }
                    catch (Exception) { }
                    Cleanup();
                    return(false);
                }

                lock (m_write_buffers)
                {
                    m_current_write_buffer.Offset += e.BytesTransferred;                                           // Update index
                    m_current_write_buffer.Count  -= e.BytesTransferred;                                           // Update count

                    if (m_current_write_buffer.Count > 0)                                                          // If there is data left to be sent
                    {
                        m_write_event_args.SetBuffer(m_current_write_buffer.Offset, m_current_write_buffer.Count); // Setup the next async write
                        DispatchWrite();                                                                           // Begin the next write
                        return(true);                                                                              // Everything is fine
                    }

                    m_current_write_buffer = null; // Clear out the last write object
                    CheckWrite();                  // Perform the logic to check for the next write
                }
            }
            catch (Exception)
            {
                Cleanup();
                return(false);
            }
            return(true); // Everything is fine
        }