Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / operating-systems / Windows

Port Sharing Features in WCF

3.42/5 (30 votes)
7 Aug 20075 min read 1  
Port Sharing Features in WCF

Introduction

WCF (formerly Indigo), is the next generation way of developing distributed applications in .NET. Apart from being developed from Service Orientation perspective in mind and unifying all the distributed technologies of the Microsoft stack, it encompasses a variety of other features which either might not be highlighted or might be not been well documented. One among those features is the port sharing feature on TCP protocols. Organizations have NAT and firewalls for obvious security reasons. If any application that needs to be deployed and accessed across the firewall, one needs to rely on the common TCP ports that firewalls open. HTTP protocol normally uses Port 80. Thanks to the usage of HTTP.sys and IIS 6.0, wherein Port 80 can be used and shared across multiple applications, the problem is that there is not a single way in which we can enable port sharing via TCP.

What if the same port can be shared across multiple applications that run on TCP?

The answer to the same lies in the NET.TCP Port Sharing feature of WCF. In this article, we will see how easily we can achieve the same in WCF.

What happens if same port is been used by applications running on TCP ?

Screenshot - pic1.jpg

In the above application, App 1 is running on TCP Port 2555 and client 1 is interacting with it. Now if Client 2 wants to access App 2 on the same port 2555, it will encounter the following error:

"There is already a listener on IP endpoint <Endpoint ID>. Make sure that you are not trying to use this endpoint multiple times in your application and that there are no other applications listening on this endpoint. "

NET.TCP Port sharing

Now through NET.TCP Port sharing service, multiple applications in WCF can share the same ports.

<group id="_x0000_s1040" style="WIDTH: 6in; HEIGHT: 177.1pt" editas="canvas" coordorigin="2527,2295" coordsize="10000,4217"><lock v:ext="edit" aspectratio="t"><shape id="_x0000_s1041" style="LEFT: 2527px; WIDTH: 10000px; POSITION: absolute; TOP: 2295px; HEIGHT: 4217px" type="#_x0000_t75" o:preferrelative="f"><fill o:detectmouseclick="t"><path o:extrusionok="t" o:connecttype="none"><lock v:ext="edit" text="t"><rect id="_x0000_s1042" style="LEFT: 6027px; WIDTH: 5700px; POSITION: absolute; TOP: 2809px; HEIGHT: 3703px; v-text-anchor: middle" fillcolor="#bbe0e3"><oval id="_x0000_s1043" style="LEFT: 2527px; WIDTH: 1875px; POSITION: absolute; TOP: 2501px; HEIGHT: 866px; v-text-anchor: middle" fillcolor="#bbe0e3"><textbox inset="1.82881mm,.91439mm,1.82881mm,.91439mm">

Screenshot - pic4.jpg

<oval id="_x0000_s1044" style="LEFT: 2527px; WIDTH: 1875px; POSITION: absolute; TOP: 4352px; HEIGHT: 1337px; v-text-anchor: middle" fillcolor="#bbe0e3"><textbox inset="1.82881mm,.91439mm,1.82881mm,.91439mm">

<shape id="_x0000_s1045" style="LEFT: 8327px; WIDTH: 1400px; POSITION: absolute; TOP: 3015px; HEIGHT: 1234px; v-text-anchor: middle" type="#_x0000_t132" fillcolor="#bbe0e3"><textbox inset="1.82881mm,.91439mm,1.82881mm,.91439mm"><shape id="_x0000_s1046" style="LEFT: 8527px; WIDTH: 1400px; POSITION: absolute; TOP: 4866px; HEIGHT: 1235px; v-text-anchor: middle" type="#_x0000_t132" fillcolor="#bbe0e3"><textbox inset="1.82881mm,.91439mm,1.82881mm,.91439mm"><line id="_x0000_s1047" style="POSITION: absolute" from="4327,3015" to="6027,3941"><stroke endarrow="block"><line id="_x0000_s1048" style="POSITION: absolute; flip: y" from="6027,3529" to="8327,3838"><stroke endarrow="block" dashstyle="dash"><line id="_x0000_s1049" style="POSITION: absolute; flip: y" from="4194,4146" to="5727,4652"><stroke endarrow="block"><rect id="_x0000_s1050" style="LEFT: 5127px; WIDTH: 2200px; POSITION: absolute; TOP: 3324px; HEIGHT: 1328px; v-text-anchor: middle" fillcolor="#bbe0e3"><textbox inset="1.82881mm,.91439mm,1.82881mm,.91439mm"><line id="_x0000_s1051" style="POSITION: absolute" from="7319,4652" to="8519,5373"><stroke endarrow="block"><shapetype id="_x0000_t106" coordsize="21600,21600" adj="1350,25920" o:spt="106" path="ar,7165,4345,13110,1950,7185,1080,12690,475,11732,4835,17650,1080,12690,2910,17640,2387,9757,10107,20300,2910,17640,8235,19545,7660,12382,14412,21597,8235,19545,14280,18330,12910,11080,18695,18947,14280,18330,18690,15045,14822,5862,21597,15082,18690,15045,20895,7665,15772,2592,21105,9865,20895,7665,19140,2715,14330,,19187,6595,19140,2715,14910,1170,10992,,15357,5945,14910,1170,11250,1665,6692,650,12025,7917,11250,1665,7005,2580,1912,1972,8665,11162,7005,2580,1950,7185xear,7165,4345,13110,1080,12690,2340,13080nfear475,11732,4835,17650,2910,17640,3465,17445nfear7660,12382,14412,21597,7905,18675,8235,19545nfear7660,12382,14412,21597,14280,18330,14400,17370nfear12910,11080,18695,18947,18690,15045,17070,11475nfear15772,2592,21105,9865,20175,9015,20895,7665nfear14330,,19187,6595,19200,3345,19140,2715nfear14330,,19187,6595,14910,1170,14550,1980nfear10992,,15357,5945,11250,1665,11040,2340nfear1912,1972,8665,11162,7650,3270,7005,2580nfear1912,1972,8665,11162,1950,7185,2070,7890nfem@23@37qx@35@24@23@36@34@24@23@37xem@16@33qx@31@17@16@32@30@17@16@33xem@38@29qx@27@39@38@28@26@39@38@29xe">

Look at the above diagram, the logic lies in the Windows service that ships with WCF called NET.TCP Port Sharing Service which enables multiple port sharing through WCF.

Sharing a common port on TCP is a three step process in WCF:

  1. Enable the NET.TCP Port Sharing Service(disabled by default)
  2. Use TCP protocols in WCF Services
  3. Setting the PortSharingEnabled Property to true

We will look at each of these steps one by one.

Step 1. Enabling NET.TCP Port Sharing Service

Installing .NET 3.0 installs a suite of other services. One of the Window services that gets installed is NET.TCP Port Sharing Service. This service enables WCF services, running on the different process, sharing the same port. The advantage of the same is that multiple applications running on TCP no longer need to open a separate port for each of them. This service is been hosted by a process called SMSvcHost.exe that resides in "c:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation" folder(Replace C with your Windows root directory). Internally, this process manages the TCP socket for the services that have port sharing enabled (specified in Step 3). By default, this service is disabled and needs to be started. To enable it:

  1. Open Run and type services.msc. Click on OK
  2. Select NET.TCP Port Sharing Service in the Name column from the service Management Console
  3. Start the service

Screenshot - pic_3.jpg

Step 2. use TCP protocols in WCF Services

WCF services can be consumed only via its endpoints. Endpoints are the entry point for the service. .NET compiler will give a compile time error if WCF services do not have any endpoints. Endpoints consist of Address, Binding and Contract. Bindings in WCF determine how to consume any WCF service. They contain the information about the protocol being used, transaction requirements, security requirements, type of communication etc. to name a few. Microsoft has come up with pre-defined bindings and most of the time, your requirements can get fulfilled with these predefined bindings. In case none of the predefined bindings fulfills your requirement, you can also create your custom bindings. These bindings can be specified either through imperative code or through a configuration file. Few of these predefined bindings use TCP protocol like NetTcpBinding and NetPeerTcpBinding. For using multiple ports sharing via Net.TCP port sharing service, create an endpoint and use one of the above TCP Binding.

To know about how to create endpoints, read this.

Step 3 : Setting the PortSharingEnabled Property to true

XML
<bindings> 
   <netTcpBinding> 
      <binding name="PortBinding" portSharingEnabled="true" />
   </netTcpBinding>
</bindings> 

The above code is an excerpt from the configuration file. This task can be done through the imperative code by instantiating NetTcpBinding and setting its PortSharingEnabled to true.

C#
// configure a binding with TCP port sharing enabled
NetTcpBinding binding = new NetTcpBinding();
binding.PortSharingEnabled = true;

Step 3 is delegating the task of monitoring the TCP port to SMSvcHost.exe for all the services using the above binding and enables port sharing. It will thereby, monitor all the TCP traffic on that server, and route it to the destined address of an application. So when any WCF service running on TCP protocol and using the PortBinding comes up, the WCF engine does not open the port directly, instead it delegates this responsibility to NET.TCP Port sharing service, which not only opens a port for that service but also acts as a listener of that port. There is no tweak of settings involved on the client side.

Summary

SMSvcHost.exe also contains the configuration file called SMSvcHost.exe.config residing in the same root directory. This configuration file manages the list of all those processes that might use the port sharing feature and list of USER accounts that can run this Windows Service. Each of the services running on different processes should have a different URI though they share the same port. This service can only be used over the TCP protocol and can't be used on top of HTTP or Named Pipes. However, it too opens the doors of opportunities for product development and sigh of relief to system administrators. They no longer need to compromise with the security of firewalls.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here