Archive

Posts Tagged ‘Architecture’

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

April 20, 2010 Leave a comment

 

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.

Dotnet Async Socket Server – 2.Architecture

April 14, 2010 4 comments

 

In this part, I will describe the basic concepts and architecture of our socket server we will implement.

Contents of this series

 

Static architecture

Architecture

Let us to see the outlook of our Socket Server component.

  • SocketListener : Connection and messaging management with multiple clients
  • Simple Protocol Codec : By implementing the IProtocol interface, this support decoding(de-serialization) and encoding(serialization) services for the protocol.
  • Event Handler : Handling socket operations and messaging for the Simple Protocol.
  • Fake Service : This provides fake business service with input parameter as decoded object and return object for the encoding resource.
  • Management UI : Through UI Invoke helper class, this UI provides Winform display  and control of the server thread and information.

This server uses two external components.

  • System.Net.Sockets
  • Protobuf-Net : fast and well-designed protobuf implementation for .NET.

This system also will contains 3 communication components.

  • Silverlight Policy Server
  • Silverlight Client : uses the SocketClient class and provides XAML UIs.
  • Winform Client : uses the SocketClient class and provides Winform UIs.

And see some technical operations before the implementation.

 

Listener and Connection

Core classes should have a SocketAsyncEventArgs instances for high-performance async networking in the pure .NET framework.

  • The SocketClient : this use the connectAsync method of the SocketAsyncEventArgs to connect.
  • The SocketListener : this use only the acceptAsync method of the SocketAsyncEventArgs class and may have a list of the Connection object to store the accepted sessions.
  • The Connection class : main role of this is to listen and response for the messaging transactions of each socket session.

Let us to see the following conceptual diagram to understand the basic socket accepting process.

The <2.AcceptAsync> step should be started when the listener start and will be finished in the <4.Accept Completed> step. After creating a connection context, the second step should be restarted to listen another accept request from other socket clients.

 

SocketAsyncEventArgs pool manager and Buffer manager classes

Let us to see the SocketAsyncEventArgs pool manager class at this MSDN section.

“asynchronous socket operations are described by reusable SocketAsyncEventArgs objects allocated and maintained by the application. High-performance socket applications know best the amount of overlapped socket operations that must be sustained.”

Each connection should have a SocketAsyncEventArgs instance for the messaging operations (receive and send). So, the SocketAsyncEventArgs pool manager would provide the instance library of many SocketAsyncEventArgs instances.

We can also see the Buffer manager class on MSDN here.

“This class creates a single large buffer which can be divided up and assigned to SocketAsyncEventArgs objects for use with each socket I/O operation. This enables buffers to be easily reused and guards against fragmenting heap memory.”

 

When each connection is created by the Socket Listener, the listener assigns the total buffer from buffer manager to the connections’ MessageArgs with setting offset and count properties.