Reading and Writing Data – C# – part 7 (Network I/O)

Handling Multiple Connections – Asynchronous Network Server

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace AsynchNetworkServer
{
    public class AsynchNetworkServer
    {
        class ClientHandler
        {
            private readonly byte[] _buffer;
            private Socket _socket;
            private NetworkStream _networkStream;
            private readonly AsyncCallback _callbackRead;
            private readonly AsyncCallback _callbackWrite;

            public ClientHandler(Socket socketForClient)
            {
                this._socket = socketForClient;
                this._buffer = new byte[256];
                this._networkStream = new NetworkStream(socketForClient);
                this._callbackRead = new AsyncCallback(this.OnReadComplete);
                this._callbackWrite = new AsyncCallback(this.OnWriteComplete);
            }

            public void StartRead()
            {
                this._networkStream.BeginRead(this._buffer, 0, this._buffer.Length, this._callbackRead, null);
            }

            private void OnWriteComplete(IAsyncResult ar)
            {
                this._networkStream.EndWrite(ar);
                // Only for debug !! -Console.WriteLine can block your thread until the write completes, so in production program it is unacceptable
                Console.WriteLine("Write is completed");
                this._networkStream.BeginRead(this._buffer, 0, this._buffer.Length, this._callbackRead, null);
            }

            private void OnReadComplete(IAsyncResult ar)
            {
                int bytesRead = this._networkStream.EndRead(ar);

                if (bytesRead > 0)
                {
                    string s = Encoding.ASCII.GetString(this._buffer, 0, bytesRead);
                    // Only for debug !! -Console.WriteLine can block your thread until the write completes, so in production program it is unacceptable
                    Console.WriteLine("Recived {0} bytes from client: {1}", bytesRead, s);
                    this._networkStream.BeginWrite(this._buffer, 0, bytesRead, this._callbackWrite, null);
                }
                else
                {
                    Console.WriteLine("Read connection is dropped");
                    this._networkStream.Close();
                    this._socket.Close();
                    this._networkStream = null;
                    this._socket = null;
                }
            }
        }

        public static void Main()
        {
            AsynchNetworkServer app = new AsynchNetworkServer();
            app.Run();
        }

        public void Run()
        {
            IPAddress localAddress = IPAddress.Parse("127.0.0.1");
            if (localAddress == null)
            {
                return;
            }

            TcpListener tcpListener = new TcpListener(localAddress, 65000);
            tcpListener.Start();

            while (true)
            {
                Socket soketForClient = tcpListener.AcceptSocket();
                Console.WriteLine("Client connected");
                ClientHandler handler = new ClientHandler(soketForClient);
                handler.StartRead();
            }
        }
    }
}
Advertisements

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