Home > Networking > Dotnet Async Socket Server – 5.Pool, buffer and disposer

Dotnet Async Socket Server – 5.Pool, buffer and disposer

 

Introduction

This article is 5th part of the Dotnet Async Socket Server series. In this part, we will implement the AsyncArgsPool and the BufferManager class to make our echo server more efficiently in memory management.

I think it is good to see the Architecture part of this series before start this part.

 

The AsyncArgsPool class (the final edition)

We can get the original source form this MSDN part.

I edited the original source a little bit and added the disposing implementation. Of course, this snippet is based on the MSDN dispose pattern.

...

namespace SuWare.Net.Sockets
{
    public class AsyncArgsPool : IDisposable
    {

        private Stack<SocketAsyncEventArgs> pool;

        ...

        /// <summary>
        /// Disposer of this object.
        /// </summary>
        /// <param name="disposing">disposing option</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    //TBD: Dispose managed resources
                    foreach (SocketAsyncEventArgs element in this.pool)
                    {
                        element.Dispose();
                    }
                }

                //TBD: Release unmanaged resources
            }
            this.disposed = true;
        }

        #endregion
    }
}

 

The BufferManager class (the final edition)

We can also get the original source from this MSDN part.

I also edited the original source a little bit and added the disposing implementation.

...

namespace SuWare.Net.Sockets
{
    public class BufferManager : IDisposable
    {


        ...

        /// <summary>
        /// Disposer of this object.
        /// </summary>
        /// <param name="disposing">disposing option</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    //TBD: Dispose managed resources
                    this.buffer = null;
                    this.freeIndexPool = null;
                }

                //TBD: Release unmanaged resources
            }
            this.disposed = true;
        }

        #endregion
    }
}

 

The SocketListener refactoring

To use the pooling and the buffer management, the prior socket listener should be edited little bit. The poolSize parameter in the constructor means the limit of concurrent maximum connections.

...

namespace SuWare.Net.Sockets
{
    public class SocketListener : IDisposable
    {
        ...
        private readonly int poolSize;
        private AsyncArgsPool readwritePool;
        private BufferManager bufferManager;

        ...

        public SocketListener(IPAddress address,int port,int backlog,int poolSize,int bufferSize)
        {
            ...
            this.poolSize = poolSize;
            this.bufferSize = bufferSize;
            ...

            this.readwritePool = new AsyncArgsPool(poolSize);
            this.bufferManager = new BufferManager(poolSize, bufferSize);
        }

        ...

        private void ProcessAccept(SocketAsyncEventArgs e)
        {
            ...

            if (e.SocketError == SocketError.Success)
            {
                //Checkout Buffer with pool and buffermanager
                SocketAsyncEventArgs messageArgs = this.readwritePool.CheckOut();
                this.bufferManager.CheckOut(messageArgs);

                Connection connection = new Connection(
                    this.bufferSize, e.AcceptSocket, messageArgs, this.RemoveConnection,
                    this.OnDisconnected, this.OnReceived, this.OnSent);

                ...
            }

            this.StartAccept();
        }

        ...
    }
}

 

The Echo server refactoring

Let’s edit the echo server to pass the poolSize parameter.

...

namespace SuWare.Sample.EchoServer
{
    class Program
    {
        static void Main(string[] args)
        {
            ...

            SocketListener server = new SocketListener(IPAddress.Parse("127.0.0.1"), 4096, 10,2000, 4096);
            ...
        }

        ...
    }

 

Dispose Implement

It is good to implement IDispose interface for the SocketListener, the Connection and the SocketClient class.

This is the dispose method of the SocketListener class.

        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    this.StopListener();
                    if (this.acceptArgs != null)
                    {
                        this.acceptArgs.Dispose();
                        this.acceptArgs = null;
                    }
                    if (this.readwritePool != null)
                    {
                        this.readwritePool.Dispose();
                        this.readwritePool = null;
                    }
                    if (this.bufferManager != null)
                    {
                        this.bufferManager = null;
                    }
                }

                disposed = true;
            }
        }

 

You can download the source of this part at here.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: