Sony Arouje

a programmer's log

Archive for November 2011

Multi client Asynchronous TCP Server

with 48 comments

This post is based on a tracer I am currently working on. My current project requires a TCP server implementation where other client could establish communication and perform data processing. The server should be able to handle multiple request from client. I never did any work with TCP Listener, initial one hour struggled a lot to get it working.

First approach I took was kind of Server – Server communication. That means there is no client both system act as server, it’s bit complex but I created a working prototype in next couple of hours. Yes it is complex, client app needs lot of work to establish a connection.

I need the server more simple and less code for the client to establish connection. So I started searching for simple TCP based client server approach. I stumble upon this post, where the author does a multi client communication. I got a start for my second tracer, a true client server model. I modified it and removed looping construct and used Async model instead. You all can see the code below.

TCP Server

    private static TcpListener _listener;
    public static void StartServer()
    {
        System.Net.IPAddress localIPAddress = System.Net.IPAddress.Parse("10.91.173.201");
        IPEndPoint ipLocal = new IPEndPoint(localIPAddress, 8888);
        _listener = new TcpListener(ipLocal);
        _listener.Start();
        WaitForClientConnect();
    }
    private static void WaitForClientConnect()
    {
        object obj = new object();
        _listener.BeginAcceptTcpClient(new System.AsyncCallback(OnClientConnect), obj);
    }
    private static void OnClientConnect(IAsyncResult asyn)
    {
        try
        {
            TcpClient clientSocket = default(TcpClient);
            clientSocket = _listener.EndAcceptTcpClient(asyn);
            HandleClientRequest clientReq = new HandleClientRequest(clientSocket);
            clientReq.StartClient();
        }
        catch (Exception se)
        {
            throw;
        }

        WaitForClientConnect();
    }
}

Here I use a async wait approach rather than waiting in a loop. So whenever a client connect OnClientConnected will fire and it handover the request to Client Request handler. After that it will again go back to wait mode for the next request. The advantage of this approach, the application is responsive and less CPU intensive compare to the looping approach.

Let’s see the client request handler

public class HandleClientRequest
{
    TcpClient _clientSocket;
    NetworkStream _networkStream = null;
    public HandleClientRequest(TcpClient clientConnected)
    {
        this._clientSocket = clientConnected;
    }
    public void StartClient()
    {
        _networkStream = _clientSocket.GetStream();
        WaitForRequest();
    }

    public void WaitForRequest()
    {
        byte[] buffer = new byte[_clientSocket.ReceiveBufferSize];

        _networkStream.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer);
    }

    private void ReadCallback(IAsyncResult result)
    {
        NetworkStream networkStream = _clientSocket.GetStream();
        try
        {
            int read = networkStream.EndRead(result);
            if (read == 0)
            {
                _networkStream.Close();
                _clientSocket.Close();
                return;
            }

            byte[] buffer = result.AsyncState as byte[];
            string data = Encoding.Default.GetString(buffer, 0, read);

            //do the job with the data here
            //send the data back to client.
            Byte[]  sendBytes = Encoding.ASCII.GetBytes("Processed " + data);
            networkStream.Write(sendBytes, 0, sendBytes.Length);
            networkStream.Flush();
        }
        catch (Exception ex)
        {
            throw;
        }

        this.WaitForRequest();
    }

}

Here also I converted the waiting in loop to Async wait model. The looping model causes a constant hike in CPU utilization. This post explain how to asynchronously read request from client.

That’s all the server side. The client side is shown below

public class TCPClient
{
    System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
    NetworkStream serverStream;
    public void ConnectToServer()
    {
        clientSocket.Connect("10.91.173.201", 8888);

    }

    public void SendData(string dataTosend)
    {
        if (string.IsNullOrEmpty(dataTosend))
            return;
        NetworkStream serverStream = clientSocket.GetStream();
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes(dataTosend);
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();
    }

    public void CloseConnection()
    {
        clientSocket.Close();
    }
    public string ReceiveData()
    {
        StringBuilder message = new StringBuilder();
        NetworkStream serverStream = clientSocket.GetStream();
        serverStream.ReadTimeout = 100;
        //the loop should continue until no dataavailable to read and message string is filled.
        //if data is not available and message is empty then the loop should continue, until
        //data is available and message is filled.
        while (true)
        {
            if (serverStream.DataAvailable)
            {
                int read = serverStream.ReadByte();
                if (read > 0)
                    message.Append((char)read);
                else
                    break;
            }
            else if (message.ToString().Length > 0)
                break;
        }
        return message.ToString();
    }
}

As you can see most of the function is very simple to understand except ReceiveData(). I haven’t concentrated much on the client side as client of the actual TCP server will not be a .NET one. I am not discarding the fact, I will refactor ReceiveData().

+Sony Arouje

Written by Sony Arouje

November 25, 2011 at 6:46 pm

Posted in .NET

Tagged with , ,

Decouple Data interchange format from Domain Model

with one comment

I was doing a client app to display some data, the client receive data in xml format. One design constrain for me was, consumer’s domain model should have less impact even if the interchange format changes. So once the domain is loosely coupled, it can work on any type of data. The data can be in XML, JSON, or what ever it is.  This post explains how I achieved it, it’s a very simple approach based on Strategy and Iterator Pattern.

For simplicity, I read the xml data from a file. Below is the xml

<Library>
  <Books>
    <Book Name="CLR via C#" Price="30"></Book>
    <Book Name="Algorithm Design Manual" Price="40"></Book>
  </Books>
</Library>

Parsers

I created a parser class to parse the xml files. Below is the contract and the parser.

public interface IBookDetailsParser:System.Collections.IEnumerator
{
    string getName();
    double getPrice();
}
public class BookDetailsXMLParser:IBookDetailsParser
{
    private int _nodeCount;
    private int _position;
    private XmlDocument _bookDetails;
    public BookDetailsXMLParser(XmlDocument bookDetails)
    {
        this._bookDetails = bookDetails;
        this._position = -1;
        this._nodeCount = _bookDetails.SelectNodes("/Library/Books/Book").Count;
    }
    public string getName()
    {
        return this.getValue("Name");
    }

    public double getPrice()
    {
        return Convert.ToDouble(this.getValue("Price"));
    }

    private string getValue(string attributeName)
    {
        var node = _bookDetails.SelectSingleNode("/Library/Books/Book[" + (_position + 1).ToString() + "]/@" + attributeName);
        if (node == null)
            return string.Empty;

        return node.Value;
    }
    public object Current
    {
        get { return _bookDetails.SelectSingleNode("/Library/Books/Book[" + (_position + 1).ToString() + "]"); }
    }

    public bool MoveNext()
    {
        _position++;
        return (_position < _nodeCount);
    }

    public void Reset()
    {
        _position = -1;
    }
}

As you can see the parser is based on the enumerator pattern.

Domain Model

public class Book
{
    public Book(string name,double price)
    {
        this.Name = name;
        this.Price = price;
    }

    public string Name { get; private set; }
    public double Price { get; private set; }
}
public class BookList
{
    private IBookDetailsParser _bookDetailParser;
    public BookList(IBookDetailsParser bookDetailParser)
    {
        this._bookDetailParser = bookDetailParser;
    }

    public IList<Book> GetBooks()
    {
        IList<Book> books = new List<Book>();
        while (_bookDetailParser.MoveNext())
        {
            Book book = new Book(_bookDetailParser.getName(), _bookDetailParser.getPrice());
            books.Add(book);
        }

        return books;
    }
}

BookList is not aware of what kind of data format it operates on. In case of XML data we can inject the xml parser provided above. Later if we want to change to JSON format then write a json parser implemented by IBookDetailsParser and pass the new json parser to BookList. In this approach any change in data interchange format wont make any impact to our model.

BookService combine all these things together.

public class BookService
{
    public IList<Book> GetAllBooks()
    {
        ServerDataReader dataReader=new ServerDataReader();
        System.Xml.XmlDocument booksXML = dataReader.GetBooks();

        BookList bookList = new BookList(new BookDetailsXMLParser(booksXML));
        return bookList.GetBooks();
    }
}

Any change in the interchange format will affect the BookService. We can make it loosely coupled here as well but that’s not the intention of this post, here I just want to show a loosely coupled domain model from data format.

Written by Sony Arouje

November 16, 2011 at 5:01 pm

Galaxy Tab Oil slick issue–Samsung’s response

with one comment

After I wrote this post, I sent the Link to Samsung India customer support via email. The response was fairly quick, I got a call from technical department and instructed me to contact Samsung UK. So I contacted Samsung UK through email.

Contacting Samsung UK via email is bit tricky as their was no direct link to open the Email popup window, but Samsung India has that option. I noticed that Samsung India’s SITE_ID is 50 and Samsung UK’s is 31. I decided to give a try by copying the email link from Samsung India and just change the SITE_ID from 50 to 31.

The URL for emailing Samsung UK is https://contactus.samsung.com/customer/contactus/formmail/mail/MailQuestionProduct.jsp?SITE_ID=31

Then pasted the new URL in chrome and sent a mail like what I sent to Samsung India. Hoping that I will get some lame excuses some days later. To my surprise I got the response from Samsung UK within 24hrs and they accepted that Samsung is aware of the Oil slick issue. Below is the response I got from Customer support.

Dear Sony
Thank you for contacting Samsung.
In response to your query, please be advised that the "oil slick" issue is something that we are aware has effected a small number of devices within the UK. Do you have a UK residence or an address in the UK? We are offering a service or replacement of these devices within the UK. If you require any further assistance, please contact Samsung again and we will be more than happy to help.

Kind regards
xxxxxxxxxx
Online Support Team
SAMSUNG Customer Support Centre

I provided my contact address in UK and they provided me a service centre address (free and a paid posting address). I had some further clarifications and the support team was very helpful in resolving all the my questions. At last I sent my tab to the address customer support provided. Hopefully I will get my Oil slick free tab in another two weeks. I will update the status once I got my tab in hand.

Written by Sony Arouje

November 15, 2011 at 12:31 am

Diagnostic Trace (SVCLog) configuration for WCF

leave a comment »

Whenever I write any WCF service, I need to search in my snippets to find out the configuration to add Diagnostic traces for WCF. This post help me to pick the configuration any time when ever I need it.

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "F:\Sony\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

 

Adding this configuration allows the WCF to log all the communication between the client and host in xml format. You can view svclog using SvcTraceViewer.exe, it shipped with Visual Studio and can found out in WCF installation location (C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin)

Written by Sony Arouje

November 10, 2011 at 2:34 pm

Posted in .NET, WCF

Tagged with , ,

Read app.config setting during installation

with 2 comments

I am working on a windows service and some specific reason the service name is stored in app.config file. One of the issue I have to solve while creating the installer is reading the service name from app.config of the service. I thought I can read it using ConfigurationManager (default approach). But it will not work out, ConfigurationManager will always return the serviceName as null, even though app.config has value. The reason behind this is the exe running my Installer is InstallUtil.exe and ConfigurationManager will look for InstallUtil.exe.config, so end up getting wrong result.

Google search shows that I have to load the config explicitly and then read the settings. To load the config file we need to specify the file path, I used reflection to get the path. The code is below

Assembly executingAssembly = Assembly.GetAssembly(typeof(WinServiceInstaller));
string targetDir = executingAssembly.Location;

Configuration config = ConfigurationManager.OpenExeConfiguration(targetDir);
string serviceName = config.AppSettings.Settings["ServiceName"].Value.ToString();

 

I called the above code in the constructor of WinServiceInstaller class. Now I am able to access the serviceName from the installer class.

 

 

 

Written by Sony Arouje

November 4, 2011 at 7:06 pm

Posted in .NET, Misc

Tagged with , ,

%d bloggers like this: