A giant leap forward in Windows HTTP technologies was introduced with Windows Server 2003, namely http.sys. Http.sys includes a kernel-mode listener that can dispatch to any process on the machine. This was great news to those of us that wanted to share port 80 with other applications (IIS for example). It also has a comprehensive namespace security mechanism which admins can use to delegate sections of the global hierarchical directory space to less-privileged accounts. IIS 6.0 (which shipped with Server 2003) was built on top of http.sys and so did not require exclusive access to its configured port #s.
Indigo’s standalone HTTP IChannelListeners are built on top of http.sys. That means that if you are not hosted in IIS, your process will need to have access to any http addresses that your ServiceHost is configured with. If the process is not running as admin you will need to add a reservation using httpcfg.exe. Alternatively, you can call the HTTP configuration APIs, such as HttpSetServiceConfiguration, directly.
There is one more wrinkle when working on XPSP2. While http.sys was backported to XP as part of Service Pack 2 (yay), IIS 6.0 was not (boo). This means that if you have IIS running on your XP box, then you are using IIS 5.1 which is built on top of a listening socket and thus owns port 80. If you try to open a Service using port 80 while IIS is running you will get the following error:
AddressAlreadyInUseException: HTTP could not register URL http://+:80/myService/ because TCP port 80 is being used by another application.
You have 2 choices to remedy this situation:
- Stop IIS (using “net stop w3svc”)
- Setup your service to use a different port#
Setting up a different port# is usually a simple matter of changing your Service’s URL. However, a more subtle variation of this failure occurs for clients that use WsDualHttpBinding (or a custom binding with CompositeDuplexBindingElement and HttpTransportBindingElement). Your indication here is the inclusion of “Temporary_Indigo_Addresses” as in:
AddressAlreadyInUseException: HTTP could not register URL http://+:80/Temporary_Listen_Addresses/51E705D5-E7B5-472B-B6B9-A6A60FE93B7A/ because TCP port 80 is being used by another application.
When your client is using a Dual binding, then the system creates a temporary address to listen on, in order to establish two-way communication over two one-way channels. For HTTP, this address by default is setup on a subtree of http://+:80/Temporary_Indigo_Addresses. This has the advantage of being a namespace pre-ACLed by Indigo for access by all processes. You can override this default through the ClientBaseAddress property on WsDualHttpBinding and CompositeDuplexBindingElement. You can do this either through code:
binding.ClientBaseAddress = "http://localhost:8000/myClient/"
Good luck on future port conflict avoidance!