{"id":110,"date":"2011-06-19T23:12:20","date_gmt":"2011-06-19T15:12:20","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=110"},"modified":"2018-09-02T22:48:54","modified_gmt":"2018-09-02T14:48:54","slug":"implementing-client-server-communication-using-serialization-and-tcpip-in-c","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/implementing-client-server-communication-using-serialization-and-tcpip-in-c\/","title":{"rendered":"Implementing client-server communication using serialization and TCP\/IP in C#"},"content":{"rendered":"<p>As software developers, we are always developing applications that can communication with other components: A server side script that echoes html to the browser, the client application that send information to a remote server endpoint and etc. One of the requirements that I got from my project was to display feedback from a windows service. However, because of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb756986.aspx\" target=\"_blank\">session 0 isolation<\/a> in windows 7, invocations of visual display logic from the windows service application <strong>is not enough<\/strong> to fulfill the requirement. In order to display feedback from a windows service application, I created a separate form application that runs when users log in and have the form application connects to the windows service application via TCP\/IP to listen for feedback. Communication between the two applications is achieved via <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms973893.aspx\" target=\"_blank\">Object Serialization in .NET framework<\/a>.<\/p>\n<h3>Reasons for using Object Serialization over TCP\/IP<\/h3>\n<p>While there are a few ways to workaround the session 0 isolation problem, I chose TCP\/IP mainly because of my familiarity with the protocol. In addition, the keep alive nature of the protocol made the coding work more straightforward. By using serialization and TCP\/IP as the communication protocol between my applications, I saved some time for developing other areas of my project.  <\/p>\n<h3>Defining the message payload<\/h3>\n<p>I modeled the <code>Message<\/code> class based on the <code>ShowBalloonTip<\/code> method of the <code><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.windows.forms.notifyicon.aspx\" target=\"_blank\">NotifyIcon<\/a><\/code> class. Hence, each message received from the windows service application includes a title, a content\/description, as well as a type. With this design in mind, defining the message payload is pretty straightforward:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing System.Runtime.Serialization;\r\n\r\n\/\/ Enumeration that define the type of message\r\npublic enum MessageType { Error, Warning, Info }\r\n\r\n&#x5B;Serializable]\r\npublic class Message\r\n{\r\n    private MessageType _messageType;\r\n    private string _messageTitle;\r\n    private string _messageContents;\r\n\r\n    public Message(string title, string contents, MessageType type)\r\n    {\r\n        this.Title = title;\r\n        this.Contents = contents;\r\n        this.Type = type;\r\n    }\r\n\r\n    public MessageType Type\r\n    {\r\n        get\r\n        {\r\n            return this._messageType;\r\n        }\r\n        set\r\n        {\r\n            this._messageType = value;\r\n        }\r\n    }\r\n\r\n    public string Title\r\n    {\r\n        get\r\n        {\r\n            return this._messageTitle;\r\n        }\r\n        set\r\n        {\r\n            this._messageTitle = value;\r\n        }\r\n    }\r\n\r\n    public string Contents\r\n    {\r\n        get\r\n        {\r\n            return this._messageContents;\r\n        }\r\n        set\r\n        {\r\n            this._messageContents = value;\r\n        }\r\n    }\r\n} \/\/ end public class Message\r\n<\/pre>\n<p>This is it, by marking the class with <code>Serializable<\/code> attribute, instances of the <code>Message<\/code> class can be sent and received via Object Serialization. The next step would then to implement the <code>MessageServer<\/code> and the <code>MessageClient<\/code> classes.<\/p>\n<h3>The MessageServer class<\/h3>\n<p>The <code>MessageServer<\/code> class utilizes <code><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.sockets.tcpclient.aspx\">TcpListener<\/a><\/code> to allow instances of <code>MessageClient<\/code> to connect to it. Connected clients are then stored in a Dictionary with the username of the current active client, which is retrieved via <code>Machine.getInstance().getUsername()<\/code> function that was discussed in <a href=\"http:\/\/www.techcoil.com\/blog\/2011\/04\/23\/how-to-retrieve-the-username-of-the-user-who-logged-onto-windows-from-windows-service\/\" target=\"_blank\">a previous post<\/a>. Also, the <code>MessageServer<\/code> provides a <code>SendMessageToActiveClient<\/code> method that utilizes the <code>Serialize<\/code> method of <code><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.runtime.serialization.formatters.binary.binaryformatter.aspx\" target=\"_blank\">BinaryFormatter<\/a><\/code> to send instances of the <code>Message<\/code> class through the <code><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.net.sockets.tcpclient.aspx\" target=\"_blank\">TcpClient<\/a><\/code> instance that is associated with the active user. With such configurations, whenever there is a feedback from the windows service application, the feedback is always sent to the windows form application instance of the currently active user. The windows form application instance can then display the feedback to the active user.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing System.Collections.Generic;\r\nusing System.Net;\r\nusing System.Net.Sockets;\r\nusing System.Runtime.Serialization.Formatters.Binary;\r\nusing System.Threading;\r\n\r\npublic class MessageServer\r\n{\r\n    private int _port;\r\n    private TcpListener _tcpListener;\r\n    private Dictionary&lt;string, TcpClient&gt; _clientsDictionary;\r\n    private bool _running, _disposed;\r\n\r\n    private BinaryFormatter _bFormatter;\r\n\r\n    private Thread _connectionThread;\r\n\r\n    \/\/ Create a message server that listens on the indicated port\r\n    public MessageServer(int port)\r\n    {\r\n        this._port = port;\r\n        this._tcpListener = new TcpListener(IPAddress.Loopback, port);\r\n        this._clientsDictionary = new Dictionary&lt;string,TcpClient&gt;();\r\n        this._running = false;\r\n        this._bFormatter = new BinaryFormatter();\r\n    } \/\/ end public MessageServer(int port) \r\n\r\n    public void Start()\r\n    {\r\n        if (!_running) \r\n        {\r\n            this._tcpListener.Start();\r\n            this._running = true;\r\n            this._connectionThread = new Thread\r\n                (new ThreadStart(ListenForClientConnections));\r\n            this._connectionThread.Start();\r\n        } \/\/ end if (!_running)\r\n\r\n    } \/\/ end public void Start()\r\n\r\n    public void Stop()\r\n    {\r\n        if (this._running) \r\n        {\r\n            this._tcpListener.Stop();\r\n            this._running = false;\r\n        }\r\n    } \/\/ end public void Stop()\r\n\r\n    public bool Running()\r\n    {\r\n        return this._running;\r\n    } \/\/ end public bool Running()\r\n\r\n    \/\/ Thread body for listening for client connections\r\n    private void ListenForClientConnections()\r\n    {\r\n        while(this._running) \r\n        {\r\n            TcpClient connectedTcpClient = this._tcpListener.AcceptTcpClient();\r\n            \/\/ Remember the current client connection\r\n            string activeUsername = Machine.getInstance().getUsername();\r\n            lock (this)\r\n            {\r\n                \/\/ If there is another connection from a same client\r\n                if (this._clientsDictionary.ContainsKey(activeUsername))\r\n                {\r\n                    \/\/ close the connection.\r\n                    this._clientsDictionary&#x5B;activeUsername].Close();\r\n                    \/\/ Remember the new connection\r\n                    this._clientsDictionary&#x5B;activeUsername] = connectedTcpClient; \r\n                }\r\n                \/\/ Else \r\n                else\r\n                {\r\n                    \/\/ Remember the new connection\r\n                    this._clientsDictionary.Add(activeUsername, \r\n                        connectedTcpClient);\r\n                } \/\/ end if\r\n\r\n            } \/\/ end lock(this._clientsDictionary)\r\n        } \/\/ end while(this._running)\r\n    } \/\/ end private void ListenForClientConnections()\r\n\r\n    \/\/ Send a message to the currently logged in user\r\n    public void SendMessageToActiveClient(Message message)\r\n    {\r\n        lock(this) \r\n        {\r\n            \/\/ Get the current active user\r\n            string activeUsername = Machine.getInstance().getUsername();\r\n            \/\/ If client had connected to the message server\r\n            if (this._clientsDictionary.ContainsKey(activeUsername))\r\n            {\r\n                try\r\n                {\r\n                    \/\/ send message to client\r\n                    this.sendMessage\r\n                        (this._clientsDictionary&#x5B;activeUsername], message);\r\n                }\r\n                catch (Exception)\r\n                {\r\n                    \/\/ close the client connection\r\n                    this._clientsDictionary&#x5B;activeUsername].Close();\r\n                    \/\/ Remove the client connection from memory\r\n                    this._clientsDictionary.Remove(activeUsername);\r\n                } \/\/ end try-catch\r\n            } \/\/ end if\r\n        } \/\/ end lock\r\n    } \/\/ end public void sendMessageToActiveClient()\r\n    \r\n    private void sendMessage(TcpClient client, Message message)\r\n    {\r\n        \/\/ Send message to the client.\r\n        _bFormatter.Serialize(client.GetStream(), message);\r\n    } \/\/ end private void sendMessage(TcpClient client, Message message)\r\n\r\n} \/\/ end public class MessageServer\r\n<\/pre>\n<h3>The MessageClient class<\/h3>\n<p>The <code>MessageClient<\/code> utilises the <code>TcpClient<\/code> class to connect to the <code>MessageServer<\/code>. After connecting to the <code>MessageServer<\/code>, the <code>TcpClient<\/code> uses the <code>Deserialize<\/code> method of the <code>BinaryFormatter<\/code> class to listen to instances of <code>Message<\/code> received from the <code>MessageServer<\/code>. When an instance of <code>Message<\/code> is received, the <code>MessageClient<\/code> will trigger the <code>MessageReceived<\/code> event.  <\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System;\r\nusing System.Net;\r\nusing System.Net.Sockets;\r\nusing System.Runtime.Serialization.Formatters.Binary;\r\nusing System.Threading;\r\n\r\npublic delegate void MessageReceivedEventHandler(object sender, Message message);\r\n\r\npublic class MessageClient\r\n{\r\n    private int _port;\r\n    private TcpClient _tcpClient;\r\n    private BinaryFormatter _bFormatter;\r\n    private Thread _listenThread;\r\n    private bool _running, _disposed;\r\n    public event MessageReceivedEventHandler MessageReceived;     \r\n\r\n\r\n    public MessageClient(int port)\r\n    {\r\n        this._port = port;\r\n        this._tcpClient = new TcpClient(&quot;localhost&quot;, port);\r\n        this._bFormatter = new BinaryFormatter();\r\n        this._running = false;\r\n    } \/\/ end public MessageClient(int port)\r\n\r\n    public void StartListening()\r\n    {\r\n        lock (this)\r\n        {\r\n            if (!_running)\r\n            {\r\n                this._running = true;\r\n                this._listenThread = new Thread\r\n                    (new ThreadStart(listenForMessage));\r\n                this._listenThread.Start();\r\n            }\r\n            else\r\n            {\r\n                this._running = true;\r\n                this._tcpClient = new TcpClient(&quot;localhost&quot;, this._port);\r\n                this._listenThread = new Thread\r\n                    (new ThreadStart(listenForMessage));\r\n                this._listenThread.Start();\r\n            } \/\/ end if (!_running)\r\n        } \/\/ end lock (this)\r\n    } \/\/ end public void StartListening()\r\n\r\n    private void ListenForMessage()\r\n    {\r\n        try\r\n        {\r\n            while (this._running)\r\n            {\r\n                \/\/ Block until an instance Message is received \r\n                Message message =\r\n                    (Message)this._bFormatter.Deserialize\r\n                        (this._tcpClient.GetStream());\r\n                \/\/ Notify all registered event handlers about the message.\r\n                if (MessageReceived != null &amp;&amp; message != null) \r\n                {\r\n                    MessageReceived(this, message);\r\n                } \/\/ end if MessageReceived != null\r\n            } \/\/ end while\r\n        }\r\n        catch (Exception)\r\n        {\r\n            this._running = false;\r\n        } \/\/ end try-catch\r\n    } \/\/ end private void ListenForMessage();\r\n\r\n    public void StopListening()\r\n    {\r\n        lock (this)\r\n        {\r\n            if (this._running)\r\n            {\r\n                this._tcpClient.Close();\r\n                _running = false;\r\n            }\r\n        } \/\/ end lock(this)\r\n    } \/\/ end public void StopListening()\r\n\r\n} \/\/ end class MessageClient\r\n<\/pre>\n<h3>Some posts that may interest you<\/h3>\n<ul>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-save-and-load-objects-to-and-from-file-in-c\/\" title=\"How to save and load objects to and from file in C#\" target=\"_blank\">How to save and load objects to and from file in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-build-a-web-based-user-interaction-layer-in-c\/\" title=\"How to build a web based user interaction layer in C#\" target=\"_blank\">How to build a web based user interaction layer in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/how-to-execute-codes-periodically-in-c\/\" title=\"How to execute codes periodically in C#\" target=\"_blank\">How to execute codes periodically in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/downloading-a-file-from-via-http-post-and-http-get-in-c\/\" title=\"Downloading a file via HTTP post and HTTP get in C#\" target=\"_blank\">Downloading a file via HTTP post and HTTP get in C#<\/a><\/li>\n<li><a href=\"http:\/\/www.techcoil.com\/blog\/quick-references\/sending-a-file-and-some-form-data-via-http-post-in-c\/\" title=\"Sending a file and some form data via HTTP post in C#\" target=\"_blank\">Sending a file and some form data via HTTP post in C#<\/a><\/li>\n<\/ul>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-1M\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-1M&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-1M&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F110&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>As software developers, we are always developing applications that can communication with other components: A server side script that echoes html to the browser, the client application that send information to a remote server endpoint and etc. One of the requirements that I got from my project was to display feedback from a windows service. However, because of <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb756986.aspx\" target=\"_blank\">session 0 isolation<\/a> in windows 7, invocations of visual display logic from the windows service application <strong>is not enough<\/strong> to fulfill the requirement. In order to display feedback from a windows service application, I created a separate form application that runs when users log in and have the form application connects to the windows service application via TCP\/IP to listen for feedback. Communication between the two applications is achieved via <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms973893.aspx\" target=\"_blank\">Object Serialization in .NET framework<\/a>.<\/p>\n","protected":false},"author":1,"featured_media":1189,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[375],"tags":[20,25,24],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/C-Sharp-Logo.gif","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-1M","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/110"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=110"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/110\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1189"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}